Sub select & union all - sql

SELECT C.ClientCaseNumber,
Sum(CASE
WHEN CA.CaseActionDefinitionId IN (28, 29, 30) THEN 1
ELSE 0
END) AS [Wezwania],
Sum(CASE
WHEN CA.CaseActionDefinitionId IN (14, 21) THEN 1
ELSE 0
END) AS [Kontakt],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 32 THEN 1
ELSE 0
END) AS [SMS],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 44 THEN 1
ELSE 0
END) AS [Zgon],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 49 THEN 1
ELSE 0
END) AS [Areszt],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 37 THEN 1
ELSE 0
END) AS [Odmowa],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 39 THEN 1
ELSE 0
END) AS [Podważa],
Sum(CASE
WHEN CA.CaseActionDefinitionId = 99 THEN 1
ELSE 0
END) AS [Ugoda],
[Adres],
[Numer],
[Mail],
[Powód]
FROM (SELECT Notes AS [Adres]
FROM CaseActionHistory
WHERE CaseActionDefinitionId = 68
UNION ALL
SELECT Info AS [Numer]
FROM CaseActionHistory
WHERE CaseActionDefinitionId IN (54, 55, 56, 58,
59, 60, 61, 62, 63)
UNION ALL
SELECT Notes AS [Mail]
FROM CaseActionHistory
WHERE CaseActionDefinitionId = 66
UNION ALL
SELECT Description AS [Powód]
FROM CaseActionDefinition
JOIN CaseActionHistory AS C
ON DefinitionId = C.CaseActionDefinitionId
WHERE DefinitionId BETWEEN 70 AND 78) AS x
INNER JOIN CaseDetails AS C
ON x.CaseDetailId = C.CaseDetaislId
INNER JOIN CaseActionHistory AS CA
ON C.CaseDetailsId = CA.CaseDetailId
WHERE C.ClientId = '11'
GROUP BY C.ClientCaseNumber
I've got such query. As return shows error of invalid columns "CaseDetailId, CaseDetailsId, Mail, Numer, Powód".
http://oi39.tinypic.com/2vwy44n.jpg
That's more or less how the results should look like.
ClientCaseNumber is taken from table CaseDetails
All the sums are sums of code added to CaseActionHistory table.
Notes/Info are in CaseActionHistory table
Description is placed in CaseActionDefinition table.
Between tables there are such connections:
CaseDetails.CaseDetailId = CaseActionHistory.CaseDetailsId
CaseActionHistory.CaseActionDefinitionId = CaseActionDefinition.DefinitionId

The UNION clause does not work like that.
This query:
select Notes as [Adres] from CaseActionHistory where ...
UNION ALL
select Info as [Numer] from CaseActionHistory where ...
UNION ALL
select Notes as [Mail] from CaseActionHistory where ...
UNION ALL
select Description as [Powód] from CaseActionDefinition join CaseActionHistory ...
will not populate a table with 4 columns. Instead it will be a table with one column, with all the values one after the other. The name of the column will be taken from the first SELECT, i.e.
if the first query returns values 1 and 2,
the second query returns values 3 and 4
the third query returns values 5 and 6
the fourth query returns values 7 and 8
you wont get:
Adres | Numer | Mail | Powód
------------------------------
1 | 3 | 5 | 7
2 | 4 | 6 | 8
but you'll get:
Adres
-------
1
2
3
4
5
6
7
8

