Counting values from a column and grouping and sorting by a second value - sql

Let's say I have this table:
NAME YEAR SCORE
_____________________
User1 2010 1
User2 2011 3
User3 2012 2
User4 2013 1
User5 2012 1
User6 2011 3
User7 2010 4
User8 2011 1
I would like to create a query whose output looks like this from this data:
YEAR 1 2 3 4
________________________
2010 1 0 0 1
2011 1 0 2 0
2012 1 1 0 0
2013 1 0 0 0
Where the values in the numbered columns is the count of how many times that score appears in the given year. This seems as if it should be easy but I am having trouble figuring out how to wrap my head around writing this query in a way that is static. Ideas?

select YEAR,
count(CASE WHEN SCORE = 1 THEN 1 END) AS `1`,
count(CASE WHEN SCORE = 2 THEN 1 END) AS `2`,
count(CASE WHEN SCORE = 3 THEN 1 END) AS `3`,
count(CASE WHEN SCORE = 4 THEN 1 END) AS `4`
from TABLE
group by year

For a set of Four values
SELECT YEAR, SUM(CASE WHEN SCORE = 1 THEN 1 ELSE 0 END) AS `1`,
SUM(CASE WHEN SCORE = 2 THEN 1 ELSE 0 END) AS `2`,
SUM(CASE WHEN SCORE = 3 THEN 1 ELSE 0 END) AS `3`,
SUM(CASE WHEN SCORE = 4 THEN 1 ELSE 0 END) AS `4`
FROM TABLE
GROUP BY YEAR

Related

Create a score card report based on match results in SQL

Here's my sample input of match results from a tournament and the result column indicates whether team 1 or team 2 won the game (0 stands for a draw).
score table -
-----------------
t1 t2 result
-----------------
us aus 1
aus sa 2
sa us 0
us nz 1
Desired output -
---------------------------------
team played won lost draw
---------------------------------
aus 2 0 2 0
us 3 2 0 1
nz 1 0 1 0
sa 2 1 0 1
Here's my solution that I came up with, but Is it possible to solve it without using a UNION operator?
select
t1 as team,
count(1) as played,
sum(case when result=1 then 1 else 0 end) as won,
sum(case when result=2 then 1 else 0 end) as lost,
sum(case when result=0 then 1 else 0 end) as draw
from
(select
t1,
t2,
result
from score
union
select
t2,
t1,
case when result=1 then 2
when result=2 then 1
else 0 end as result
from score
) t
group by t.t1
You could UNPIVOT your data via a CROSS APPLY and then perform the aggregation on the results
Example
Select Team
,played = count(1)
,won = sum(case when Val=1 then 1 else 0 end)
,lost = sum(case when Val=2 then 1 else 0 end)
,draw = sum(case when Val=0 then 1 else 0 end)
From score A
Cross Apply ( values (T1,Result )
,(T2,case when result=1 then 2 when result=2 then 1 else 0 end)
) B(Team,Val)
Group By Team
Results
team played won lost draw
aus 2 0 2 0
nz 1 0 1 0
sa 2 1 0 1
us 3 2 0 1

How do I query a table in SQL to produce a result where column names are stacked vertically based on a condition?

Suppose I have a SQL table titled Users with the following example data:
Description Days
--------------------------
Healthy 10
High-blood pressure 20
Cholesterol 23
Diabetes 31
High-blood pressure 8
Healthy 12
Diabetes 18
Cholesterol 25
High-blood pressure 20
Healthy 6
How would I produce a result that looks like the following where the columns: Less_than_20_days, 20_days and Greater_than_20_days contains counts from the table above
Description Less_than_20_days 20_days Greater_than_20_days
-----------------------------------------------------------------------------------
Healthy 3 0 0
High-blood pressure 1 2 0
Cholesterol 0 0 2
Diabetes 1 0 1
I'm trying to get this to work in SQL Server and have tried using the union operator, temp tables and ctes but I can't seem to get the desired result.
Any help would be much appreciated!
You can combine case with sum():
select
[Description]
,sum(case when [Days] < 20 then 1 else 0 end) as Less_than_20_days
,sum(case when [Days] = 20 then 1 else 0 end) as d20_days
,sum(case when [Days] > 20 then 1 else 0 end) as Greater_than_20_days
from users
group by [Description]
Use conditional aggregation:
select description,
sum(case when days < 20 then 1 else 0 end) as num_lt_20,
sum(case when days = 20 then 1 else 0 end) as num_eq_20,
sum(case when days > 20 then 1 else 0 end) as num_gt_20
from t
group by description

SQL Server - Show All possible Values and Count Them

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.

Counting the 1's and 2's in a Table

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

How to return one single row from groupped by columns

I have table like this
ID Specified TIN
-----------------
1 0 tin1
2 0 tin1
3 1 tin1
4 0 tin2
5 0 tin3
6 1 tin3
7 1 tin3
I need to count rows groupped by TIN, Specified columns - but result should one row for each TIN:
TIN ZEROSpecified NOTZEROSpecified
tin1 2 1
tin2 0 1
tin3 1 2
Important notice - i have only 2 values for Specified column - 0 and 1
SELECT TIN,
SUM(case when Specified=0 then 1 else 0 end) as ZeroSpecified,
SUM(case when Specified<>0 then 1 else 0 end) as NOTZEROSpecified
FROM table
GROUP BY TIN
Pretty Simple;
SELECT
TIN
,SUM(CASE WHEN Specified = 0 THEN 1 ELSE 0 END) ZEROSpecified
,SUM(CASE WHEN Specified <> 0 THEN 1 ELSE 0 END) NotZEROSpecified
FROM TableName
GROUP BY TIN