Replace function in Oracle SQL - sql

I'm using oracle SQL, and i have the following query:
select replace(replace('count(distinct <thiscol>) over (partition by <nextcol>) / count(*) over () as <thiscol>_<nextcol>,',
'<thiscol>', column_name
), '<nextcol>', lead(column_name) over (order by column_id)
)
from all_tab_columns atc
where table_name = 'mytable'
The output supposed to be queries such as follow:
select id,
count(distinct name2) over (partition by name3) / count(*) over (),
count(distinct name3) over (partition by name4) / count(*) over (),
. . .
from mytable;
I'm expecting to get instead of:
count(distinct name2) over (partition by name3) / count(*) over ()
this query:
count(distinct name3) over (partition by name2) / count(*) over ()
Anyone can advise how to replace the order of the column values? (<thiscol> and <nextcol>). I tried to replace <thiscol> with <nextcol> but it gave me the same result. I tried many other things with of success.
Anyone?

That is really strange. Instead, let's sort in the reverse order:
select replace(replace('count(distinct <thiscol>) over (partition by <nextcol>) / count(*) over () as <thiscol>_<nextcol>,',
'<thiscol>', column_name
), '<nextcol>', lead(column_name) over (order by column_id desc)
)
from all_tab_columns atc
where table_name = 'mytable';
Note the desc in the sort.

Related

Need to change from rows to column

i have a table like
id,Jdate,Desc
1,3-jul,a
2,3-jul,b
3,3-jul,c
1,4-jul,a
2,4-jul,b
query:
SELECT jdate,id_1,desc_1,id_2,desc_2,id_3,desc_3
from
(select jdate,id,
'id'+ CAST (row_number() OVER(PARTIOTION BY jdate order by jdate) AS varchar(5))AS id_seq,
desc,
'desc' + CAST (row_number() OVER(PARTIOTION BY jdate order by jdate) AS varchar(5))AS id_seq
FROM temp)temp
PIVOT
(MAX(lotid)
FOR id_seq IN(id_1,id_2,id_3)
)PIV;
i need output as
jdate,id_1,desc_1,id_2,desc_2,id_3,desc_3
3-jul,1,a,2,b,3,c
4-jul,1,a,2,b
Another approach to get desired output is through below query
with abc as
(SELECT jdate, LISTAGG(id||','||desc, ',') WITHIN GROUP (ORDER BY id) AS list_1
FROM test_table
GROUP BY jdate)
select abc.jdate, regexp_substr(list_1,'[^,]+',1,1) id_1 ,
regexp_substr(list_1,'[^,]+',1,2) desc_1,
regexp_substr(list_1,'[^,]+',1,3) id_2,
regexp_substr(list_1,'[^,]+',1,4) desc_2,
regexp_substr(list_1,'[^,]+',1,5) id_3,
regexp_substr(list_1,'[^,]+',1,6) desc_3
from abc
OR
if you are looking for only data output then you can use below
select 'Jdate'||','||'id_1'||','||'desc_1'||','||'id_2'||','||'desc_2'||','||'id_3'||','|| 'desc_3' DATA from dual
union
SELECT jdate||','|| LISTAGG(id||','||desc, ',') WITHIN GROUP (ORDER BY id) as DATA FROM test_table GROUP BY jdate
order by data desc
Hope this would help.

query condition - Oracle SQL

I wrote code only on transact sql . I want to write this query in oracle sql. But it doesn't work . the main problem that I can't write my select parameters in the where condition . How to avoid this problem . My query ,
select t.*,
count(*) over(partition by t.el1_code) cnt ,
count(*) over(partition by t.el1_code, t.el1_valid) cnt1 ,
concat(t.el1_name,t.el1_sname) str,
max(concat(t.el1_name,t.el1_sname)) over(partition by t.el1_code) str_check
from tasuser.coda_element_1 t
)tt
—where tt.cnt>1 and (tt.el1_valid=0 or (tt.el1_valid=1 and cnt=cnt1 and
str<>str_check) )
where not (tt.cnt>1 and (tt.el1_valid=0 or (tt.el1_valid=1 and
cnt=cnt1 and
str<>str_check)))
You need to use derived table/inline view:
SELECT *
FROM (
select t.*,
count(*) over(partition by t.el1_code) cnt ,
count(*) over(partition by t.el1_code, t.el1_valid) cnt1 ,
concat(t.el1_name,t.el1_sname) str,
max(concat(t.el1_name,t.el1_sname)) over(partition by t.el1_code) str_check
from tasuser.coda_element_1 t
) tt
WHERE tt.conditions....
or common table expression:
WITH cte AS (
select t.*,
count(*) over(partition by t.el1_code) cnt ,
count(*) over(partition by t.el1_code, t.el1_valid) cnt1 ,
concat(t.el1_name,t.el1_sname) str,
max(concat(t.el1_name,t.el1_sname)) over(partition by t.el1_code) str_check
from tasuser.coda_element_1 t
)
SELECT *
FROM cte
WHERE conditions ...

