SQL rows to column [duplicate] - sql

This question already has answers here:
SQL Rows to Columns
(3 answers)
Closed 7 years ago.
This is my query.
select name, walk_to, count(*) count
from walk
where name='Rizwan'
group by name, walk_t0;
This results in data like:
NAME WALK_TO COUNT
Rizwan Cafe 2
Rizwan Arena 10
Rizwan Outside 20
There are other users' data as well. What I want is:
NAME CAFE ARENA OUTSIDE
Rizwan 2 10 20
John 3 21 90
James 5 5 9
Any idea how to write a query to get this result?

SELECT name,
SUM(CASE WHEN walk_to = 'Cafe' THEN 1 ELSE 0 END) Cafe,
SUM(CASE WHEN walk_to = 'Arena' THEN 1 ELSE 0 END) Arena,
SUM(CASE WHEN walk_to = 'Outside' THEN 1 ELSE 0 END) Outside
FROM walk
GROUP BY name
This is called pivioting for more examples look here SQL Server: Examples of PIVOTing String data

select name,
sum(case when walk_to='Cafe' then 1 else 0 end) as CAFE,
sum(case when walk_to='Arena' then 1 else 0 end) as ARENA,
sum(case when walk_to='Outside' then 1 else 0 end) as OUTSIDE
FROM walk
GROUP BY name

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

SQL - Impala - How to unfold one categorical column into many?

I have the following table :
user category number
1 A 8
1 B 6
2 A 1
2 C 9
3 B 5
I want to "unfold" or "dummify" the category column and fill them with the "number" column to obtain:
user cat_A cat_B cat_C
1 8 6 0
2 1 0 9
3 0 5 0
Is it possible to achieve this in SQL (Impala) ?
I found this question How to create dummy variable columns for thousands of categories in Google BigQuery?
However it seems a little bit complex and I'd rather do it in Pandas.
Is there a simpler solution, knowing that I have 10 categories (A, B, C, D etc)?
You can try to use condition aggregate function.
SELECT user,
SUM(CASE WHEN category = 'A' THEN number ELSE 0 END) cat_A,
SUM(CASE WHEN category = 'B' THEN number ELSE 0 END) cat_B,
SUM(CASE WHEN category = 'C' THEN number ELSE 0 END) cat_C
FROM T
GROUP BY user

Find count group by id in SQL Server

I need some help to solve this query. I have a table which contains the ages of the passengers who are going to stay in a room which is mentioned below:
Age RoomId
----- ---
1 1
12 1
8 1
19 1
3 2
12 2
18 2
21 3
Also, I have properties table which contains the maximum age of the child and maximum age of the infant. Based on the age of the passenger, I need to segregate them to adult, child, and infant to each of the properties.
Properties table structure
Property Id Maximum_child_age Maximum_infant_age
-------------------------------------------------
1 11 2
Desired output
RoomId Adult Child Infant PropertyId
--------------------------------
1 2 1 1 1
2 2 1 0 1
3 1 0 0 1
Use conditional aggregation :
SELECT
SUM(CASE WHEN pas.age > ppt.Maximum_child_age THEN 1 ELSE 0 END) AS Adult,
SUM(CASE WHEN pas.age BETWEEN Maximum_infant_age AND ppt.Maximum_child_age THEN 1 ELSE 0 END) AS Child,
SUM(CASE WHEN pas.age < ppt.Maximum_infant_age THEN 1 ELSE 0 END) AS Infant,
ppt.id
FROM
passengers pas
CROSS JOIN properties ppt
GROUP BY ppt.id
Cross join the properties and then do conditional aggregation.
SELECT count(CASE
WHEN pa.ages > pr.maximum_child_age THEN
1
END) adult,
count(CASE
WHEN pa.ages > pr.maximum_infant_age
AND pa.ages <= pr.maximum_child_age THEN
1
END) child,
count(CASE
WHEN pa.ages <= pr.maximum_infant_age THEN
1
END) infant,
pr.propertyid
FROM passengers pa
CROSS JOIN properties pr
GROUP BY pr.propertyid;

sql query required grouping column in single row [duplicate]

This question already has answers here:
need to return two sets of data with two different where clauses
(2 answers)
Closed 8 years ago.
I have following table structure
TicketID Status Duration
-----------------------------
1234 8 2
1233 8 10
1232 4 5
1231 8 12
1230 4 50
status 8 means Closed
status 4 means Open
It is required to have output in following way. Please do the need ful. If possible I wanted it in a single sql query.
Please help me to produce output in following way.
Row Closed (sum) Open(Sum)
---------------------------------
1 24 55
select 1 as row,
sum(case when status = 8 then 1 else 0 end) as closed,
sum(case when status = 4 then 1 else 0 end) as open
from your_table
select
1 as Row,
sum(case when Status=8 then 1 else 0 end ) as Closed_Sum,
sum(case when Status=4 then 1 else 0 end ) as Open_Sum
from
Mytable

SQL ROW TO COLUMN [duplicate]

This question already has answers here:
Dynamic Pivot in Oracle's SQL
(10 answers)
Closed 8 years ago.
I have a table as follow
OPERATIONS
OPERATOR-OPERATION TYPE
Ahmet DELETE
Ahmet UPDATE
Ahmet READ
Salih DELETE
Salih UPDATE
Salih READ
Salih READ
Salih CREATE
What SQL will be to get following result? When simple COUNT, GROUP BY clauses used Operation types written as ROW based.
Name- Total- DELETE- READ- UPDATE CREATE
Ahmet 3 1 1 1 0
Salih 5 1 2 1 1
select operator,
count(*) as total,
sum(case when operation_type = 'DELETE' then 1 else 0 end) as deletes,
sum(case when operation_type = 'UPDATE' then 1 else 0 end) as updates,
sum(case when operation_type = 'READ' then 1 else 0 end) as reads,
sum(case when operation_type = 'CREATE' then 1 else 0 end) as creates
from operations
group by operator