Are you not missing the alias 'x' from these fields:
SELECT
C.ClientCaseNumber
,sum(case when CA.CaseActionDefinitionId in (28,29,30) then 1 else 0 end) as [Wezwania]
,sum(case when CA.CaseActionDefinitionId in (14,21) then 1 else 0 end) as [Kontakt]
,sum(case when CA.CaseActionDefinitionId = 32 then 1 else 0 end) as [SMS]
,sum(case when CA.CaseActionDefinitionId = 44 then 1 else 0 end) as [Zgon]
,sum(case when CA.CaseActionDefinitionId = 49 then 1 else 0 end) as [Areszt]
,sum(case when CA.CaseActionDefinitionId = 37 then 1 else 0 end) as [Odmowa]
,sum(case when CA.CaseActionDefinitionId = 39 then 1 else 0 end) as [Podważa]
,sum(case when CA.CaseActionDefinitionId = 99 then 1 else 0 end) as [Ugoda]
,x.[Adres]
,x.[Numer]
,x.[Mail]
,x.[Powód]
FROM
(select Notes as [Adres] from CaseActionHistory where CaseActionDefinitionId = 68
UNION ALL
select Info as [Numer] from CaseActionHistory where CaseActionDefinitionId in (54,55,56,58,59,60,61,62,63)
UNION ALL
select Notes as [Mail] from CaseActionHistory where CaseActionDefinitionId = 66
UNION ALL
select Description as [Powód] from CaseActionDefinition join CaseActionHistory as C on DefinitionId = C.CaseActionDefinitionId where DefinitionId between 70 and 78)
AS x
inner join CaseDetails as C on x.CaseDetailId = C.CaseDetaislId
inner join CaseActionHistory as CA on C.CaseDetailsId = CA.CaseDetailId
where C.ClientId = '11'
GROUP by C.ClientCaseNumber

Related

How to Combine two pivot tables when both the tables are combined by inner Join function

Tag
SELECT TOP (1000) [System_Order_Id]
,[Batch_No]
,[Material_Code]
,[Set_Weight]
,[Actual_Weight]
FROM [master].[dbo].[Consumption_Report]
Batch No
System Id
Material Code
Set Weight
Actual Weight
1
1
1
Mat01
100
99
2
1
1
Mat02
50
55
3
1
1
Mat03
80
35
4
1
1
Mat04
40
20
SELECT TOP (1000)[Batch_End_TimeStamp]
,[Machine_Code]
, [User_Order_Id]
,[Batch_No]
,[Recipe_Code]
,[Cycle_Time]
,[System_Mode]
FROM [master].[dbo].[Batch_Report]
System Id
Batch No
Machine_Code
Recipe_Code
Cycle_Time
1
1
1
23
AA01
532
My Code:
WITH Consumption_Report AS (
SELECT
t1.Material_Code,
t1.Set_Weight,
t2.Batch_End_TimeStamp,
t2.Machine_Code,
t2.User_Order_Id,
t2.Recipe_Code,
t2.Cycle_Time
FROM
dbo.Consumption_Report t1
INNER JOIN dbo.Batch_Report t2 ON t2.Batch_No = t1.Batch_No
)
SELECT *
FROM Consumption_Report
PIVOT (AVG(Set_Weight) FOR Material_Code IN (Mat01,Mat02,Mat03,Mat04)) P
I want output like this:
Batch No
System Id
Machine_Code
Recipe_Code
Cycle_Time
Mat 01 Set Weight
Mat 01 Actual Weight
Mat 02 Set Weight
Mat 02 Actual Weight
Mat 03 Set Weight
Mat 03 Actual Weight
Mat 04 Set Weight
Mat 04 Actual Weight
1
1
1
23
AA01
532
100
99
50
55
80
35
40
20
I don't see what the second table has to do with anything. Just use conditional aggregation:
select Id, Batch_No, System_Id,
max(case when Material_Code = 'Mat01' then set_weight end) as mat01_set_weight,
max(case when Material_Code = 'Mat01' then actual_weight end) as mat01_actual_weight,
max(case when Material_Code = 'Mat02' then set_weight end) as mat02_set_weight,
max(case when Material_Code = 'Mat02' then actual_weight end) as mat02_actual_weight,
max(case when Material_Code = 'Mat03' then set_weight end) as mat03_set_weight,
max(case when Material_Code = 'Mat03' then actual_weight end) as mat03_actual_weight,
max(case when Material_Code = 'Mat04' then set_weight end) as mat04_set_weight,
max(case when Material_Code = 'Mat04' then actual_weight end) as mat04_actual_weight
from Consumption_Report
group by Id, Batch_No, System_Id;
SELECT * FROM Batch_Report
INNER JOIN (
select Batch_No,
sum(case when Material_Code = 'Mat01' then Set_Weight else 0 end) as Mat01,
sum(case when Material_Code = 'Mat01' then Actual_Weight else 0 end) as
Mat01_Act,
sum(case when Material_Code = 'Mat02' then Set_Weight else 0 end) as Mat02,
sum(case when Material_Code = 'Mat02' then Actual_Weight else 0 end) as
Mat02_Act,
sum(case when Material_Code = 'Mat03' then Set_Weight else 0 end) as Mat03,
sum(case when Material_Code = 'Mat03' then Actual_Weight else 0 end) as
Mat03_Act,
sum(case when Material_Code = 'Mat04' then Set_Weight else 0 end) as Mat04,
sum(case when Material_Code = 'Mat04' then Actual_Weight else 0 end) as Mat04_Act
from Consumption_Report
group by Batch_No) Consumption_Report
ON Batch_Report.Batch_No = Consumption_Report.Batch_No;