Runnig the same query over and over again

I'm using Oracle SQL and I need help with hard query.
I have the following table (MyTable):
id int,
name1 int,
name2 int,
..
..
..
name80 int,
These column names are fake.
Here is my query:
select id ,cnt / (select count(*) from MyTable)
from(
select id, name1, name2, count(distinct name1) over(partition by name2) cnt
from my MyTable);
I need to run this query each time for next pair of columns. For example, the next pair will be:
select id ,cnt / (select count(*) from MyTable)
from(
select id, name2, name3, count(distinct name2) over(partition by name3) cnt
from my MyTable);
And so on.
The final output table need to include id and each pair calculation.
id int,
"calc of name1+name2" float,
"calc of name2+name3" float,
"calc of name3+name4" float,
"calc of name4+name5" float,
"calc of name5+name6" float,
...
...
...
"calc of name79+name80" float,
Can someone show me how to do that? I'll really appreciate any help. I'm feel lost.
Am I missing something? You want a query like this:
select id,
count(distinct name2) over (partition by name3) / count(*) over (),
count(distinct name3) over (partition by name4) / count(*) over (),
. . .
from mytable;
My guess is that your problem is typing all these rows.
You can run a query like this to generate the code:
select replace(replace('count(distinct <thiscol>) over (partition by <nextcol>) / count(*) over () as <thiscol>_<nextcol>,',
'<thiscol>', column_name
), '<nextcol>', lead(column_name) over (order by column_id)
)
from all_tab_columns atc
where table_name = 'mytable'
You can use dynamic sql (EXECUTE IMMEDIATE ) and USER_TAB_COLUMNS table for table column metadata.

SQL group by clause with two columns

Have a TSQL view, which I need to group by one column, however, am using nhibernate(C#) and am required to specify the Id column too.. my query looks like:
SELECT
row_number() over(order by id)as Id,
column_name,..etc
from tblName
group by column_name
which gives me an error that the Id has to be included in the group by clause.
Alternatively, I can write:
SELECT
row_number() over(order by id)as Id,
column_name,..etc
from tblName
group by column_name, id
which return multiple rows of the same column_name name.
Is there a way around this?
I think you want to do this:
Select row_number() over(order by column_name) as ID, column_name from (
Select distinct column_name from tblName
) as A
Do you mean this?
SELECT
row_number() over(partition by column_name order by id)as Id,
column_name,..etc
from tblName

Error : aggregate may not appear in the WHERE clause

I'm trying to get the max of column:
select * from
( select col1, count(*) as cnt from talbe1
group by col1
) dt
where cnt = max(cnt)
I tried to get exact value and it worked such as:
where cnt = 5
or
where cnt > 3
that was OK so what is wrong with the first query?
Edit: the numbers I put there (5, 3) are completely random, I want to get the maximum number of cnt.
Aggregate clauses have to go in the HAVING section. However, this won't work with your query as is. What you probably wanted to do was:
select top 1 col1, count(*) as cnt
from talbe1
group by col1
order by count(*) desc
You can do this with HAVING clause. For example if you want to get cnt=3 records
Select col1, count(*) as cnt from talbe1
Group by col1
Having count(*)=3
If you want to get MAX(cnt)
Select Top(1) col1, count(*) as cnt from talbe1
Group by col1
Order by cnt desc
I found a solution,
it was pretty simple:(I should have focused more)
select max(cnt) from
( select Fld301, count(*) as cnt from TbC3
group by Fld301
) dt
How about this query:
select * from
(
select
col1,
count(*) as cnt,
RANK() OVER(ORDER BY count(*) DESC) AS ran
from talbe1
group by col1
) dt
where ran=1