Case-when error when creating individual monthly values - sql

If I have the following
ID Disputes_Count Month-Year
123 45 12020
123 85 32020
I want the result to be
ID Jan_2020_Disputes Mar_2020_Disputes
123 45 85
I tried this:
proc sql;
create table disputes_count as
select ID,
sum(case when Month_Year = '12020' then Dispute_Count else 0 end) as January_2020_Disputes,
sum(case when Month_Year = '32020' then Dispute_Count else 0 end) as Mar_2020_Disputes,
from rb.disputes
group by ID;
quit;
However the output I got with this is the following:
ID January_2020_Disputes Mar_2020_Disputes
0 7
Please help!

Related

SQL: SUM OR COUNT with CASE WHEN condition in multiple criteria

Course name
Section number
Course type
MATH 101
1
In person
MATH 101
2
In person
MATH 101
3
Online
MATH 101
4
In person
SOC 101
1
In person
SOC 101
2
In person
SOC 101
3
In person
ENGL 201
1
In person
ENGL 201
2
Online
ENGL 201
3
Online
ENGL 201
4
In person
PHY 101
1
Online
PHY 101
2
Online
From this table, I'd like to count Courses with only an 'In person' course, an 'Online' course, and both course types.
The query I tried is below.
SELECT
SUM(CASE WHEN coursetype = 'Inperson' AND coursetype = 'Online' THEN 1 ELSE 0 END) AS bothtype,
SUM(CASE WHEN coursetype = 'Online' THEN 1 ELSE 0 END) AS Onlineonly,
SUM(CASE WHEN coursetype = 'Inperson' THEN 1 ELSE 0 END) AS Onlineonly
From Course
The result what I expected is
bothtpye
Onlineonly
Inpersononly
2
1
1
but I got
bothtpye
Onlineonly
Inpersononly
0
7
6
Please advise me to get through this.
Thank you.
My solution uses double conditional aggregation.
SELECT SUM (CASE WHEN In_Person > 0 AND Online > 0 THEN 1 ELSE 0 END) as bothtype,
SUM (CASE WHEN In_Person > 0 AND Online = 0 THEN 1 ELSE 0 END) as inpersononly,
SUM (CASE WHEN In_Person = 0 AND Online > 0 THEN 1 ELSE 0 END) as onlineonly
FROM (
SELECT Course_name,
SUM(CASE WHEN Course_type='In Person' THEN 1 ELSE 0 END) as In_Person,
SUM(CASE WHEN Course_type='Online' THEN 1 ELSE 0 END) as Online
FROM Course
GROUP BY Course_name
) tot
DEMO Fiddle
SUGGESTION ( using PL/SQL ! ) :
CREATE PROCEDURE countCourses(OUT bothtype INT,OUT Inpersononly INT,OUT Onlineonly INT)
begin
SELECT COUNT(*) INTO bothtype FROM Course;
select COUNT(*) INTO Inpersononly FROM Course
WHERE courseType = "In person";
select COUNT(*) INTO Onlineonly FROM Course
WHERE courseType = "Online";
end;
call countCourses(#bothtype,#Inpersononly,#Onlineonly);
SELECT #bothtype,#Inpersononly,#Onlineonly;
EXPLICATION :
Creating procedure to store the count of each type of course in OUT variable
Call the procedure with convenient parameters
Select out given parameters

Transpose data in HIVE

I have the following dataset in Hive, and I would like to transpose rows into columns.
Customer
Status
Quantity
25
Paid
5
25
N Paid
2
67
Open
12
67
Paid
4
45
N Paid
3
45
Open
2
I would like to have a new table after transpose that shows only one line by a customer and multiple columns by Status, e.g.
Customer
Paid
N Paid
Open
25
5
2
0
67
4
0
12
45
0
3
2
I tried some examples I've found on the Internet, but I could not make it works. Here, for the sake of simplicity, I listed only three statuses, but in fact, I could have more than that.
In SAS, I used to did something such as the following:
proc transpose
data = imputtable;
out = outputtable;
by customer;
id status;
var quantity;
run;
SAS gets all the existing statuses and pivots them into columns. I was looking to do the same in Hive.
Regards,
Marcio
Use conditional aggregation:
select Customer,
sum(case when Status = 'Paid' then Quantity else 0 end) as Paid ,
sum(case when Status = 'N Paid' then Quantity else 0 end) as `N Paid` ,
sum(case when Status = 'Open' then Quantity else 0 end) as Open
from table
group by Customer

SQL Server Rowcount of column value

I am trying to write a simple SQL code that can get the desired output, from this table -
Original Table :
id | type
123 0
123 1
123 1
345 0
345 0
What I'm trying to get is:
id | zeroCount | oneCount
123 1 2
345 2 0
I tried to group by the id and also type but, both of them gives the same thing!
How to get desired output?
Here is a simple way, assuming the values are only 0 and 1:
select id, sum(1 - type) as zerocount, sum(type) as onecount
from t
group by id;
A more typical approach would use case (or even pivot):
select id, sum(case when type = 0 then 1 else 0 end) as zerocount,
sum(case when type = 1 then 1 else 0 end) as onecount
from t
group by id;
You could get fancy and use a pivot function. But this will work:
Select id,
sum(case when type = 0 then 1 else 0 end) as ZeroCount,
Sum(case when type = 1 then 1 else 0 end) as OneCount
from table
group by id
order by id

SQL find total count of each type in a column

I'm learning SQL and am stumped on what should be a simple query. I have a table with the following pattern:
Id | Type
------------
1 | Red
2 | Blue
3 | Blue
4 | Red
..
I would like to write a query to return a table that counts the total number of instances of each type and returns a table with the following pattern, for example, if 'Blue' occurs in 12 rows, and 'Red' occurs in 16 rows in the table above, the result would be:
Blue | Red
-----------
12 | 16
You could do it this way:
SELECT Type, COUNT(*) FROM TABLE GROUP BY Type
If you'd like to see the Types in separate columns, you could do this:
SELECT SUM(CASE WHEN Type = 'Blue' THEN 1 ELSE 0 END) AS Blue, SUM(CASE WHEN Type = 'Red' THEN 1 ELSE 0 END) AS Red FROM TABLE
I suggest using count over partition by. Here's a code I wrote to help my company check for duplicate Technician EmployeeID's and Pincodes, including count and YES/NO columns to allow filtering in excel so they can see what corrections need to be made:
select
t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
, [Pincode Count] = count(t.Pincode) over (partition by t.Pincode)
, [Duplicate Pincode?] = case count(t.Pincode) over (partition by t.Pincode) when 1 then 'NO' else 'YES' end
, [EmployeeID Count] = count(t.EmployeeID) over (partition by t.EmployeeID)
, [Duplicate EmployeeID?] = case count(t.EmployeeID) over (partition by t.EmployeeID) when 1 then 'NO' else 'YES' end
from Technicians t
group by t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
order by 4

Aggregation two table

I have two tables
nameTB contains:
id | name | gender | nationalityid
nationalityTB contains:
nationalityid | nationalityname
I want create sql query to return the result:
nationalityname female male total
UK 10 5 15
USA 11 7 18
You should be able to easily get the result by joining the tables and using an aggregate function with conditional logic (like a CASE expression):
select nt.nationalityname,
sum(case when nm.gender = 'Female' then 1 else 0 end) Female,
sum(case when nm.gender = 'Male' then 1 else 0 end) Male,
count(*) Total
from nationalityTB nt
left join nameTB nm
on nt.nationalityid = nm.nationalityid
group by nt.nationalityname;
See SQL Fiddle with Demo