Using SQL, how to calculate count of rows for each ID(column) for each month by using only datetime and put them in monthly columns? - sql

I am relatively new to SQL. I have a dataset as follows:
'ID' 'date'
1 2016-01-01 01:01:06
2 2016-01-02 02:02:07
1 2016-01-03 03:03:08
3 2016-04-04 04:04:09
2 2016-04-05 05:05:00
I want to obtain smth like this:
'ID' 'Count: Jan' 'Count: Feb' 'Count: March' 'Count: April'
1 2 0 0 0
2 1 0 1 0
3 0 0 0 1
I really have no idea how handle this. I could put the data creating a column "month" and another column "count" but I want to be able to have a table like this.
Thanks in advance

You ca use conditional aggregation:
select id,
sum(case when month(date) = 1 then 1 else 0 end) as cnt_jan,
sum(case when month(date) = 2 then 1 else 0 end) as cnt_feb,
. . .
sum(case when month(date) = 12 then 1 else 0 end) as cnt_dec
from t
group by id;

Related

SQL count when equation of two columns are true

I have a sheet with rows (id and year). See below:
id
year
101
2002
101
2006
101
2010
101
2014
101
2018
102
2002
102
2006
102
2010
102
2014
103
2010
I simply want to regroup and reformat my table to look like this:
id
2002
2006
2010
2014
2018
101
1
1
1
1
1
102
1
1
1
1
0
103
0
0
1
0
0
In other words, whenever there is an id with a specific year it will show as a "1" in a field corresponding to that year. Note, that in the sheet there are no other years than the ones above.
I have managed to get the sheet reformatted by
select
id,
null as '2002', null as '2006', null as '2010',
null as '2014', null as '2018'
from
year_sheet
order by
id
But how to count and fill in the values for each year I don't find any solution.
Can someone help?
Thanks
You can use conditional aggregation:
SELECT id
, COUNT(CASE WHEN year = 2002 THEN 1 END) AS "2002"
, COUNT(CASE WHEN year = 2006 THEN 1 END) AS "2006"
, COUNT(CASE WHEN year = 2010 THEN 1 END) AS "2010"
, COUNT(CASE WHEN year = 2014 THEN 1 END) AS "2014"
, COUNT(CASE WHEN year = 2018 THEN 1 END) AS "2018"
FROM t
GROUP BY id
ORDER BY id
SQL Fiddle
try using case statement (Conditional statements)
select id,
case when year=2002 then 1 else 0 end as "2002",
case when year=2006 then 1 else 0 end as "2006",
case when year=2010 then 1 else 0 end as "2010",
case when year=2014 then 1 else 0 end as "2014",
case when year=2018 then 1 else 0 end as "2018"
from table
order by id
assuming that you would like to make the flags as 1 and 0 if the year appears for the id (for every id year appears only once).
In case if you want to count them (for eery id year appears more than once) then try using sum(case when....) as follows
select id,
sum(case when year=2002 then 1 else 0 end)as "2002",
sum(case when year=2006 then 1 else 0 end)as "2006",
sum(case when year=2010 then 1 else 0 end)as "2010",
sum(case when year=2014 then 1 else 0 end)as "2014",
sum(case when year=2018 then 1 else 0 end)as "2018"
from table
group by id
order by id

SQL Conditional Counting

I am working with a dataset that contains information about train delays. The dataset contains an arrival delay column and departing delay column. Each delay column is measured in minutes. I need to calculate the number of total delays for each day of the week to determine which day has the most train delays. If the delay is equal to or more than 1 minute, it needs to be counted as a delay. How can I complete this in SQL? I have tried the following code.
select dayofweek
count(case when arrivaldelay>=1 then 1 end)+
count(case when departuredelay>=1 then 1 end)
group by dayofweek;
dayofweek arrivaldelay departuredelay
2 12 5
4 7 10
4 6 -3
6 5 4
dayofweek delays
2 1
4 1
6 1
Assuming dayofweek is a stored column and not a function, then you can use either count or sum
select
dayofweek
, count(case when arrivaldelay >= 1 then 1 end)
+ count(case when departuredelay >= 1 then 1 end)
as delays
from mytable as t
group by dayofweek;
select
dayofweek
, sum(case when arrivaldelay >= 1 then 1 else 0 end)
+ sum(case when departuredelay >= 1 then 1 else 0 end)
as delays
from mytable as t
group by dayofweek;
both give the following result from the sample data in the question
+-----------+--------+
| dayofweek | delays |
+-----------+--------+
| 2 | 2 |
| 4 | 3 |
| 6 | 2 |
+-----------+--------+
IF dayofweek is NOT a stored column then you can extract the day of week from a date or timestamp, BUT there are differences in how this is achieved in different databases
demonstrated #db<>fiddle here
You can use sum() like this:
select dayofweek
( sum(case when arrivaldelay >= 1 then 1 else 0 end)+
sum(case when departuredelay >= 1 then 1 else 0 end)
)
from t
group by dayofweek;

Group by datepart and find total count of individual values of each record