Solution to insert sub-query with additional group by

I'm trying to merge two working SQL query's in Oracle SQL Developer but can't seem to get the sub's Group By's to play nicely. I want/expect to see separate totals for each row but I'm getting an overall total for all rows.
I tried adding the second query as sub-query.
Query 1:
SELECT SOURCE,
sum(case when status = 'C1' then 1 else 0 end) as "C1",
sum(case when status = 'C2' then 1 else 0 end) as "C2",
sum(case when status = 'C3' then 1 else 0 end) as "C3",
sum(case when status = 'C4' then 1 else 0 end) as "C4",
sum(case when status = 'C5' then 1 else 0 end) as "C5"
FROM TABLE.req
GROUP BY SOURCE
ORDER BY SOURCE;
Query 2 to be added to the above:
SELECT SOURCE, COUNT(REQ.SOURCE) AS "Done in 7 Days"
FROM TABLE.req REQ
JOIN TABLE.audit AUD ON REQ.ROW_ID = AUD.RECORD_ID
WHERE (AUD.LAST_UPD - REQ.CREATED) <= 7
AND REQ.STATUS = 'Complete'
GROUP BY SOURCE;
Tried Sub-Query:
SELECT SOURCE,
sum(case when status = 'C1' then 1 else 0 end) as "C1",
sum(case when status = 'C2' then 1 else 0 end) as "C2",
sum(case when status = 'C3' then 1 else 0 end) as "C3",
sum(case when status = 'C4' then 1 else 0 end) as "C4",
sum(case when status = 'C5' then 1 else 0 end) as "C5"
(SELECT SOURCE, COUNT(REQ.SOURCE)
FROM TABLE.req REQ
JOIN TABLE.audit AUD ON REQ.ROW_ID = AUD.RECORD_ID
WHERE (AUD.LAST_UPD - REQ.CREATED) <= 7
AND REQ.STATUS = 'Complete'
GROUP BY SOURCE) AS "Done in 7"
FROM TABLE.req
GROUP BY SOURCE
ORDER BY SOURCE;
Query 1 returns:
A 0 0 0 0 0
B 0 0 3026 26 2461
C 0 0 0 0 0
D 3 39 2 1 19
E 0 0 61156 0 79430
Query 2 returns:
A 2906
B 10
C 28
D 7
E 0
ACTUAL:
Sub-Query returns the additional Column BUT it's being totaled
A 0 0 0 0 0 2951
B 0 0 3026 26 2461 2951
C 0 0 0 0 0 2951
D 3 39 2 1 19 2951
E 0 0 61156 0 79430 2951
EXPECTED:
Sub-Query returns the additional Column BUT it's being totaled
A 0 0 0 0 0 2906
B 0 0 3026 26 2461 10
C 0 0 0 0 0 28
D 3 39 2 1 19 7
E 0 0 61156 0 79430 0
You seem to want a correlated subquery:
SELECT SOURCE,
sum(case when status = 'C1' then 1 else 0 end) as "C1",
sum(case when status = 'C2' then 1 else 0 end) as "C2",
sum(case when status = 'C3' then 1 else 0 end) as "C3",
sum(case when status = 'C4' then 1 else 0 end) as "C4",
sum(case when status = 'C5' then 1 else 0 end) as "C5",
(SELECT COUNT(*)
FROM TABLE.req REQ r2 JOIN
TABLE.audit a
ON r2.ROW_ID = a.RECORD_ID
WHERE r2.SOURCE = r.SOURCE AND
(a.LAST_UPD - r2.CREATED) <= 7 AND
r2.STATUS = 'Complete'
)
FROM TABLE.req r
GROUP BY SOURCE
ORDER BY SOURCE;

