5

Usually I feel pretty confident with SQL queries, however this one has me scratching my head. I feel like this -should- be a quick fix, but I'm just not seeing it.

I'm trying to do a count on multiple values on the same table, in one query.

Don't mind the "0000000000000000" it's just representing an empty byte array.

Is there an easy way to combine these queries?

SELECT COUNT(ssn)
FROM patients
WHERE ssn="0000000000000000";

SELECT COUNT(firstname)
FROM patients
WHERE firstname="0000000000000000"

SELECT COUNT(lastname)
FROM patients
WHERE lastname="0000000000000000"

etc...

4 Answers 4

6
SELECT SUM(CASE WHEN ssn = '0000000000000000' THEN 1 ELSE 0 END) AS ssn_count,
       SUM(CASE WHEN firstname = '0000000000000000' THEN 1 ELSE 0 END) AS first_count,
       SUM(CASE WHEN lastname = '0000000000000000' THEN 1 ELSE 0 END) AS last_count
    FROM patients
    WHERE ssn = '0000000000000000'
        OR firstname = '0000000000000000'
        OR lastname = '0000000000000000'
Sign up to request clarification or add additional context in comments.

5 Comments

That's pretty darned cool. How do you think it compares in performance to the "union" solutions below?
@Marvo: My standard answer is try both and compare. I'd assume this would be better as it's 1 select vs. 3.
I guess it depends on how it gets executed; e.g. it might be one full table scan, rather than three index range scans, which could be very different, depending on the table contents.
Thanks, @Joe. I wonder if you'd be guaranteed a table scan with this solution, or if it could make effective use of indexes. So yeah, performance might be situation dependent. Still, very cool.
@Marvo: A WHERE clause might help avoid the table scan. I'll add one to the answer.
2

You can do something like this -

SELECT COUNT(ssn) AS patient_count, 'ssn' AS count_type
FROM patients
WHERE ssn="0000000000000000";
UNION
SELECT COUNT(firstname) AS patient_count, 'firstname' AS count_type
FROM patients
WHERE firstname="0000000000000000"
UNION
SELECT COUNT(lastname) AS patient_count, 'lastname' AS count_type
FROM patients
WHERE lastname="0000000000000000"

2 Comments

Is there a way I can then pivot the table? I mean it would be nicer to have my tiles as headers, not values.
You could put UNION ALL instead of UNION, just to save the SQL server a bit of redundant work.
1

Try with UNION

SELECT COUNT(ssn)
FROM patients
WHERE ssn="0000000000000000";
UNION
SELECT COUNT(firstname)
FROM patients
WHERE firstname="0000000000000000"
UNION    
SELECT COUNT(lastname)
FROM patients
WHERE lastname="0000000000000000"

3 Comments

You'd want to use UNION ALL here. If two (or even all three) counts happen to be the same, UNION would eliminate them as duplicates.
Not sure if I like this one, as you can't distinguish which counts are which.
you could put another column with the description to solve this
1

I guess this would work?

SELECT *
FROM
(SELECT COUNT(ssn) AS ssn_count
 FROM patients
 WHERE ssn="0000000000000000") AS ssn
CROSS JOIN
(SELECT COUNT(firstname) AS firstname_count
 FROM patients
 WHERE firstname="0000000000000000") AS firstname
CROSS JOIN
(SELECT COUNT(lastname) AS lastname_count
 FROM patients
 WHERE lastname="0000000000000000") AS lastname

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.