This is table structure;
ID Score Valid CreatedDate
1 A 1 2018-02-19 23:33:10.297
2 C 0 2018-02-19 23:32:40.700
3 B 1 2018-02-19 23:32:30.247
4 A 1 2018-02-19 23:31:37.153
5 B 0 2018-02-19 23:25:08.667
...
I need to find total number of each score and valid in each month
I mean final result should be like
Month A B C D E Valid(1) NotValid(0)
January 123 343 1021 98 12 1287 480
February 516 421 321 441 421 987 672
...
This is what I tried;
SELECT DATEPART(year, CreatedDate) as Ay,
(select count(*) from TableResults where Score='A') as 'A',
(select count(*) from TableResults where Score='B') as 'B',
...
FROM TableResults
group by DATEPART(MONTH, CreatedDate)
but couldn't figure how to calculate all occurrence of scores on each month.
Use conditional aggregation.
SELECT DATEPART(year, CreatedDate) as YR
, DATEPART(month, CreatedDate) MO
, sum(Case when score = 'A' then 1 else 0 end) as A
, sum(Case when score = 'B' then 1 else 0 end) as B
, sum(Case when score = 'C' then 1 else 0 end) as C
, sum(Case when score = 'D' then 1 else 0 end) as D
, sum(Case when score = 'E' then 1 else 0 end) as E
, sum(case when valid = 1 then 1 else 0 end) as Valid
, sum(case when valid = 0 then 1 else 0 end) as NotValid
FROM TableResults
GROUP BY DATEPART(MONTH, CreatedDate), DATEPART(year, CreatedDate)
I'm not a big fan of queries in the select; I find they tend to cause performance problems in the long run. Since we're aggregating here I just applied the conditional logic to all the columns.

Select Count usage divided by month

I do have a table license_Usage where which works like a log of the usage of licenses in a day
ID User license date
1 1 A 22/1/2015
2 1 A 23/1/2015
3 1 B 23/1/2015
4 1 A 24/1/2015
5 2 A 22/2/2015
6 2 A 23/2/2015
7 1 B 23/2/2015
Where I want to Count how many licenses a user used in a month, the result should look like:
User Jan Feb
1 2 1 ...
2 0 2
How can I manage to do that???
You need a PIVOT or cross tab query. e.g.
SELECT [User],
COUNT(CASE WHEN Month = 1 THEN 1 END) AS Jan,
COUNT(CASE WHEN Month = 2 THEN 1 END) AS Feb,
COUNT(CASE WHEN Month = 3 THEN 1 END) AS Mar
/*TODO - Fill in other 9 months using above pattern*/
FROM [license]
CROSS APPLY (SELECT MONTH([date])) AS CA(Month)
WHERE [date] >= '20150101'
AND [date] < '20160101'
AND [license] = 'A'
GROUP BY [User]
SQL Fiddle

How to count sql from one column, and display it in two column

I have a table like this:
idrecord | date
----------------------------------------------
INC-20140308102029 | 2014-03-08 00:00:00.000
INC-20140308102840 | 2014-03-06 00:00:00.000
INC-20140310164404 | 2014-03-10 00:00:00.000
INC-20140311075714 | 2014-03-09 00:00:00.000
NRM-20140310130512 | 2014-04-02 00:00:00.000
NRM-20140311134720 | 2014-03-11 00:00:00.000
USF-20140317212232 | 2014-03-17 00:00:00.000
USF-20140321075402 | 2014-03-18 00:00:00.000
USF-20140321083137 | 2014-03-21 00:00:00.000
how to count this table and display result like this:
month | INC | NRM | USF
march | 4 | 1 | 3
April | 0 | 1 | 0
Thank you
You'd use case to count 1 or zero depending on the string matching or not. Use sum to count.
select
extract(month from thedate) as whichmonth,
sum( case when idrecord like 'INC%' then 1 else 0 end) as inc,
sum( case when idrecord like 'NRM%' then 1 else 0 end) as nrm,
sum( case when idrecord like 'USF%' then 1 else 0 end) as usf
from mytable
group by extract(month from thedate);
The function to extract the month from the date may vary from dbms to dbms. Look the appropriate function up in Google, if extract doesn't work for you.
Don't use the name date for a column. Date is a reserved word in SQL.
Try this
SELECT convert(char(3), date, 0) AS Month,
SUM(Case when LEFT(idrecord,3) = 'INC' then 1 else 0 end) as 'INC',
SUM(Case when LEFT(idrecord,3) = 'NRM' then 1 else 0 end) as 'NRM',
SUM(Case when LEFT(idrecord,3) = 'USF' then 1 else 0 end) as 'USF'
FROM Table1
Group By convert(char(3), date, 0)
Fiddle Demo
or:
SELECT datename(mm, date) AS Month,
SUM(Case when LEFT(idrecord,3) = 'INC' then 1 else 0 end) as 'INC',
SUM(Case when LEFT(idrecord,3) = 'NRM' then 1 else 0 end) as 'NRM',
SUM(Case when LEFT(idrecord,3) = 'USF' then 1 else 0 end) as 'USF'
FROM Table1
Group By datename(mm, date)
Fiddle Demo
Output:
month | INC | NRM | USF
march | 4 | 1 | 3
April | 0 | 1 | 0
try this one
select month (date) as month,
count( case when idrecord like 'INC%' then 1 else 0 end) as inc,
count( case when idrecord like 'NRM%' then 1 else 0 end) as nrm,
count( case when idrecord like 'USF%' then 1 else 0 end) as usf
from table
group by month;