Select Count Where Values greater than 0 SQL Server - sql

I'm trying to figure out how to return a select query showing a count of all values in a column that are greater than 0. Then in the next column show a count of all values that = 0.
Example:
ID ColumnA
1 1
2 2
3 1
4 2
5 0
6 0
7 1
Would return a result for the select query of:
NumberOfGreaterThan0 NumberThatEqual0
5 2

You can use conditional aggregates for this via CASE expression:
SELECT COUNT(CASE WHEN ColumnA > 0 THEN 1 END) AS NumberOfGreaterThan0
,COUNT(CASE WHEN ColumnA = 0 THEN 1 END) AS NumberThatEqual0
FROM YourTable
This works because aggregate functions ignore NULL values.

You can use a couple of count functions over case expressions:
SELECT COUNT(CASE WHEN columa > 0 THEN 1 ELSE NULL END) AS NumberOfGreaterThan0,
COUNT(CASE columa WHEN 0 THEN 1 ELSE NULL END) AS NumberThatEqual0
FROM my_table

Related

Adding a dummy identifier to data that varies by position and value

I am working on a project in SQL Server with diagnosis codes and a patient can have up to 4 codes but not necessarily more than 1 and a patient cannot repeat a code more than once. However, codes can occur in any order. My goal is to be able to count how many times a Diagnosis code appears in total, as well as how often it appears in a set position.
My data currently resembles the following:
PtKey
Order #
Order Date
Diagnosis1
Diagnosis2
Diagnosis3
Diagnosis 4
345
1527
7/12/20
J44.9
R26.2
NULL
NULL
367
1679
7/12/20
R26.2
H27.2
G47.34
NULL
325
1700
7/12/20
G47.34
NULL
NULL
NULL
327
1710
7/12/20
I26.2
J44.9
G47.34
NULL
I would think the best approach would be to create a dummy column here that would match up the diagnosis by position. For example, Diagnosis 1 with A, and Diagnosis 2 with B, etc.
My current plan is to rollup the diagnosis using an unpivot:
UNPIVOT ( Diag for ColumnALL IN (Diagnosis1, Diagnosis2, Diagnosis3, Diagnosis4)) as unpvt
However, this still doesn’t provide a way to count the diagnoses by position on a sales order.
I want it to look like this:
Diagnosis
Total Count
Diag1 Count
Diag2 Count
Diag3 Count
Diag4 Count
J44.9
2
1
1
0
0
R26.2
1
1
0
0
0
H27.2
1
0
1
0
0
I26.2
1
1
0
0
0
G47.34
3
1
0
2
0
You can unpivot using apply and aggregate:
select v.diagnosis, count(*) as cnt,
sum(case when pos = 1 then 1 else 0 end) as pos_1,
sum(case when pos = 2 then 1 else 0 end) as pos_2,
sum(case when pos = 3 then 1 else 0 end) as pos_3,
sum(case when pos = 4 then 1 else 0 end) as pos_4
from data d cross apply
(values (diagnosis1, 1),
(diagnosis2, 2),
(diagnosis3, 3),
(diagnosis4, 4)
) v(diagnosis, pos)
where diagnosis is not null;
Another way is to use UNPIVOT to transform the columns into groupable entities:
SELECT Diagnosis, [Total Count] = COUNT(*),
[Diag1 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis1' THEN 1 ELSE 0 END),
[Diag2 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis2' THEN 1 ELSE 0 END),
[Diag3 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis3' THEN 1 ELSE 0 END),
[Diag4 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis4' THEN 1 ELSE 0 END)
FROM
(
SELECT * FROM #x UNPIVOT (Diagnosis FOR DiagGroup IN
([Diagnosis1],[Diagnosis2],[Diagnosis3],[Diagnosis4])) up
) AS x GROUP BY Diagnosis;
Example db<>fiddle
You can also manually unpivot via UNION before doing the conditional aggregation:
SELECT Diagnosis, COUNT(*) As Total Count
, SUM(CASE WHEN Position = 1 THEN 1 ELSE 0 END) As [Diag1 Count]
, SUM(CASE WHEN Position = 2 THEN 1 ELSE 0 END) As [Diag2 Count]
, SUM(CASE WHEN Position = 3 THEN 1 ELSE 0 END) As [Diag3 Count]
, SUM(CASE WHEN Position = 4 THEN 1 ELSE 0 END) As [Diag4 Count]
FROM
(
SELECT PtKey, Diagnosis1 As Diagnosis, 1 As Position
FROM [MyTable]
UNION ALL
SELECT PtKey, Diagnosis2 As Diagnosis, 2 As Position
FROM [MyTable]
WHERE Diagnosis2 IS NOT NULL
UNION ALL
SELECT PtKey, Diagnosis3 As Diagnosis, 3 As Position
FROM [MyTable]
WHERE Diagnosis3 IS NOT NULL
UNION ALL
SELECT PtKey, Diagnosis4 As Diagnosis, 4 As Position
FROM [MyTable]
WHERE Diagnosis4 IS NOT NULL
) d
GROUP BY Diagnosis
Borrowing Aaron's fiddle, to avoid needing to rebuild the schema from scratch, and we get this:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d1f7f525e175f0f066dd1749c49cc46d

Counting values within the same row in SQL Server

My SQL Server problem is as follows: let's say we have clients and we wish to rate them based on 4 categories (Score_1...Score_4) on a scale of 0 to 2. I have a table presented below:
What I want my code to do is count the number of 0, 1, and 2 values each of my clients recieved. The result table I would like to get would like this:
So client_1 got two 0 scores, one 1 score and one 2 score, client_2 got one 0 score, one 1 score and two 2 scores. Any suggestions? Thanks in advance!
You can unpivot, then do conditional aggregation:
select t.id,
sum(case when x.score = 0 then 1 else 0 end) cnt_0,
sum(case when x.score = 1 then 1 else 0 end) cnt_1,
sum(case when x.score = 2 then 1 else 0 end) cnt_2
from mytable t
cross apply (values (score_1), (score_2), (score_3), (score_4)) x(score)
group by t.id

I need to Count the Number of Columns that have value more than 0 in SQL

I want to create a calculated field at the end of the columns where it will count all the Columns having values greater than 0.
Below is a sample Data Set.
Account_number DAY_0 DAY_30 DAY_60 DAY_90 DAY_120
acc_001 99 10 0 0.2 0
You can use case expressions:
select t.*,
( (case when day_0 > 0 then 1 else 0 end) +
(case when day_30 > 0 then 1 else 0 end) +
(case when day_60 > 0 then 1 else 0 end) +
(case when day_90 > 0 then 1 else 0 end) +
(case when day_120 > 0 then 1 else 0 end)
) as num_gt_zero
from t;
That said, you probably constructed this from a group by query. You might be able to put this logic directly into that query. If that is the case, ask a new question, with sample data, desired results, and an appropriate database tag.

Running Counts on Multiple Columns with One SQL Query

I'm looking to run a count SQL query on multiple columns at once. 83 of them. For each, I'd simply like to figure out how many instances there are in which the value = 1.
ex.
select count(*) from [filename.filename]
where [Column001] = 1
select count(*) from [filename.filename]
where [Column002] = 1
All data in each column is marked with wither a 0 or a 1.
Instead of writing 83 small queries, is there a way for me to write it all in one query and have them all display as a table with the results?
This seems to be what you want:
SELECT SUM(CASE WHEN Column_1 = 1 THEN 1 ELSE 0 END) N_1,
SUM(CASE WHEN Column_2 = 1 THEN 1 ELSE 0 END) N_2,
SUM(CASE WHEN Column_3 = 1 THEN 1 ELSE 0 END) N_3,
.....
SUM(CASE WHEN Column_83 = 1 THEN 1 ELSE 0 END) N_83
FROM YourTable;

SQL: Comparing count of 2 fields with specific value

I have 2 tables, one (Jobs) contains the list of the jobs and second contains the details of the records in each job.
Jobs
JobID Count
A 2
B 3
Records
JobID RecordID ToBeProcessed IsProcessed
A A1 1 1
A A2 1 1
B B1 1 1
B B2 1 0
B B3 1 0
How would I be able to create a query that would list all the jobs that have the count of ToBeProcessed which has a value of 1 is equal to the count of isProcessed that has a value of 1? Thanks in advance. Any help is greatly appreciated.
Start with the calculation of the number of items with ToBeProcessed set to 1 or IsProcessed set to one:
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
This gives you all counts, not only ones where ToBeProcessedIsOne is equal to IsProcessedIsOne. To make sure that you get only the records where the two are the same, use either a HAVING clause, or a nested subquery:
-- HAVING clause
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
HAVING SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END)=SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END)
-- Nested subquery with a condition
SELECT * FROM (
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
) WHERE ToBeProcessedIsOne = IsProcessedIsOne
Note: if ToBeProcessed and IsProcessed are of type that does not allow values other than zero or one, you can replace the CASE statement with the name of the column, for example:
SELECT
JobID
, SUM(ToBeProcessed) ToBeProcessedIsOne
, SUM(IsProcessed) IsProcessedIsOne
FROM Records
GROUP BY JobID
HAVING SUM(ToBeProcessed)=SUM(IsProcessedD)
if im not misunderstanding your question it looks like you just need a WHERE clause in your statement to see when they are both equal to 1.
SELECT
r.JobID AS j_id,
r.RecordID as r_id,
r.ToBeProcessed AS tbp,
r.IsProcessed AS ip
FROM Records AS r
WHERE r.ToBeProcessed = 1 AND r.IsProcessed = 1
GROUP BY j_id;
let me know if this is not what you are asking for.
if its a count from a different table then just do a count of the tbp and ip rows grouped by jobID and then the where should still do the trick