how to show my data as in interval form in sql

I have a Table like that:
ID Class Marks
1 12th 0
2 10th 25
3 09th 24
4 12th 50
5 10th 60
6 09th 70
Desired Output Like that:-
Marks CLass12th class9th class10th
0-25 1 1 1
25-50 1 0 0
50-60 1 0 1
60-70 0 1 1
Total 3 2 3
how can i do same with sql
CREATE TABLE marks
(
id INT,
class VARCHAR(200),
marks INT
);
INSERT INTO marks
VALUES (1,
'12th',
0);
INSERT INTO marks
VALUES (1,
'10th',
25);
INSERT INTO marks
VALUES (1,
'9th',
24);
INSERT INTO marks
VALUES (1,
'12th',
50);
INSERT INTO marks
VALUES (1,
'10th',
60);
INSERT INTO marks
VALUES (1,
'9th',
70);
-----not able to put (0-24) condition in marks as it is actually minus the value as -24 -----
SELECT CASE
WHEN marks >= 0
AND marks < 25 THEN ( 024 )
WHEN marks >= 25
AND marks <= 50 THEN ( 2550 )
WHEN marks >= 51
AND marks < 60 THEN ( 5160 )
WHEN marks >= 60
AND marks < 71 THEN ( 6070 )
ELSE NULL
END AS marks,
Sum(class12th) AS CLass12th,
Sum(class10th) AS CLass9th,
Sum(class9th) AS CLass9th
FROM (SELECT id,
marks,
[12th] AS CLass12th,
[10th] AS CLass10th,
[9th] AS CLass9th
FROM (SELECT id,
class,
marks
FROM marks) AS SourceTable
PIVOT ( Count(class)
FOR class IN ([12th],
[10th],
[9th]) ) AS pivottable)a
GROUP BY marks
Try this :
select '0-25', sum(case when class = '12th' then 1 else 0 end) '12th',sum(case when class = '10th' then 1 else 0 end) '10th',sum(case when class = '9th' then 1 else 0 end) '9th'
from Yourtable where marks >= 0 and marks < = 25
union
select '25-50', sum(case when class = '12th' then 1 else 0 end),sum(case when class = '10th' then 1 else 0 end),sum(case when class = '9th' then 1 else 0 end)
from Yourtable where marks >= 25 and marks < = 50
union
select '50-60', sum(case when class = '12th' then 1 else 0 end),sum(case when class = '10th' then 1 else 0 end),sum(case when class = '9th' then 1 else 0 end)
from Yourtable where marks >= 50 and marks < = 60
union
select '60-70', sum(case when class = '12th' then 1 else 0 end),sum(case when class = '10th' then 1 else 0 end),sum(case when class = '9th' then 1 else 0 end)
from Yourtable where marks >= 60 and marks < = 70
union
select 'total', sum(case when class = '12th' then 1 else 0 end),sum(case when class = '10th' then 1 else 0 end),sum(case when class = '9th' then 1 else 0 end)
from Yourtable
You need to store your ranges our use a CTE and use it in a query like this:
;with ranges as (
select 0 fromMark, 25 toMark, '0-25' title
union all select 25,50, '25-50'
union all select 50,60, '50-60'
union all select 60,70, '60-70'
union all select 0,100, 'Total'
)
select
r.title,
count(case when t.Class = '12th' then 1 end) Class12th,
count(case when t.Class = '09th' then 1 end) Class9th,
count(case when t.Class = '10th' then 1 end) Class10th
from yourTable t
left join ranges r
on t.Marks >= r.fromMark and t.Marks < r.toMark
group by
r.title;

