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
Related
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
I have 3 tables. 1st table stores coil information, 2nd table store coil information in transport and 3rd stores reserved coils.
coils
ID
SERIAL
COLOR
MATERIAL
STATUS
1
12345
5
1
2
2
12346
4
1
3
3
12347
3
1
2
coils_in_transport
ID
SERIAL
COLOR
MATERIAL
STATUS
1
f34S5
5
1
2
2
A23GG6
4
1
3
3
ff2S147
3
1
2
reserved_coils
ID
NUMBER
QUANTITY
START
END
1
12345
25
2022-05-01
2023-05-01
3
12347
252
2022-01-01
2023-05-01
4
A23GG6
33
2022-04-01
2023-05-01
5
ff2S147
35
2022-08-01
2023-05-01
I need to write query that will get all reserved coils (reserved_coils) that has status 2 and for each coil I need to join tables for materials and colors
material
ID
NAME
1
color
ID
NAME
I wrote query but it doesn't show coils in transport that are reserved, here is what I tried
SELECT a.QUANTITY, a.START, a.END, b.name, m.name
FROM reserved_coils a
LEFT JOIN coils b ON a.number = b.serial
LEFT JOIN coils_in_transport c ON a.number = c.serial
LEFT JOIN material m ON b.material = m.id
LEFT JOIN material b ON b.material = b.id
where b.status = 2 and c.status = 2
To get all coils and colis_in_transport you need to use UNION for SELECT statements for both tables, each filtered by status value, which should be equal to 2. Then you need to do a JOIN between reserved_coils and the result of UNION to filter out reserved_coils rows.
Your query would be like this
SELECT
r.quantity,
r.start,
r.[end],
c.serial,
material.name AS material,
color.name AS color
FROM reserved_coils r
JOIN (
SELECT * FROM coils WHERE status = 2
UNION
SELECT * FROM coils_in_transport WHERE status = 2
) c ON r.number = c.serial
LEFT JOIN material ON material.id = c.material
LEFT JOIN color ON color.id = c.color
Demo
If you want left join twice on same table, this might help
SELECT a.QUANTITY, a.START, a.[END], isnull(b.serial,c.serial) serial,isnull(c1.name,c2.name) color, isnull(m.name,n.name) material
FROM reserved_coils a
LEFT JOIN coils b ON a.number = b.serial
LEFT JOIN coils_in_transport c ON a.number = c.serial
LEFT JOIN material m ON b.material = m.id
LEFT JOIN material n ON c.material = n.id
LEFT JOIN color c1 on b.color=c1.id
LEFT JOIN color c2 on c.color=c2.id
where isnull(b.status,c.status) = 2
DB<>Fiddle
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!!
I have a problem with the combination of multiple tables.
My SQL query:
SELECT *
FROM CRM.Bank as a
JOIN CRM.Documents as b ON a.Bank_ID = b.Documents_ID
JOIN CRM.Counterparties as c ON c.Counterparties_ID = b.Documents_ID
JOIN CRM.Items as d ON d.Document_tran_ID = b.Documents_ID
I have table CRM.Items, which has the following columns:
Item_ID Document_tran_ID Name
======= ================ ====
1 1 Advertising banner
2 1 Shipping costs
3 2 Garden tent
4 2 Additional fasteners
5 2 Shipping costs
And now I have a problem how to connect only the first items to the document (d.Document_tran_ID = b.Documents_ID ) ??
I know I should use SELECT TOP. However, I have a problem with creating the correct query
Expect the result in the form of:
Bank_ID Documents_ID Counterparties_ID Document_tran_ID Name
======= ============ ================= ================ ====
22 1 4 1 Advertising banner
23 2 20 2 Garden tent
24 3 21 3 Other
Only the first Item from the document is matched.
I think you can try to use CROSS APPLY join. In the inner query, you can apply order condition for selecting TOP row
SELECT *
FROM CRM.Bank as a
JOIN CRM.Documents as b ON a.Bank_ID = b.Documents_ID
JOIN CRM.Counterparties as c ON c.Counterparties_ID = b.Documents_ID
CROSS APPLY
(select top 1 * from CRM.Items i where i.Document_tran_ID = b.Documents_ID) as d
use sub-query for documents table
SELECT *
FROM CRM.Bank as a
JOIN ( select min(Document_tran_ID) as Documents_ID from CRM.Documents) as b ON a.Bank_ID = b.Documents_ID
JOIN CRM.Counterparties as c ON c.Counterparties_ID = b.Documents_ID
JOIN CRM.Items as d ON d.Document_tran_ID = b.Documents_ID
Table Product
Id name t1 t2
1 A 1 4
2 B 5 2
3 C 3 1
4 D 4 5
Table Tan
id tan
1 tanA
2 tanB
3 tanC
4 tanD
5 tanE
I have two above table and i want the result as below in expecting result how it is possible.
Expecting result
A tanA tanD
B tanE tanB
C tanC tanA
D tanD tanE
You can join on multiple tables:
SELECT p.Name AS ProductName,
t1.tan AS Tan1,
t2.tan AS Tan2
FROM dbo.Product p
INNER JOIN Tan t1
ON p.t1 = t1.id
INNER JOIN Tan t2
ON p.t2 = t2.id
ORDER BY ProductName ASC
Demo
You can select from the tan table twice by using a table alias:
FROM Product INNER JOIN tan tan1 ON tan1.id = product.t1
INNER JOIN tan tan2 ON tan2.id = product.t2
select the appropriate columns:
SELECT Product.name AS name, tan1.tan AS Tan_1, tan2.tan AS Tan_2
to give:
SELECT product.name AS name, tan1.tan AS Tan_1, tan2.tan AS Tan_2
FROM Product INNER JOIN tan tan1 ON tan1.id = product.t1
INNER JOIN tan tan2 ON tan2.id = product.t2