SQL count when equation of two columns are true - sql

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

Related

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?

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;

How to subtract result of 2 queries grouped by a field

I have a table in this form:
id year type amount
1 2015 in 10
2 2015 out 5
3 2016 in 20
4 2016 out 1
...
The followin query will give me the sum of the amount of type = 'in' grouped by year:
SELECT year, sum(amount)
FROM table
WHERE type = in
GROUP BY year
How am I going to get the following result?
year sum(in) sum(out) "in-out"
2015 10 5 5
2016 20 1 19
sum(in) is the sum of the 'amount' where type='in'.
Use a CASE statement to handle the values of type.
SELECT year,
SUM(CASE WHEN type = 'in' THEN amount ELSE 0 END) AS sum_in,
SUM(CASE WHEN type = 'out' THEN amount ELSE 0 END) AS sum_out,
SUM(CASE WHEN type = 'in' THEN amount ELSE -amount END) AS in_out
FROM table
GROUP BY year;

SQL count and group by date and type

I have a quality system table. There are 2 types of quality points NCR and RMA.
RMA is external and NCR is internal. We log transactions to the table either as a NCR or a RMA. I would like to have a query that will count all of the RMA's and all of the NCR's then group them by monthly count. For example:
MONTH RMA NCR
JANUARY 10 54
FEBRUARY 48 22
MARCH 25 55
If the value is zero for the month or the month has not yet come up, I don't want to see it on the report.
the table. this is what I have.
SELECT MONTH(QualityControl.CreateDate) MONTH, COUNT(*) AS 'NCR'
FROM QualityControl
WHERE YEAR(QualityControl.CreateDate)=2015
and
QualityControl.NCR is not null
GROUP BY MONTH(QualityControl.CreateDate)
This only gives me the month number (1=January) and the NCR count for that month.
Then I tried the following:
SELECT
SUM(CASE datepart(month,CreateDate) WHEN 1 THEN 1 ELSE 0 END) AS 'January',
SUM(CASE datepart(month,CreateDate) WHEN 2 THEN 1 ELSE 0 END) AS 'February',
SUM(CASE datepart(month,CreateDate) WHEN 3 THEN 1 ELSE 0 END) AS 'March',
SUM(CASE datepart(month,CreateDate) WHEN 4 THEN 1 ELSE 0 END) AS 'April',
SUM(CASE datepart(month,CreateDate) WHEN 5 THEN 1 ELSE 0 END) AS 'May',
SUM(CASE datepart(month,CreateDate) WHEN 6 THEN 1 ELSE 0 END) AS 'June',
SUM(CASE datepart(month,CreateDate) WHEN 7 THEN 1 ELSE 0 END) AS 'July',
SUM(CASE datepart(month,CreateDate) WHEN 8 THEN 1 ELSE 0 END) AS 'August',
SUM(CASE datepart(month,CreateDate) WHEN 9 THEN 1 ELSE 0 END) AS 'September',
SUM(CASE datepart(month,CreateDate) WHEN 10 THEN 1 ELSE 0 END) AS 'October',
SUM(CASE datepart(month,CreateDate) WHEN 11 THEN 1 ELSE 0 END) AS 'November',
SUM(CASE datepart(month,CreateDate) WHEN 12 THEN 1 ELSE 0 END) AS 'December',
SUM(CASE datepart(year,CreateDate) WHEN 2015 THEN 1 ELSE 0 END) AS 'TOTAL'
FROM
QualityControl
WHERE
CreateDate BETWEEN '2015/01/01' AND '2015/12/30'
And it gave me the count for NCR and RMA
Let's go with your first attempt, which is one row per value. You want to count the valid "NCR" and "RMA" values. You can use a COUNT() like this:
SELECT MONTH(qc.CreateDate) as MON, COUNT(NCR) as NCR, COUNT(RMA) as RMA
FROM QualityControl qc
WHERE CreateDate >= '2015-01-01' AND CreateDate < '2016-01-01'
GROUP BY MONTH(qc.CreateDate)
ORDER BY MON;
With a column (or other expression), COUNT() counts the number of non-NULL values. That seems to be exactly what you want.
If you wanted the SUM() of the values, then you would use SUM() instead of COUNT().
Note about the dates:
The version using comparisons is better than the one using YEAR(), because it can make use of indexes.
I changed the BETWEEN to >= and <. This version works correctly, if your date/time column has a time component. It also works for dates.
December has 31 days.
in sql server you can do all of these :
SELECT
CASE datepart(month,getdate()) WHEN 1 THEN 1 ELSE 0 END AS January,
CASE datepart(month,getdate()) WHEN 2 THEN 1 ELSE 0 END AS "February",
CASE datepart(month,getdate()) WHEN 3 THEN 1 ELSE 0 END AS [March]
the best method would be
SELECT datename(month, getdate())

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;

sql query to subtract columns

I have a table which looks like this :
Item Month Year Sales
Name1 1 2013 333
Name2 2 2013 454
Name3 1 2013 434
I need to write a stored procedure which looks like this :
Item Sales_On_Month(1) Sales_On_Month(2) Sales_On_Month(2)-Sales_On_Month(1) Sales_On_Month(3) Sales_On_Month(3)-Sales_On_Month(2)
Name1 333 334 1 335 1
Name2 454 454 0 654 200
I tried the following query :
I see a lot of nulls in the middle.If you could let me know the modifications to the query or another approach
it would be great :
select (case when [MONTH] = 1 then Sales END) AS Sales_On_Month(1),
(case when [MONTH] = 2 then Sales END) AS Sales_On_Month(2),
(case when [MONTH] = 2 then Sales END) - (case when [MONTH] = 1 then Sales END) AS Sales_On_Month(2)-Sales_On_Month(1) ...............
from ABC;
Use an aggregate, SUM(), MAX(), whatever, andGROUP BY`:
SELECT Item
,SUM(CASE WHEN [MONTH] = 1 THEN Sales END) AS Sales_1
,SUM(CASE WHEN [MONTH] = 2 THEN Sales END) AS Sales_2
,SUM(CASE WHEN [MONTH] = 2 THEN Sales END) - SUM(CASE WHEN [MONTH] = 1 THEN Sales END) AS Sales_On_Month(2)-Sales_On_Month(1)
FROM ABC
GROUP BY Item