Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pivot not returning aggregate (SQL Adventureworks)

I am using the Adventureworks sample database (HumanResources.Employee table is the database).

For simplicity I will take a sample of the table:

HireDate       Gender        SalariedFlag
-----------------------------------------
2014-01-01         M              1
2015-01-30         F              1
2014-01-30         M              1
2014-02-12         F              0
2014-03-11         F              1 and so on

Code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

SELECT
    YEAR(hiredate), F, M 
FROM
    HumanResources.employee
PIVOT
    (sum(SalariedFlag) 
         FOR gender IN ([F], [M])
    ) AS gg
  -- Unable to use sum though since its bit field

Expected output:

Year      F     M
-------------------
2014      1     2    # count(SalariedFlag) 
2015      1     0    # count(SalariedFlag)

But I really get:

No name     F               M
-------------------------------
2014         0              1
2015         1              0
2014         0              1
2014         1              0
2014         1              0 

and so on.

So basically in output its not considering the salariedflag column at all, it is simply returning 1 in F if the person was female and 1 in M if person was male.

What am I doing wrong?

>Solution :

Firstly, counting the value of SalariedFlag isn’t going to achieve anything. COUNT counts the number of rows with a non-NULL value, and all your rows have a non-NULL value. Instead you want to COUNT the number of rows where the value of SalariedFlag is 1.

You might, therefore, be able to SUM the column, however, as it’s a "flag" it’s more likely to be a bit and you can’t SUM a bit. Therefore using COUNT and checking the value is 1 with a CASE would likely be better.

Personally, rather than using the restrictive PIVOT operator, I would suggest you use conditional aggregation. This gives you the following:

SELECT YEAR(HireDate) AS HireYear,
       COUNT(CASE WHEN Gender = 'M' AND SalariedFlag = 1 THEN 1 END) AS M,
       COUNT(CASE WHEN Gender = 'F' AND SalariedFlag = 1 THEN 1 END) AS F
FROM #YourTable
GROUP BY YEAR(HireDate);

db<>fiddle

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading