How to transpose columns? - sql

I have this table
SKU
CITY
MOV
TYPE
UNI
IMP
1
116
49
Caducidad
3
203.889
1
116
48
Daño
3
203.889
1
116
47
Robo
NULL
NULL
And I'm trying to transpose 'Type' column to display something like this
SKU
CITY
TYPE_UNI_CADUCIDAD
TYPE_IMP_CADUCIDAD
TYPE_UNI_DAÑO
TYPE_IMP_DAÑO
TYPE_UNI_ROBO
TYPE_IMP_ROBO
1
116
3
203.889
3
203.889
NULL
NULL
I tried case and pivot but not really working
SELECT SKU, CITY,
case
when MOV=49 then sum(Total_Imp) end as Type_Imp_Caducidad ,
case
when MOV=48 then sum(Total_Imp) end as Type_Imp_Daño ,
case
when MOV=47 then sum(Total_Imp) end as Type_Imp_Robo
from #movimientos
where Id_Num_SKU=11466978
group by SKY, CITY, MOV

As both comentsalready told you you need to aggreate the hole CASE WHEN to have an aggregation function
SELECT SKU, CITY,
sum(case
when MOV=49 then Total_Imp end) as Type_Imp_Caducidad ,
sum(case
when MOV=48 then Total_Imp end) as Type_Imp_Daño ,
SUM(case
when MOV=47 then Total_Imp end) as Type_Imp_Robo
from #movimientos
where Id_Num_SKU=11466978
group by SKY, CITY

You need to remove MOV from the GROUP BY and then aggregate the whole CASE expression
SELECT
m.SKU,
m.CITY,
SUM(case when m.MOV = 49 then m.Total_Uni end) as Type_Uni_Caducidad,
SUM(case when m.MOV = 49 then m.Total_Imp end) as Type_Imp_Caducidad,
SUM(case when m.MOV = 48 then m.Total_Uni end) as Type_Uni_Daño,
SUM(case when m.MOV = 48 then m.Total_Imp end) as Type_Imp_Daño,
SUM(case when m.MOV = 47 then m.Total_Uni end) as Type_Uni_Robo,
SUM(case when m.MOV = 47 then m.Total_Imp end) as Type_Imp_Robo
from #movimientos m
where m.Id_Num_SKU = 11466978
group by
m.SKY,
m.CITY;

Related

How to Combine two pivot tables when both the tables are combined by inner Join function

Tag
SELECT TOP (1000) [System_Order_Id]
,[Batch_No]
,[Material_Code]
,[Set_Weight]
,[Actual_Weight]
FROM [master].[dbo].[Consumption_Report]
Batch No
System Id
Material Code
Set Weight
Actual Weight
1
1
1
Mat01
100
99
2
1
1
Mat02
50
55
3
1
1
Mat03
80
35
4
1
1
Mat04
40
20
SELECT TOP (1000)[Batch_End_TimeStamp]
,[Machine_Code]
, [User_Order_Id]
,[Batch_No]
,[Recipe_Code]
,[Cycle_Time]
,[System_Mode]
FROM [master].[dbo].[Batch_Report]
System Id
Batch No
Machine_Code
Recipe_Code
Cycle_Time
1
1
1
23
AA01
532
My Code:
WITH Consumption_Report AS (
SELECT
t1.Material_Code,
t1.Set_Weight,
t2.Batch_End_TimeStamp,
t2.Machine_Code,
t2.User_Order_Id,
t2.Recipe_Code,
t2.Cycle_Time
FROM
dbo.Consumption_Report t1
INNER JOIN dbo.Batch_Report t2 ON t2.Batch_No = t1.Batch_No
)
SELECT *
FROM Consumption_Report
PIVOT (AVG(Set_Weight) FOR Material_Code IN (Mat01,Mat02,Mat03,Mat04)) P
I want output like this:
Batch No
System Id
Machine_Code
Recipe_Code
Cycle_Time
Mat 01 Set Weight
Mat 01 Actual Weight
Mat 02 Set Weight
Mat 02 Actual Weight
Mat 03 Set Weight
Mat 03 Actual Weight
Mat 04 Set Weight
Mat 04 Actual Weight
1
1
1
23
AA01
532
100
99
50
55
80
35
40
20
I don't see what the second table has to do with anything. Just use conditional aggregation:
select Id, Batch_No, System_Id,
max(case when Material_Code = 'Mat01' then set_weight end) as mat01_set_weight,
max(case when Material_Code = 'Mat01' then actual_weight end) as mat01_actual_weight,
max(case when Material_Code = 'Mat02' then set_weight end) as mat02_set_weight,
max(case when Material_Code = 'Mat02' then actual_weight end) as mat02_actual_weight,
max(case when Material_Code = 'Mat03' then set_weight end) as mat03_set_weight,
max(case when Material_Code = 'Mat03' then actual_weight end) as mat03_actual_weight,
max(case when Material_Code = 'Mat04' then set_weight end) as mat04_set_weight,
max(case when Material_Code = 'Mat04' then actual_weight end) as mat04_actual_weight
from Consumption_Report
group by Id, Batch_No, System_Id;
SELECT * FROM Batch_Report
INNER JOIN (
select Batch_No,
sum(case when Material_Code = 'Mat01' then Set_Weight else 0 end) as Mat01,
sum(case when Material_Code = 'Mat01' then Actual_Weight else 0 end) as
Mat01_Act,
sum(case when Material_Code = 'Mat02' then Set_Weight else 0 end) as Mat02,
sum(case when Material_Code = 'Mat02' then Actual_Weight else 0 end) as
Mat02_Act,
sum(case when Material_Code = 'Mat03' then Set_Weight else 0 end) as Mat03,
sum(case when Material_Code = 'Mat03' then Actual_Weight else 0 end) as
Mat03_Act,
sum(case when Material_Code = 'Mat04' then Set_Weight else 0 end) as Mat04,
sum(case when Material_Code = 'Mat04' then Actual_Weight else 0 end) as Mat04_Act
from Consumption_Report
group by Batch_No) Consumption_Report
ON Batch_Report.Batch_No = Consumption_Report.Batch_No;

Oracle : Multiple Pivot columns on the Same numeric column

I have the following Data:
Vehicle ID Region District City Revenue
X50 Southwest FLD Miami 50
X50 Northeast NYC Rochester 70
X70 Southwest FLD Miami 20
I want to pivot the Region, District and City with the Revenue column.
Output:
Vehicle ID Southwest_R Northeast_R FLD_R NYC_R Miami_R Rochester_R
X50 50 0 50 0 50 0
X50 0 75 0 75 0 75
X70 20 0 25 0 25 0
The problem I am facing is to add those pivots in a single query.
Select * from table
Pivot( SUM(Revenue) for Region IN ('Southwest' Southwest_R, 'Northeast' Northeast_R))
in this query if I add District and City, it throws error.
Hmmm . . . This looks like conditional logic not aggregation:
select vehicle_id,
(case when region = 'Southwest' then revenue else 0 end) as southwest_r,
(case when region = 'Northeast' then revenue else 0 end) as northeast_r,
(case when district = 'District' then revenue else 0 end) as fld_r,
(case when district = 'NYC' then revenue else 0 end) as nyc_r,
. . .
from t;
If you can have multiple rows per vehicle, then you can use aggregation:
select vehicle_id,
sum(case when region = 'Southwest' then revenue else 0 end) as southwest_r,
sum(case when region = 'Northeast' then revenue else 0 end) as northeast_r,
sum(case when district = 'District' then revenue else 0 end) as fld_r,
sum(case when district = 'NYC' then revenue else 0 end) as nyc_r,
. . .
from t
group by vehicle_id;

Total of Multiple COUNT SELECTS from the multiple tables not working

I have A attendance report in which I want to show report day wise like this :
I can calculate Sum individually , But not the total of all Sum
My StudentAttendance Table :
ID ClassID SubjectID Day10 Day11 Day12 Day13 Day14 Day15 ProfessorID
215 23 46 P 36 36
216 23 47 P 36
217 23 48 P 36 P 36
218 17 35 P 28
I have Tried this Query :
select ClassID,
sum(case when Day14= 'P' then 1 else 0 end) Present,
sum(case when Day14= 'A' then 1 else 0 end) Absent,
sum(case when Day14= 'L' then 1 else 0 end) Leave
from studentattendance
group by ClassID,Day14
I tried Sum(Present.Absent,Leave)..But not working What I am missing ??
There is no SQL syntax for a SELECT with multiple FROM clauses(WITHOUT nesting).
Perhaps you want something like this?
select
classID,
count(Day14) Total,
sum(case when Day14='P' then 1 else 0 end) Present,
sum(case when Day14='A' then 1 else 0 end) Absent,
sum(case when Day14='L' then 1 else 0 end) Leave
from studentattendance
group by classID
Here Total is merely the total number of records in each classID. The sum(case..when..) statements simulates a selective count() only when certain condition is satisfied (Day14 is either Present,Absent or Leave). Note that there is no guarantee that the Total to be equal to Present+Absent+Leave if you expect values other than these 3 to be present in the column Day14

Getting sub-counts along with Average and Count

I have two tables...
MODULES ENROLMENTS
GroupNo StudentNo
Title GroupNo
Tutor CourseworkMark
DayNo ExamMark
Time
Room
Semester
I wish to create a view that displays the average mark achieved in coursework and exam for each module and also a count of the number of students who achieved >70, 60-69, 50-59, 40-49 and <40. Is this possible?
I have the average marks worked out with...
SELECT Title,
AVG(CourseworkMark) AS AverageCoursework,
AVG(ExamMark) AS AverageExam
FROM tblModules INNER JOIN tblEnrolments
ON tblModules.GroupNo = tblEnrolments.GroupNo
GROUP BY Title;
You can use a SUMmed CASE expression to do this;
SELECT Title,
AVG(CourseworkMark) AS AverageCoursework,
AVG(ExamMark) AS AverageExam,
SUM(CASE WHEN CourseworkMark > 70 THEN 1 ELSE 0 END) AS CourseworkMarkOver70,
SUM(CASE WHEN CourseworkMark BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS CourseworkMarkOver60To69,
SUM(CASE WHEN CourseworkMark BETWEEN 50 and 59 THEN 1 ELSE 0 END) AS CourseworkMarkOver50To59,
SUM(CASE WHEN CourseworkMark BETWEEN 40 and 49 THEN 1 ELSE 0 END) AS CourseworkMarkOver40To49,
SUM(CASE WHEN CourseworkMark < 40 THEN 1 ELSE 0 END) AS CourseworkMarkUnder40
FROM tblModules INNER JOIN tblEnrolments
ON tblModules.GroupNo = tblEnrolments.GroupNo
GROUP BY Title;

count(*) based on the gender condition

I have the following table in oracle10g.
state gender avg_sal status
NC M 5200 Single
OH F 3800 Married
AR M 8800 Married
AR F 6200 Single
TN M 4200 Single
NC F 4500 Single
I am trying to form the following report based on some condition. The report should look like the one below. I tried the below query but count(*) is not working as expected
state gender no.of males no.of females avg_sal_men avg_sal_women
NC M 10 0 5200 0
OH F 0 5 0 3800
AR M 16 0 8800 0
AR F 0 12 0 6200
TN M 22 0 4200 0
NC F 0 8 0 4500
I tried the following query but I am not able to count based onthe no.of males and no.of females..
select State, "NO_OF MALES", "$AVG_sal", "NO_OF_FEMALES", "$AVG_SAL_FEMALE"
from(
select State,
to_char(SUM((CASE WHEN gender = 'M' THEN average_price ELSE 0 END)),'$999,999,999') as "$Avg_sal_men,
to_char(SUM((CASE WHEN gender = 'F' THEN average_price ELSE 0 END)), '$999,999,999') as "$Avg_sal_women,
(select count (*) from table where gender='M')"NO_OF MALES",
(select count (*) from table where gender='F')"NO_OF_FEMALES"
from table group by State order by state);
You can use case as an expression (which you already know...). And the subquery is unnecessary.
select State
, sum(case gender when 'M' then 1 else 0 end) as "no.of males"
, sum(case gender when 'F' then 1 else 0 end) as "no.of females"
, to_char(
SUM(
(
CASE
WHEN gender = 'M' THEN average_price
ELSE 0
END
)
)
, '$999,999,999'
) as "Avg_sal_men",
to_char(SUM((CASE WHEN gender = 'F' THEN average_price ELSE 0 END))
,'$999,999,999'
) as "Avg_sal_women"
from table
group by State;
You are Conting by this sub-query select count (*) from table where gender='M' which always count the total number of male in your whole table....and you are doing same for counting female...
So you Can Try like this...
select State, "NO_OF MALES", "$AVG_sal", "NO_OF_FEMALES", "$AVG_SAL_FEMALE"
from(
select State,
to_char(SUM((CASE WHEN gender = 'M' THEN average_price ELSE 0 END)),'$999,999,999') as "$Avg_sal_men",
to_char(SUM((CASE WHEN gender = 'F' THEN average_price ELSE 0 END)), '$999,999,999') as "$Avg_sal_women,
Sum(Case when gender='M' then 1 else 0 end) "NO_OF MALES",
Sum(Case when gender='F' then 1 else 0 end) "NO_OF_FEMALES"
from table group by State order by state);
Try the following.
select state
,sum(case when gender = 'M' then 1 else 0 end) as nof_males
,sum(case when gender = 'F' then 1 else 0 end) as nof_females
,avg(case when gender = 'M' then average_price end) as avg_sal_male
,avg(case when gender = 'F' then average_price end) as avg_sal_female
from table
group
by state;
..add formatting as required.