SQL ORACLE make result in one row - sql

I'm using ORACLE 11G , I want to make a query but I dont know how it works , and if is it possible:
This is my query :
SELECT DC.CLEF_NAME,DC.CLEF_X, DC.CLEF_Y, DC.CLEF_COL, DC.CLEF_ROW, DC.CLEF_CLASSCOLOR ,DCO.COLOR_NAME,DCO.COLOR_VALUE
FROM DASHBOARD_SAVE DS
LEFT JOIN DASHBOARD_CLEF DC ON DC.DASHBOARD_UID = DS.DASHBOARD_UID
LEFT JOIN DASHBOARD_COLOR DCO ON DCO.CLEF_UID = DC.CLEF_UID
WHERE DC.REGROUPEMENT_UID is null and DS.DASHBOARD_USERID = 'testok'
I got the result :
TESTDECLEF 1 1 1 1 BLUE 1 RED
TESTDECLEF 1 1 1 1 BLUE 2 PINK
But I want to get :
1 2
--------------------------------------
TESTDECLEF 1 1 1 1 BLUE RED PINK
Thanks for help

I am considering that color_name is 1,2 and color_value is PINK, RED.
You can use pivot as following:
Select * from
(SELECT DC.CLEF_NAME,DC.CLEF_X, DC.CLEF_Y, DC.CLEF_COL, DC.CLEF_ROW, DC.CLEF_CLASSCOLOR ,DCO.COLOR_NAME,DCO.COLOR_VALUE
FROM DASHBOARD_SAVE DS
LEFT JOIN DASHBOARD_CLEF DC ON DC.DASHBOARD_UID = DS.DASHBOARD_UID
LEFT JOIN DASHBOARD_COLOR DCO ON DCO.CLEF_UID = DC.CLEF_UID
WHERE DC.REGROUPEMENT_UID is null and DS.DASHBOARD_USERID = 'testok')
Pivot
(Max(COLOR_VALUE) for COLOR_NAME IN (1 as 1, 2 as 2)
);
Or you can use conditional aggregation as following:
SELECT DC.CLEF_NAME,DC.CLEF_X, DC.CLEF_Y, DC.CLEF_COL, DC.CLEF_ROW, DC.CLEF_CLASSCOLOR,
Max(case when DCO.COLOR_NAME = 1 then DCO.COLOR_VALUE end) as 1,
Max(case when DCO.COLOR_NAME = 2 then DCO.COLOR_VALUE end) as 2
FROM DASHBOARD_SAVE DS
LEFT JOIN DASHBOARD_CLEF DC ON DC.DASHBOARD_UID = DS.DASHBOARD_UID
LEFT JOIN DASHBOARD_COLOR DCO ON DCO.CLEF_UID = DC.CLEF_UID
WHERE DC.REGROUPEMENT_UID is null and DS.DASHBOARD_USERID = 'testok'
Group by
DC.CLEF_NAME,DC.CLEF_X, DC.CLEF_Y, DC.CLEF_COL, DC.CLEF_ROW, DC.CLEF_CLASSCOLOR;
Cheers!!

Related

how to generate a report in sql server from a previous select

Periodically I need to generate a report based on some data from database.
The first select IS:
SELECT DISTINCT
A.PRO_C_NOME,
B.ETS_C_NOME
FROM WETI_ETAPA_ITEM F
INNER JOIN WETE_ETAPA_ITEM_EDITORS E
ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO
INNER JOIN WETA_ETAPA_PROCESSO H
ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO
INNER JOIN WIPR_ITEM_PROCESSO C
ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO
INNER JOIN WIWF_ITEM_WORKFLOW D
ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO
INNER JOIN WPRO_PROCESSO A
ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0
LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G
ON G.ISP_N_ID = F.ETI_ISP_N_ID
INNER JOIN WETS_ETAPA_SLA B
ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO
Returns something like this:
C1
C2
A
1
A
1
A
3
B
2
B
2
B
2
B
3
B
3
B
3
C
1
C
2
I need a report from that first select returning something like this:
S.1
S.2
S.3
S.4
A
2
0
1
B
0
3
3
C
1
1
0
that is:
S.1 - distinct values from C1
S.2 - count 1 values in C2 for the S.1 value
S.3 - count 2 values in C2 for the S.1 value
S.4 - count 3 values in C2 for the S.1 value
Can someone help how do I solve this?
I tried many solutions, such as using temporary tables and selecting from another select but doesn't work at all for different reasons.
;with cte(PRO_C_NOME, ETS_C_NOME) as (
SELECT DISTINCT
A.PRO_C_NOME,
B.ETS_C_NOME
FROM WETI_ETAPA_ITEM F
INNER JOIN WETE_ETAPA_ITEM_EDITORS E
ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO
INNER JOIN WETA_ETAPA_PROCESSO H
ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO
INNER JOIN WIPR_ITEM_PROCESSO C
ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO
INNER JOIN WIWF_ITEM_WORKFLOW D
ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO
INNER JOIN WPRO_PROCESSO A
ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0
LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G
ON G.ISP_N_ID = F.ETI_ISP_N_ID
INNER JOIN WETS_ETAPA_SLA B
ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO
)
SELECT PRO_C_NOME AS 'S.1'
,SUM(CASE WHEN ETS_C_NOME=1 THEN 1 ELSE 0 END) AS 'S.2'
,SUM(CASE WHEN ETS_C_NOME=2 THEN 1 ELSE 0 END) AS 'S.3'
,SUM(CASE WHEN ETS_C_NOME=3 THEN 1 ELSE 0 END) AS 'S.4'
FROM cte
GROUP BY PRO_C_NOME

