Reputation: 1
Right now i have multiple distinct queries which gives respective results .. But i wanted to run a single query to get all those outputs in multiple rows..
Ex:
select count(distinct message_id)
from dssam.message_metadata
where object_id > 1177 AND workflow_type='3'; --- This gives o/p - 24
select count(distinct message_id)
from dssam.message_metadata
where object_id > 1177 AND workflow_type='4'; --- This gives o/p - 40
select count(distinct message_id)
from dssam.message_metadata
where object_id > 1177 AND flagged='true';--- This gives o/p - 6
But what i am looking for is .. o/p should be as below:
[workflow_type count
============== ====
3 24
4 40
true 6][1]
Can somebody help me on this ..?
Upvotes: 0
Views: 58
Reputation: 1270873
Put the values in columns:
select count(distinct case when workflow_type = 3 then message_id end) as cnt_wt_3,
count(distinct case when workflow_type = 4 then message_id end) as cnt_wt_4,
count(distinct case when flag = 'true' then message_id end) as cnt_true
from dssam.message_metadata m
where object_id > 1177 and
( workflow_type in (3, 4) or flag = 'true' );
(Note: I assume that workflow_type
is really an integer.)
You want them in separate columns so you can tell which row corresponds to which value. Otherwise, you have no label on the row. In a table called message_metadata
, I am guessing that message_id
is unique.
If this is the case, do not use count(distinct)
. I prefer sum()
for this calculation:
select sum(case when workflow_type = 3 then 1 else 0 end) as cnt_wt_3,
count(case when workflow_type = 4 then message_id else 0 end) as cnt_wt_4,
count(case when flag = 'true' then 1 else 0 end) as cnt_true
from dssam.message_metadata m
where object_id > 1177 and
( workflow_type in (3, 4) or flag = 'true' );
Upvotes: 0
Reputation: 22811
A bit shorter version of single scan + unpivot query.
WITH Aggs AS(
SELECT COUNT(DISTINCT CASE mm.workflow_type WHEN 3 THEN message_id END) AS Workflow3,
COUNT(DISTINCT CASE mm.workflow_type WHEN 4 THEN message_id END) AS Workflow4,
COUNT(DISTINCT CASE mm.flagged WHEN 'true' THEN message_id END) AS FlaggedTrue
FROM dssam.message_metadata mm
WHERE [object_id] = 1177)
SELECT V.KPI, V.DistinctCount
FROM Aggs A
CROSS APPLY (VALUES('3', Workflow3),
('4', Workflow4),
('true', FlaggedTrue)
) V(KPI,DistinctCount);
Upvotes: 0
Reputation: 95949
You can avoid 3 scans of the table with some conditional aggregation:
WITH Aggs AS(
SELECT COUNT(DISTINCT CASE mm.workflow_type WHEN 3 THEN message_id END) AS Workflow3,
COUNT(DISTINCT CASE mm.workflow_type WHEN 4 THEN message_id END) AS Workflow4,
COUNT(DISTINCT CASE mm.flagged WHEN 'true' THEN message_id END) AS FlaggedTrue
FROM dssam.message_metadata mm
WHERE [object_id] = 1177)
SELECT V.KPI,
CASE V.KPI WHEN 'Workflow 3' THEN A.Workflow3
WHEN 'Workflow 4' THEN A.Workflow4
WHEN 'Flagged True' THEN A.FlaggedTrue
END AS DistinctCount
FROM Aggs A
CROSS APPLY (VALUES('Workflow 3'),
('Workflow 4'),
('Flagged True')) V(KPI);
Upvotes: 0
Reputation: 37487
You can use UNION ALL
and a literal for the workflow_type
column.
SELECT '3' workflow_type,
count(DISTINCT message_id) count
FROM dssam.message_metadata
WHERE object_id > 1177
AND workflow_type = '3'
UNION ALL
SELECT '4' workflow_type,
count(DISTINCT message_id) count
FROM dssam.message_metadata
WHERE object_id > 1177
AND workflow_type = '4'
UNION ALL
SELECT 'true' workflow_type,
count(DISTINCT message_id) count
FROM dssam.message_metadata
WHERE object_id > 1177
AND flagged = 'true';
Upvotes: 1