Trying to get a basic understanding of T-SQL here in SQL Server 2008. Suppose I have a table named "Issues" with columns such as:
Priority User
1 Foo
1 Foo
2 Foo
5 Foo
4 Bar
5 Bar
1 Bar
1 Fuz
and I wish to display a count of the Priority for each User, along with a breakdown of each Priority, such that the resulting table might be named "Breakdown" might look like
User Total 1 2 3 4 5
Foo 4 2 1 0 0 1
Bar 3 1 0 0 1 1
Fuz 1 1 0 0 0 0
I was thinking I might declare variables and write my query something like
DECLARE #P1 INT
DECLARE #P2 INT
DECLARE #P3 INT
DECLARE #P4 INT
DECLARE #P5 INT
SELECT COUNT(id) AS Total,UserName,
CASE Priority
WHEN 1 Then #P1 = #P1 + 1
WHEN 2 Then #P2 = #P2 + 1
WHEN 3 Then #P3 = #P3 + 1
WHEN 4 Then #P4 = #P4 + 1
WHEN 5 Then #P5 = #P5 + 1
END,
FROM Breakdown
GROUP BY UserName
but I'm pretty sure I'm on the wrong track. Does anyone have any suggestions?
Thanks, and sorry for the noobish question; but I'm not sure exactly what to google for here...
-R.
Use:
SELECT i.user,
COUNT(i.priority) AS total,
SUM(CASE WHEN i.priority = 1 THEN 1 ELSE 0 END) AS 1,
SUM(CASE WHEN i.priority = 2 THEN 1 ELSE 0 END) AS 2,
SUM(CASE WHEN i.priority = 3 THEN 1 ELSE 0 END) AS 3,
SUM(CASE WHEN i.priority = 4 THEN 1 ELSE 0 END) AS 4,
SUM(CASE WHEN i.priority = 5 THEN 1 ELSE 0 END) AS 5
FROM ISSUES i
GROUP BY i.user
It's a pivot query, converting row data into columnar data.
Not a noob/beginner issue to deal with. SQL Server 2005+ added the (now ANSI) PIVOT/UNPIVOT syntax, but this is portable to most databases (because few currently support PIVOT/UNPIVOT).
You need to SELECT one column for each column you want in your result set. In your SQL, you're only selecting three columns. Try:
SELECT UserName,
Count(*) AS Total,
SUM(CASE Priority WHEN 1 THEN 1 ELSE 0 END) AS P1_Total,
SUM(CASE Priority WHEN 2 THEN 1 ELSE 0 END) AS P2_Total,
SUM(CASE Priority WHEN 3 THEN 1 ELSE 0 END) AS P3_Total,
SUM(CASE Priority WHEN 4 THEN 1 ELSE 0 END) AS P4_Total,
SUM(CASE Priority WHEN 5 THEN 1 ELSE 0 END) AS P5_Total
FROM Issues
GROUP BY UserName
Related
I have an automated check script for each morning where the user will be informed of the current number of jobs running as long as they don't fall into the category of "expected running jobs".
I would expected StatusID to be GREEN for IMPORT and AMBER for BATCH due to the current counts being 4 and 3 respectivley
My current code is
DECLARE #Datecreated DATETIME = GetDate())
DECLARE #JobInfo AS TABLE
(
JobType INT,
JobID NVARCHAR(30),
StatusID NVARCHAR(30),
Message NVARCHAR(500),
DateCreated DATETIME,
ITEMS INT
)
INSERT INTO #JobInfo (JobType,JobID,StatusID,Message, DateCreated,ITEMS)
SELECT
0 as Jobtype,
'BATCH' AS JobID,
CASE WHEN Count(CASE JobTypeID WHEN 1 THEN 0 WHEN 30 THEN 0 WHEN 234 THEN 0 ELSE 1 end) >0 THEN N'AMBER' ELSE N'GREEN' END,
'Jobs running longer than 1 hour (ITEMS)',
CAST( #DateCreated AS NVARCHAR(30)),
COUNT(CASE JobTypeID WHEN 1 THEN 0 WHEN 30 THEN 0 WHEN 234 THEN 0 ELSE 1 end)
FROM BATCH.dbo.JOB (NOLOCK) WHERE StatusID = 3
AND JobTypeID NOT IN (1,30,4005)
INSERT INTO #JobInfo (JobType,JobID,StatusID,Message, DateCreated,ITEMS)
SELECT
0 as Jobtype,
'IMPORT' AS JobID,
CASE WHEN Count(CASE JobTypeID WHEN 191 THEN 0 WHEN 124 THEN 0 WHEN 4005 THEN 0 ELSE 1 end) >0 THEN N'AMBER' ELSE N'GREEN' END,
'Jobs running longer than 1 hour (ITEMS)',
CAST( #DateCreated AS NVARCHAR(30)),
COUNT(CASE JobTypeID WHEN 191 THEN 0 WHEN 124 THEN 0 WHEN 4005 THEN 0 ELSE 1 end)
FROM IMPORT.dbo.JOB (NOLOCK) WHERE StatusID = 3
AND JobTypeID NOT IN (191,124,4005)
SELECT * FROM #JobInfo
However currently the StatusID is AMBER for both and the ITEMS are 2 and 4 respectively
SELECT * FROM BATCH.dbo.JOB (NOLOCK) WHERE StatusID = 3 --shows 4 rows, 30,1,1072,234
SELECT * FROM IMPORT.dbo.JOB (NOLOCK) WHERE StatusID = 3 --shows 3 rows, 4005,124,191
Could someone please help explain why this is the case?
How to total count?
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) as "New",
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Accepted"
from SHP
RESULT:
NEW Accepted
1 5
But I need a total count
result: 6
I'd do something like this;
SELECT
COUNT(CASE WHEN id = 1 THEN 1 END) as New,
COUNT(CASE WHEN id = 2 THEN 5 END) as Accepted,
COUNT(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM SHP
This is exactly what the CASE statement should be used for, the logic is very simple. This will avoid having to perform multiple calculations on the same fields.
As a note, the value in your THEN statement isn't used in this instance at all, it's just doing a COUNT of the number rather than performing a SUM. I've also removed the ELSE NULL because this is what the CASE will do by default anyway.
If your intention was to SUM the values then do this;
SELECT
SUM(CASE WHEN id = 1 THEN 1 END) as New,
SUM(CASE WHEN id = 2 THEN 5 END) as Accepted,
SUM(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM SHP
Example
Assuming you have only two values in your database, 1 and 2, we can create test data like this;
CREATE TABLE #SHP (id int)
INSERT INTO #SHP (id)
VALUES (1),(2)
And use this query;
SELECT
SUM(CASE WHEN id = 1 then 1 END) as New,
SUM(CASE WHEN id = 2 then 5 END) as Accepted,
SUM(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM #SHP
Gives this result;
New Accepted Total
1 5 6
Try this:
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) +
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Total"
from SHP
You could wrap your query into a subquery and do something like this:
SELECT SUM(New) as New, Sum(Accepted) as Accepted, Sum(New + Accepted) as Total FROM
(SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) as "New",
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Accepted"
from SHP) as SubQuery
That's if you don't want to duplicate doing the counts and just adding the two together.
try this
with s1 as(
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE 0 END) as "New"
from SHP
),s2 as
(
SELECT
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE 0 END) as "Accepted"
from SHP
)
select sum("New"+ "Accepted") from s1,s2
I have the following table:
IdSce Year NoIte Value
1 0 1 1
1 0 2 5
1 0 3 1
1 1 1 2
1 1 2 3
1 1 3 2
2 0 1 4
2 0 2 4
2 0 3 1
2 1 1 2
2 1 2 4
2 1 3 3
I want to group by IdSce and Year, and show each possible value and count how many time each value appears like this:
IdSce Year Value1 Value2 Value3 Value4 Value5
1 0 2 0 0 0 1
1 1 0 2 1 0 0
2 0 1 0 0 2 0
2 1 0 1 1 1 0
Thanks !
EDIT
shawnt00 is really close to what I want, but I'm looking to do it as dynamic as possible, meaning if I have 10 different values for the column value, I will be missing information in my table. Therefore, if I have 10 different values, I want 10 new columns (value1, value2, ... , value10)
This is what I've tried so far:
SELECT IdSce
,Year
,SUM(CASE WHEN Value >= 0 and Value < 1 THEN 1 else 0 end) Zero
,SUM(CASE WHEN Value >= 1 and Value < 2 THEN 1 else 0 end) One
,SUM(CASE WHEN Value >= 2 and Value < 3 THEN 1 else 0 end) Two
,SUM(CASE WHEN Value >= 3 and Value < 4 THEN 1 else 0 end) Three
,SUM(CASE WHEN Value >= 4 and Value < 5 THEN 1 else 0 end) Four
,SUM(CASE WHEN Value >= 5 THEN 1 else 0 end) FiveMore
,SUM(CASE WHEN Value >= 0 THEN 1 else 0 end) Total
FROM Table
GROUP BY IdSce
,Year
Thanks for the help again!
Ok, I'll do it!
select IdSce, "Year"
count(case when Value = 1 then 1 end) as "1",
count(case when Value = 2 then 1 end) as "2",
count(case when Value = 3 then 1 end) as "3",
count(case when Value = 4 then 1 end) as "4",
count(case when Value = 5 then 1 end) as "5"
from T
group by IdSce, "Year"
I think you'll often find this filed under "conditional aggregation". SQL Server has a proprietary syntax that uses pivot if you want to look into that also.
I have this table
SECTION
Which consist of field called
Semester
2
1
1
1
2
1
1
2
2
2
1
2
I need sql to count how many 1's and how many 2's are there
And out put like this
semester 1 | semester 2
6 | 6
Demo here:After testing
select
sum(Case when semester=1 then 1 else 0 end) as 'Semester1',
sum(Case when semester=2 then 1 else 0 end) as 'Semester2'
from section
Try out this:
Select sum(case when semster =1 then 1 else 0 end) as semster1 ,
sum(case when semster =2 then 1 else 0 end) as semster2
from section;
Assuming there are more values than 1 and 2, and that the values are integers:
SELECT semester, count(*)
FROM section
WHERE semester = 1 OR semester = 2
GROUP BY semester
I have stored procedure and inside i have select statement, insert and update but in my select statement i would like the results to be stored in a variable so i can access it later on in my update statement. How can i store the result first in a variable? Here is my select statement:
SELECT
REV1 = COUNT(CASE WHEN QTR = 1 AND MAIN_SAT =1 AND ACTIVE_FLAG = 1 THEN 1 END),
REV2= COUNT(CASE WHEN QTR = 1 AND MAIN_EKL =1 AND ACTIVE_FLAG = 1 THEN 1 END),
REV3= COUNT(CASE WHEN QTR = 1 AND MAIN_LAM =1 AND ACTIVE_FLAG = 1 THEN 1 END),
REV4= COUNT(CASE WHEN QTR = 1 AND MAIN_JAC =1 AND ACTIVE_FLAG = 1 THEN 1 END)
FROM MyTable
The result of this select statement looks like this:
REV1 REV2 REV3 REV4
12 45 87 54
You can either make a table variable or individual variables (depending on your preference). Example with separate variables:
DECLARE #Rev1 int
DECLARE #Rev2 int
DECLARE #Rev3 int
DECLARE #Rev4 int
SELECT
#Rev1 = COUNT(CASE WHEN QTR = 1 AND MAIN_SAT =1 AND ACTIVE_FLAG = 1 THEN 1 END),
#Rev2= COUNT(CASE WHEN QTR = 1 AND MAIN_EKL =1 AND ACTIVE_FLAG = 1 THEN 1 END),
#Rev3= COUNT(CASE WHEN QTR = 1 AND MAIN_LAM =1 AND ACTIVE_FLAG = 1 THEN 1 END),
#Rev4= COUNT(CASE WHEN QTR = 1 AND MAIN_JAC =1 AND ACTIVE_FLAG = 1 THEN 1 END)
FROM MyTable
Try This
this will reduced the condition and much clearer.
DECLARE #Rev1 int
DECLARE #Rev2 int
DECLARE #Rev3 int
DECLARE #Rev4 int
SELECT
#Rev1 = SUM(CASE WHEN MAIN_SAT =1 THEN 1 ELSE 0 END),
#Rev2= SUM(CASE WHEN MAIN_EKL =1 THEN 1 ELSE 0 END),
#Rev3= SUM(CASE WHEN MAIN_LAM =1 THEN 1 ELSE 0 END),
#Rev4= SUM(CASE WHEN MAIN_JAC =1THEN 1 ELSE 0 END)
FROM MyTable
WHERE QTR = 1
AND ACTIVE_FLAG = 1