Home > Net >  SQL query to get count of distinct values of columns in a same table
SQL query to get count of distinct values of columns in a same table

Time:10-08

I have table with columns like Gender, Status.

The table value is something like this

ID Gender Status
1 Male A01
2 Male
3 Female A02
4 Female
5 Unknown
6 Male
7 Female
8 Unknown

I want to display

Gender Status Count
Male A01 1
Female A02 1
Unknown 0

I tried

SELECT 
    t3.Gender, t3.Status, COUNT(*) AS count 
FROM
    (SELECT DISTINCT
         t1.Gender, t1.Status 
     FROM 
         Consumer AS t1
     CROSS JOIN 
         Consumer AS t2 
     WHERE 
         t1.Status <> t2.Status 
         OR t1.Status <> t2.Status) AS t3 
GROUP BY
    t3.Gender, t3.Status

The final output something I want to display is enter image description here Please help on this. Thanks

CodePudding user response:

Since the desired results have now been updated, the solution is now much different.

Try:

SELECT
  CASE WHEN GROUPING(Status) = 1 THEN 'Total' ELSE Status END AS Status,
  --ISNULL(Status, 'Total') AS Status, -- This would not work is actual Status might be null
  COUNT(CASE WHEN Gender = 'Female' THEN 1 END) AS Female,
  COUNT(CASE WHEN Gender = 'Male' THEN 1 END) AS Male,
  COUNT(CASE WHEN Gender = 'Unknown' THEN 1 END) AS Unknown,
  COUNT(*) AS Count
FROM @Consumer
WHERE Status > ''
GROUP BY Status WITH Rollup
ORDER BY GROUPING(Status), Status

The above uses conditional aggregation to get the partial counts. WITH ROLLUP automatically creates a totals row. The ISNULL() sets a status label for that row (which would otherwise display as null). lastly, the GROUPING() in the ORDER BY places the rollup/total after the detail rows.

See this db<>fiddle.

There are also ways to do this using a pivot table, but the above may be sufficient for your current needs.

CodePudding user response:

You might be overthinking your requirements. Perhaps the following will work:

SELECT Gender, Status, COUNT(*) AS count
FROM Consumer
GROUP BY Gender, Status
ORDER BY Gender, Status

It was not clear what you were expecting in your results for unknown gender. If you need special handling for unknown gender and/or blank status, you can add a WHERE condition to the above for the normal cases and the UNION ALL the results with a second query to handle the special cases.

SELECT Gender, Status, COUNT(*) AS count
FROM Consumer
WHERE Gender <> 'Unknown' AND Status > ''
GROUP BY Gender, Status
  UNION ALL
SELECT 'Unknown' AS Gender, '' AS Status, COUNT(*) AS count
FROM Consumer
WHERE NOT (Gender <> 'Unknown' AND Status > '')
  • Related