Query to show one column multiplied

I have the following 3 tables;
Table_Names:
user_id Name
------------------
1 Mark
2 Tom
3 Ana
Table_Language:
language_id Language
-----------------------
1 English
2 German
Table_Name_Lang
id user_id language_id
---------------------------
1 1 1
2 1 2
3 2 1
4 3 2
How can I create a query to show the expected results like those below?
Name Expr_1_Eng Expr_1_Ger
---------------------------------
Mark English German
Tom English
Ana German
Thanks Tok
I would do:
select n.name,
max(case when l.language = 'English' then l.language end) as has_English,
max(case when l.language = 'German' then l.language end) as has_German
from names n join
name_lang nl
on nl.user_id = n.user_id join
lang l
on nl.language_id = l.language_id
group by n.name
You can try to use JOIN with condition aggregate function
SELECT Name,
MAX(CASE WHEN tnl.language_id = 1 then tl.Language end),
MAX(CASE WHEN tnl.language_id = 2 then tl.Language end)
FROM
Table_Name_Lang tnl
JOIN Table_Names tn on tnl.language_id = tn.language_id
JOIN Table_Language tl on tl.user_id = tnl.user_id
GROUP BY Name
I think you should use pivot:
select n.name,[0] as language_one,[1] as language_two,[2],[3] from
(select n.name,tl.language
tablename n
left join Table_Name_Lang tnl on n.userid=tnl.userid
left join table_language tl on tl.id=tnl.id
group by n.name,tl.language
)T
pivot
(
language
for name in [0],[1],[2],[3]
)AS PivotTable;

Trying to GROUP BY with CASE WHEN THEN - postgresql

I have three tables PATH, ELEMENTS and ELEMENT_DETAILS with the following structure:
PATH:
ID
1
2
3
ELEMENTS:
ID | PATH_ID | DIRECTION | ELEMENT_DETAILS_ID
1 1 'left' 1
2 1 'right' 2
3 2 'left' 3
4 2 'right' 2
ELEMENT_DETAILS:
ID | NAME
1 'Henry'
2 'Mark'
3 'John'
I would like the result to be like so:
ID | left | right
1 'Henry' 'Mark'
2 'John' 'Mark'
This is the SQL I have come up with so far:
SELECT path.id,
CASE WHEN elements.direction='left' THEN element_details.name
ELSE NULL END
as left,
CASE WHEN elements.direction='right' THEN element_details.name
ELSE NULL END
as right,
FROM elements
INNER JOIN path on elements.path_id = path.id
LEFT JOIN element_details on elements.element_details_id = element_details.id
GROUP BY path.id
ORDER BY path.id
However, this does not work since postgres gives me an error saying elements.direction should be in group by. And including elements.direction in group_by does not give me aggregation at path.id level.
Stuck on this. Can someone please help.
I am using Postgres version 9.5
You need aggregation. Here is one method:
SELECT p.id,
MAX(CASE WHEN e.direction = 'left' THEN ed.name
END) as left,
MAX(CASE WHEN e.direction = 'right' THEN ed.name
END) as right
FROM elements e INNER JOIN
path p
ON e.path_id = p.id LEFT JOIN
element_details ed
ON e.element_details_id = ed.id
GROUP BY p.id
ORDER BY p.id

Most efficient way to SELECT and JOIN these tables

