convert row output to column in oracle - sql

with cte1 as
(
select count(*) as count_emp from emp;
),
cte2 as
(
select count(*) as count_dept from dept;
),
cte3 as
(
select count(*) as count_hr from hr;
)
select count_emp,count_dept,count_hr from cte1,cte2,cte3;
I want output in one column with three rows.
for more details see image .

Use union all:
select count_emp from cte1
union all
select count_dept from cte2
union all
select count_hr from cte3;
Do note that the results are not guaranteed to be in any particular order. I would highly advise you to label the rows:
select 'emp', count_emp as cnt from cte1
union all
select 'dept', count_dept from cte2
union all
select 'hr', count_hr from cte3;

Related

replacement of Offset Limit in SQL Server

We have DataTemp table which has the records in desc order.
select * from (
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
sno - Auto Id.
id - code of the Doors*.
N_th_Record - for denoting the n the record.
At a time, only three* records per Door are need to store on this table. For example Door 'a' has new entry(means 4th record) then first of 'a' Door need to delete.
4th record:
select * from (
select 10,'a',4 union --- new entry
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union -- need to delete
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
I do following query. But I need easiest way for deleting the row. Because, we are try to reduce the time consumption of over all project.
delete from door where sno = (
select sno from (
select 10,'a',4 union
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
where id = 'a'
order by sno desc -- For 'DataTemp' *order by* is no needed.
offset 3 rows fetch next 1 rows only
)
Note:
Three rows and three Door are given for example. Actually we work with 144 rows per 12 Doors.
Before this delete, we check lot of Business rules.
Version: SQL Server 2012
You could use ROW_NUMBER:
WITH cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY id ORDER BY sno DESC) rn FROM t)
DELETE FROM cte WHERE rn > 3;
db<>fiddle demo

Select rows with same ID/email but different value in other table

Select rows with same ID/email but different value in other table
I have two tables: person and email, now there are mail addresses that have the same value, and persons/ID with different values.
Can anyone tell how to write an SQL query for this? I have tried but I can't figure it out. I have found some answers but then it is always finding the match in the same table
Like this
Table_person. ​​Table_email
1​​​ email#persoon1
2​​​ email#persoon2
3​​​ email#persoon3
4​​​ email#persoon1
5​​​ email#persoon5
6​​​ email#persoon2
The output should be
Table_person​​ Table_email
1​​​ email#persoon1
4​​​ email#persoon1
2​​​ email#persoon2
6​​​ email#persoon2
Using a common table expression with row_number()
;with cte as (
select *
, rn = row_number() over (partition by email order by person_id)
from email e
)
select *
from cte
where exists (
select 1
from cte i
where i.email = cte.email
and rn > 1
)
or using exists()
select *
from email e
where exists (
select 1
from email i
where i.email = e.email
and i.person_id <> e.person_id
)
rextester demo: http://rextester.com/JHFEF82373
Hope it will helps you
;with cte(Table_person,​​Table_email)
AS
(
SELECT 1​​​,'email#persoon1' UNION ALL
SELECT 2​​​,'email#persoon2' UNION ALL
SELECT 3​​​,'email#persoon3' UNION ALL
SELECT 4​​​,'email#persoon1' UNION ALL
SELECT 5​​​,'email#persoon5' UNION ALL
SELECT 6​​​,'email#persoon2'
)
,Cte2
AS
(
SELECT Table_person,​​Table_email From
(
Select Table_person,​​Table_email,ROW_NUMBER()OVER(Partition by Table_email Order By Table_person )Seq
from cte
)dt WHERE dt.Seq>1
)
,Final
AS
(
SELECT Table_person,​​Table_email From
(
Select Table_person,​​Table_email,ROW_NUMBER()OVER(Partition by Table_email Order By Table_email )Seq2
from cte
)dt
where dt.Seq2>1
Union ALL
SELECT Table_person,​​Table_email From cte2
)
SELECt Table_person,​​Table_email from Final

Get Var() and AVG() from many columns

I'm building a query to show average and variance from many columns.
To get the average I use this:
SELECT *,
(SELECT AVG(t.c)
FROM (
SELECT peca_1 UNION ALL
SELECT peca_2 UNION ALL
SELECT peca_3 UNION ALL
SELECT peca_4 UNION ALL
SELECT peca_5 UNION ALL
SELECT peca_6 UNION ALL
SELECT peca_7 UNION ALL
SELECT peca_8 UNION ALL
SELECT peca_9 UNION ALL
SELECT peca_10
) t(c)
) as [media]
from Durabilidade
where cd_durabilidade = 1
The result is:
Now I need a new column with VAR(media) comparing each row with first row.
Any idea?
I think this is a case where cross apply is appropriate. I am assuming that you want the variance of the values as calculated by the var() function:
SELECT *, t.avgval as [media], t.varval
from Durabilidade d cross apply
(select avg(t.val) as avgval, var(t.val) as varval
from (select d.peca_1 union all
select d.peca_2 union all
select d.peca_3 union all
select d.peca_4 union all
select d.peca_5 union all
select d.peca_6 union all
select d.peca_7 union all
select d.peca_8 union all
select d.peca_9 union all
select d.peca_10
) t(val) -- t(val) to work
) t
where cd_durabilidade = 1
Something like this?
SELECT *,
VAR(media) AS [variance]
FROM
(
SELECT *,
(SELECT AVG(t.c)
FROM (
SELECT peca_1 UNION ALL
SELECT peca_2 UNION ALL
SELECT peca_3 UNION ALL
SELECT peca_4 UNION ALL
SELECT peca_5 UNION ALL
SELECT peca_6 UNION ALL
SELECT peca_7 UNION ALL
SELECT peca_8 UNION ALL
SELECT peca_9 UNION ALL
SELECT peca_10
) t(c)
) as [media]
from Durabilidade
where cd_durabilidade = 1
) x
GROUP BY
column1_from_durabilidade
,column2_from_durabilidade
--etc
,media

How to get query to return rows where first three characters of one row match another row?

Here's my data:
with first_three as
(
select 'AAAA' as code from dual union all
select 'BBBA' as code from dual union all
select 'BBBB' as code from dual union all
select 'BBBC' as code from dual union all
select 'CCCC' as code from dual union all
select 'CCCD' as code from dual union all
select 'FFFF' as code from dual union all
select 'GFFF' as code from dual )
select substr(code,1,3) as r1
from first_three
group by substr(code,1,3)
having count(*) >1
This query returns the characters that meet the cirteria. Now, how do I select from this to get desired results? Or, is there another way?
Desired Results
BBBA
BBBB
BBBC
CCCC
CCCD
WITH code_frequency AS (
SELECT code,
COUNT(1) OVER ( PARTITION BY SUBSTR( code, 1, 3 ) ) AS frequency
FROM table_name
)
SELECT code
FROM code_frequency
WHERE frequency > 1
WITH first_three AS (
...
)
SELECT *
FROM first_three f1
WHERE EXISTS (
SELECT 1 FROM first_three f2
WHERE f1.code != f2.code
AND substr(f1.code, 1, 3) = substr(f2.code, 1, 3)
)
select res from (select res,count(*) over
(partition by substr(res,1,3) order by null) cn from table_name) where cn>1;

Is it possible to Union the result sets of two CTEs with identical structure

I want to union the results sets from the following CTEs so that I get 4 rows of data.
Id Name
-------------
1 Test1
2 Test2
3 Test3
4 Test4
The Sql I want to use is as follows
;with CTE1 (Id,Name)
as
(
select 1 as Id, 'Test1' as Name
union all
select 2, 'Test2'
)
select * from CTE1
union all
;with CTE2 (Id,Name)
as
(
select 3 as Id, 'Test3' as Name
union all
select 4, 'Test4'
)
select * from CTE2
However, I am getting a syntax error suggesting I can not use Union All between the two CTEs.
How can I go around this?
YES, but not the way you are doing it. try it this way:
;with CTE1 (Id,Name)
as
(
select 1 as Id, 'Test1' as Name
union all
select 2, 'Test2'
)
,CTE2 (Id,Name)
as
(
select 3 as Id, 'Test3' as Name
union all
select 4, 'Test4'
)
select * from CTE1
union all
select * from CTE2
you can have multiple CTEs chained together. There is only one "WITH", and a comma between CTEs. Then in the statement following the CTE, you can reference any of those CTEs.
;with CTE1 (Id,Name)
as
(
select 1 as Id, 'Test1' as Name
union all
select 2, 'Test2'
)
,CTE2 (Id,Name)
as
(
select 3 as Id, 'Test3' as Name
union all
select 4, 'Test4'
)
select * from CTE1
union all
select * from CTE2
with CTE1 (Id,Name)
as
(
select 1 as Id, 'Test1' as Name
union all
select 2, 'Test2'
),
CTE2 (Id,Name)
as
(
select * from CTE1
union all
select 3 as Id, 'Test3' as Name
union all
select 4, 'Test4'
)
select * from CTE2
or
with CTE1 (Id,Name)
as
(
select 1 as Id, 'Test1' as Name
union all
select 2, 'Test2'
),
CTE2 (Id,Name)
as
(
select 3 as Id, 'Test3' as Name
union all
select 4, 'Test4'
)
select * from CTE1
union all
select * from CTE2