Get COUNT with a condition from a joined table

I have a table SyncHistory:
SyncHistoryId SyncType SyncDateTime
-----------------------------------------------------
55 1 2017-11-28 09:30:51.810
56 1 2017-11-28 10:30:32.123
And then another table SyncDetails:
SyndDetailId SyncHistoryId ItemId ItemCreated ItemChanged
---------------------------------------------------------------------------
98 55 12345 1 0
99 55 23183 1 0
100 55 87687 0 1
101 55 23234 0 0
102 55 23222 0 0
103 56 9928 1 0
What I'm trying to do is create a query that gives me this:
Sync Data New Existing & Changed Existing & Not Changed
---------------------------------------------------------------------------
11/28/2017 9:30am 2 1 2
11/28/2017 10:30am 1 0 0
This is what I'm trying:
SELECT
sh.SyncHistoryId
, sh.SyncDateTime
, count(sd1.SyncDetailId) AS Created
, count(sd2.SyncDetailId) AS ExistingChanged
, count(sd3.SyncDetailId) AS ExistingNotChanged
FROM
SyncHistory sh
LEFT JOIN SyncDetails sd1 ON sh.SyncHistoryId = sd1.SyncHistoryId AND sd1.ItemCreated = 1 AND sd1.ItemChanged = 0
LEFT JOIN SyncDetails sd2 ON sh.SyncHistoryId = sd2.SyncHistoryId AND sd2.ItemCreated = 0 AND sd2.ItemChanged = 1
LEFT JOIN SyncDetails sd3 ON sh.SyncHistoryId = sd3.SyncHistoryId AND sd3.ItemCreated = 0 AND sd3.ItemChanged = 0
WHERE
sh.SyncType = 1
GROUP BY
sh.SyncHistoryId
, sh.SyncDateTime
ORDER BY
sh.SyncDateTime DESC
But, none of the resulting counts are accurate. I'm doing something wrong, but not sure what.
SELECT h.SyncDateTime,
SUM(case when d.ItemCreated = 1 then 1 else 0 end) as New,
SUM(case when d.ItemChanged = 1 then 1 else 0 end) as [Existing & Changed],
SUM(case when d.ItemCreated = 0 and d.ItemChanged = 0 then 1 else 0 end) as [Existing & Not Changed]
FROM SyncHistory h
INNER JOIN SyncDetails d ON h.SyncHistoryId = d.SyncHistoryId
GROUP BY h.SyncDateTime
You only need to JOIN to the details table once. You can get your counts from that through aggregation:
SELECT
CONVERT(VARCHAR(16), SH.SyncDateTime, 120) AS SyncTime,
SUM(CASE WHEN SD.ItemCreated = 1 AND SD.ItemChanged = 0 THEN 1 ELSE 0 END) AS New,
SUM(CASE WHEN SD.ItemCreated = 0 AND SD.ItemChanged = 1 THEN 1 ELSE 0 END) AS ExistingAndChanged,
SUM(CASE WHEN SD.ItemCreated = 0 AND SD.ItemChanged = 0 THEN 1 ELSE 0 END) AS ExistingAndNotChanged
FROM
SyncHistory SH
LEFT OUTER JOIN SyncDetails SD ON SD.SyncHistoryID = SH.SyncHistoryID
GROUP BY
CONVERT(VARCHAR(16), SH.SyncDateTime, 120)
You weren't clear on how the grouping/datetime should be determined. What I have is by the minute. If it's supposed to be by the hour on the 1/2 hour mark or something else then you'll need to change that part of the query in the GROUP BY and the first column of the SELECT.
Another solution. I hope it will work - no CASE, no subquery:
SELECT
sh.SyncHistoryId
,sh.SyncDateTime
,COUNT( NULLIF( sd.ItemCreated, 0 ) ) AS Created
,COUNT( NULLIF( sd.ItemCreated, 1 ) + NULLIF( sd1.ItemChanged, 0 ) ) AS ExistingChanged
,COUNT( NULLIF( sd.ItemCreated, 1 ) + NULLIF( sd1.ItemChanged, 1 ) ) AS ExistingNotChanged
FROM
SyncHistory sh JOIN SyncDetails sd ON sh.SyncHistoryId = sd.SyncHistoryId
WHERE
sh.SyncType = 1
GROUP BY
sh.SyncHistoryId
,sh.SyncDateTime
ORDER BY
sh.SyncDateTime DESC
I hope subquery is not forbidden:
SELECT
sh.SyncHistoryId
,sh.SyncDateTime
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 1 AND sd1.ItemChanged = 0) AS Created
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 0 AND sd1.ItemChanged = 1) AS ExistingChanged
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 0 AND sd1.ItemChanged = 0) AS ExistingNotChanged
FROM
SyncHistory sh
WHERE
sh.SyncType = 1
ORDER BY
sh.SyncDateTime DESC