I have 4 tables:
Table1(Groups):
id_group name_group
1 abc
2 def
3 ghi
Table2(Color):
id_color name_color
1 blue
2 red
3 green
Table3(Variety):
id_variety id_color id_group name_variety
1 1 1 light
2 3 1 dark
3 6 2 dark
Table4(Tone):
id_tone id_color id_group name_tone
1 1 1 ocean
2 5 1 sea
3 9 3 clay
Given an id_group like 1 I want to make a selection resulting something like this:
id_group id_color name_variety name_tone
1 1 light ocean
1 3 dark NULL
1 5 NULL sea
I was able to solve the problem with an union and changing the order of the JOINS but I think that there must be another solution
SELECT
GRO.id_group, COL.id_color, VARI.name_variety, TONE.name_tone
FROM
groups GRO
LEFT OUTER JOIN
variety VARI ON (VARI.id_group = GRO.id_group)
LEFT OUTER JOIN
tone TONE ON (TONE.id_group = GRO.id_group)
AND (TONE.id_color = VARI.id_color)
LEFT OUTER JOIN
color COL ON (COL.id_color = VARI.id_color)
OR (COL.id_color = TONE.id_color)
WHERE
GRO.id_group = 1
UNION
SELECT
GRO.id_group, COL.id_color, VARI.name_variety, TONE.name_tone
FROM
groups GRO
LEFT OUTER JOIN
tone TONE ON (TONE.id_group = GRO.id_group)
LEFT OUTER JOIN
variety VARI ON (VARI.id_group = GRO.id_group)
AND (VARI .id_color = TONE.id_color)
LEFT OUTER JOIN
color COL ON (COL.id_color = VARI.id_color)
OR (COL.id_color = TONE.id_color)
WHERE
GRO.id_group = 1
I think what you want is something more like:
SELECT
id_group,
id_color,
MAX(max_variety),
MAX(max_tone)
FROM
(SELECT
v.id_group,
v.id_color,
MAX(name_variety) AS max_variety,
MAX(name_tone) AS max_tone
FROM
variety V INNER JOIN
color c ON
V.id_color = c.id_color LEFT OUTER JOIN
tone t ON
t.id_group = v.id_group AND
t.id_color = V.id_color
WHERE
v.id_group = 1
GROUP BY
v.id_group,
v.id_color
UNION ALL
SELECT
t.id_group,
t.id_color,
MAX(name_variety) AS max_variety,
MAX(name_tone) AS max_tone
FROM
tone t INNER JOIN
color c ON
t.id_color = c.id_color LEFT OUTER JOIN
variety V ON
v.id_group = t.id_group AND
v.id_color = t.id_color
WHERE
t.id_group = 1
GROUP BY
t.id_group,
t.id_color) u
GROUP BY
id_group,
id_color
instead of using union you could use full join , as full join return all result from first table and also all results from the second tables.
SELECT
GRO.id_group, COL.id_color, VARI.name_variety, Tone.name_tone from Variety VARI
join Color COL on col.id_color=VARI col.id
join Groups GRO on GRO.id_group=VARI.id_group
full join Tone on Tone.id_group=GRO.id_group
where GRO.id_group = 1

Get separate count for each condition within group

I am trying to get a view of table information from and Oracle 10g table that lists the counts of specific values of a column in their own columns with each row being the group value.
for example:
The first select is :
SELECT processed_by, count(priority) as P2
FROM agreement_activity
WHERE priority = '2'
GROUP BY processed_by
Which outputs:
PROCESSED_BY P2
------------------------------ ----------
Alicia 2
Christine 2
The second select is:
SELECT processed_by, count(priority) as P1
FROM agreement_activity
WHERE priority = '1'
GROUP BY processed_by
Which outputs:
PROCESSED_BY P1
------------------------------ ----------
Bonita 2
Alicia 6
Christine 2
What I am looking for is to output those values as the following:
PROCESSED_BY P1 P2
------------------------------ ---------- ----------
Bonita 2
Alicia 6 2
Christine 2 2
Is that possible?
You can use sum with the case expression to get conditional count:
select processed_by
, sum(case when priority = 1 then 1 else 0 end) as P1
, sum(case when priority = 2 then 1 else 0 end) as P2
from agreement_activity
group by processed_by
P.S. If you don't care that P1 or P2 maybe null instead of 0 you can omit else in both expressions.
this is how I implement the sql. I'm using firebird code but I think you can convert the code into your sql
SELECT
a.equipmentid,
a.name equipname,
w1.countwarranty1 ,
w2.countwarranty2
FROM TBL_EQUIPMENTMST a
inner JOIN
(select c.equipmentid, count(c.WARRANTYID) countwarranty1 from tbl_equipwarranty c where c.serviceproduct='1' group by c.equipmentid) w1
ON w1.equipmentid = a.equipmentid
inner JOIN
(select d.equipmentid, count(d.WARRANTYID) countwarranty2 from tbl_equipwarranty d where d.serviceproduct='2' group by d.equipmentid) w2
ON w2.equipmentid = a.equipmentid
inner JOIN
(select e.equipmentid, count(e.equiplocationid) countlocation from tbl_equiplocation e group by e.equipmentid) w3
ON w3.equipmentid = a.equipmentid
this is the output
My warranty table has only 2 warranty for equipment each that's why its only showing 2.
you can also inner join to the same table with different count.
as you can see my warranty has multiple warranty where serviceproduct is different on each table
if I edit your code it will be like this
SELECT a.processed_by, b.priority as p2, c.priority as p1
FROM agreement_activity a
inner join
(
SELECT w1.processed_by, count(w1.priority) as P2 FROM agreement_activity w1
WHERE w1.priority = '2' GROUP BY w1.processed_by
) b
on a.processed_by = b.processed_by
inner join
(
SELECT w2.processed_by, count(w2.priority) as P2 FROM w2.agreement_activity
WHERE w2.priority = '1' GROUP BY w2.processed_by
) c
on a.processed_by = c.processed_by
test it