Query for Joining three tables with row value as column header

I have three tables as shown below.
TABLE1 : tb_subject
subject_id subject_name
1 English
2 Maths
3 Science
Table2 : tb_student
subject_id student_id
1 AA
1 BB
2 CC
3 DD
3 EE
Table3 : tb_student_score
student_id score conducted_month_number
AA 20 2
BB 30 3
CC 50 4
AA 80 4
DD 50 6
BB 10 2
EE 40 3
Result should be
conducted_month_number SUM(subject_id1) SUM(subject_id2) SUM(subject_id3)
1 0 0 0
2 30 0 0
3 30 0 40
4 80 50 0
5 0 0 0
6 0 0 60
7 0 0 0
8 0 0 0
9 0 0 0
10 0 0 0
11 0 0 0
12 0 0 0
How to write a select query for this? Can add all month number that is not stored in table as like in the resulted output?
You should be able to use case when to sum for each subject individually:
SELECT conducted_month_number,
SUM(CASE b.subject_id WHEN 1 THEN a.score ELSE 0 END) AS English,
SUM(CASE b.subject_id WHEN 2 THEN a.score ELSE 0 END) AS Maths,
SUM(CASE b.subject_id WHEN 3 THEN a.score ELSE 0 END) AS Science
FROM tb_student_score AS a
JOIN tb_student AS b ON b.student_id = a.student_id
GROUP BY conducted_month_number
ORDER BY conducted_month_number;
However, this alone will not ensure you have results for values of conducted_month_number that don't exist - if this is an issue, you could simply create a dummy student with a score of 0 for each month.
Edit: I noticed some comments posted around the same time I submitted my answer - if you want the number of summation columns to be variable based on the values of rows in the tb_subject table, you will not find the relational model of SQL to be well suited for that task. However, you can easily go back and update your query to include any new subjects you may add later on.
Have added dummy values of 1 to 12 months using union statement and later on did group by on them to calculate total scores.
Try this:-
Select conducted_month_number ,
sum(case when subject_id=1 then score else 0 end) as sum_subject_id1,
sum(case when subject_id=2 then score else 0 end) as sum_subject_id2,
sum(case when subject_id=3 then score else 0 end) as sum_subject_id3
from
(
Select a.conducted_month_number ,subject_id,score
from
tb_student_score a
inner join
tb_student b
on a.student_id=b.student_id
union
select 1,' ',0 from tb_student_score
union
select 2,' ',0 from tb_student_score
union
select 3,' ',0 from tb_student_score
union
select 4,' ',0 from tb_student_score
union
select 5,' ',0 from tb_student_score
union
select 6,' ',0 from tb_student_score
union
select 7,' ',0 from tb_student_score
union
select 8,' ',0 from tb_student_score
union
select 9,' ',0 from tb_student_score
union
select 10,' ',0 from tb_student_score
union
select 11,' ',0 from tb_student_score
union
select 12,' ',0 from tb_student_score
)a
group by conducted_month_number
My Output
conducted_month_number sum_subject_id1 sum_subject_id2 sum_subject_id3
1 0 0 0
2 30 0 0
3 30 0 40
4 80 50 0
5 0 0 0
6 0 0 50
7 0 0 0
8 0 0 0
9 0 0 0
10 0 0 0
11 0 0 0
12 0 0 0