column headers in select Union query - sql

I have to select query like the following example :
Select name,
SUM(DECODE(TO_CHAR(Datee,'MM'),'01',PRICE)) JAN_12,
SUM(DECODE(TO_CHAR(Datee,'MM'),'02',PRICE)) FEB_12
from price_list_LastYear
UNION ALL
Select name,
SUM(DECODE(TO_CHAR(Datee,'MM'),'01',PRICE)) JAN_11,
SUM(DECODE(TO_CHAR(Datee,'MM'),'02',PRICE)) FEB_11
from price_list_TwoLastYear.
When I execute the query, In my column header I get name, JAN_12, FEB_12.
I want to combine my results like : name, JAN_11, JAN_12, FEB_11,FEB_12.

Try this:
SELECT P1.name,
SUM(DECODE(TO_CHAR(P1.Datee,'MM'),'01',P1.PRICE)) JAN_12,
SUM(DECODE(TO_CHAR(P1.Datee,'MM'),'02',P1.PRICE)) FEB_12,
SUM(DECODE(TO_CHAR(P2.Datee,'MM'),'01',P2.PRICE)) JAN_11,
SUM(DECODE(TO_CHAR(P2.Datee,'MM'),'02',P2.PRICE)) FEB_11
FROM price_list_LastYear P1
JOIN price_list_TwoLastYear P2
ON P1.nmae = P2.nmae
GROUP BY P1.nmae
If same name doesn't exists in both tables try this:
SELECT N.name,
SUM(DECODE(TO_CHAR(P1.Datee,'MM'),'01',P1.PRICE)) JAN_12,
SUM(DECODE(TO_CHAR(P1.Datee,'MM'),'02',P1.PRICE)) FEB_12,
SUM(DECODE(TO_CHAR(P2.Datee,'MM'),'01',P2.PRICE)) JAN_11,
SUM(DECODE(TO_CHAR(P2.Datee,'MM'),'02',P2.PRICE)) FEB_11
FROM
(
SELECT name FROM price_list_LastYear
UNION
SELECT name FROM price_list_TwoLastYear
) N
LEFT JOIN price_list_LastYear P1
ON N.nmae = P1.name
LEFT JOIN price_list_TwoLastYear P2
ON N.nmae = P2.name
GROUP BY N.name

Try this
SELECT A.*, B,JAN_11, B.FEB_11 FROM (
Select name,
SUM(DECODE(TO_CHAR(Datee,'MM'),'01',PRICE)) JAN_12,
SUM(DECODE(TO_CHAR(Datee,'MM'),'02',PRICE)) FEB_12
from price_list_LastYear
Group By Name) A
LEFT OUTER JOIN (
Select name,
SUM(DECODE(TO_CHAR(Datee,'MM'),'01',PRICE)) JAN_11,
SUM(DECODE(TO_CHAR(Datee,'MM'),'02',PRICE)) FEB_11
from price_list_TwoLastYear
Group By Name) B ON A.name = B.Name
Or
Select name,
SUM(CASE WHEN Yr = '11' THEN DECODE(Mnth,'01',PRICE) ELSE NULL END) JAN_11,
SUM(CASE WHEN Yr = '12' THEN DECODE(Mnth,'01',PRICE) ELSE NULL END) JAN_12,
SUM(CASE WHEN Yr = '11' THEN DECODE(Mnth,'02',PRICE) ELSE NULL END) FEB_11,
SUM(CASE WHEN Yr = '12' THEN DECODE(Mnth,'02',PRICE) ELSE NULL END) FEB_12
from
(
SELECT '12' As yr, name, TO_CHAR(Datee,'MM') Mnth, Price
FROM price_list_LastYear
UNION ALL
SELECT '11' As yr, name, TO_CHAR(Datee,'MM') Mnth, Price
FROM price_list_TwoLastYear
)
GROUP BY Name

If the name does not exist in both tables, then it might be difficult to use a JOIN. So here is a version using UNION ALL and then applying an aggregate function with a CASE expression to transform the data to columns:
SELECT name,
sum(case when Month = 'JAN_12' then price else 0 end) JAN_12,
sum(case when Month = 'FEB_12' then price else 0 end) FEB_12,
sum(case when Month = 'JAN_11' then price else 0 end) JAN_11,
sum(case when Month = 'FEB_11' then price else 0 end) FEB_11
FROM
(
Select name,
PRICE,
case
when TO_CHAR(Datee,'MM') = '01' Then 'JAN_12'
when TO_CHAR(Datee,'MM') = '02' Then 'FEB_12' End Month
from price_list_LastYear
WHERE TO_CHAR(Datee,'MM') in ('01', '02')
UNION ALL
Select name,
PRICE,
case
when TO_CHAR(Datee,'MM') = '01' Then 'JAN_11'
when TO_CHAR(Datee,'MM') = '02' Then 'FEB_11' End Month
from price_list_TwoLastYear
WHERE TO_CHAR(Datee,'MM') in ('01', '02')
) src
GROUP BY name

Related

Sum of rows as columns

I have a table as below with (ID, DATE, Category, Price) as columns
I would like the output as below.
Could you please help me?
Thank you
You can go for conditional grouping as given below. you can go for IN clause to make code simpler.
SELECT ID, DATE,
SUM(CASE WHEN Category IN ('R','F') THEN Price ELSE 0 END) AS Regular,
SUM(CASE WHEN Category IN ('B','C') THEN Price ELSE 0 END) AS Bonus,
SUM(CASE WHEN Category IN ('K','W','O','OW') THEN Price ELSE 0 END) AS Other
FROM TableName
GROUP BY ID, DATE
Per my understanding, you want to do group by Date column and show the SUM of the values in new column
Try this (haven't test it):
select ID, Date,
sum((case when Category = 'R' then Price) + (case when Category = 'F' then Price)) as 'Regular (R+F)',
sum((case when Category = 'B' then Price) + (case when Category = 'C' then Price)) as 'Bonus (B+C)',
sum((case when Category = 'K' then Price) + (case when Category = 'W' then Price)
+ (case when Category = 'O' then Price) + (case when Category = 'OW' then Price)) as 'Other (K+W+O+OW)'
from t
group by Date;

SUM Function with WHERE clause for each sum?

I have two tables: Staff and Hours.
Staff(200+ rows) with:
Staff_ID, Name, Position
each staff member only appears once in this table
Hours (1000+ rows) with:
Staff_ID, Hours, Amount, BillableFlag, Office, DatePeriod
each staff member appears many times in this table
I need a query that pulls in all Staff from the Staff table with position = 'Assistant' and the Hours and Amount columns from the Hours table summed twice each with different logic for each sum.
Something like this ( it's a query with some plain english to help with the explanation ):
select s.name,
sum(h.hours) as 'Hours_Not_Billable' --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG <> 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.amount) as 'Amount_Not_Billable' --[NEED IT TO SUM ONLY AMOUNT WHERE h.BILLABLEFLAG <> 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.hours) as 'Hours_Billable' --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG = 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.amount) as 'Amount_Billable --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG = 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER]'
from Staff S
left join Hours H on S.Staff_ID = H.Staff_ID
where s.position = 'Assistant'
group by s.name
Help much appreciated!
Thank you
Use conditional aggregation. The idea is to put a case expression inside the sum(), that filters out with values are taken into account.
Your pseudo-code would translate as:
select
s.name,
sum(case when h.billableflag <> 'Y' then h.hours else 0 end) hours_not_billable,
sum(case when h.billableflag <> 'Y' then h.amount else 0 end) amount_not_billable,
sum(case when h.billableflag = 'Y' then h.hours else 0 end) hours_billable,
sum(case when h.billableflag = 'Y' then h.amount else 0 end) amount_billable
from staff s
left join hours h
on s.staff_id = h.staff_id and h.office = 2 and h.period = 'Q3'
where s.position = 'Assistant'
group by s.name
Note: most of the conditions are common to all expressions, so I moved them to the on clause of the left join.
You can use CASE WHEN within SUM() aggregation function as follows
select
s.name,
sum(case when h.BILLABLEFLAG <> 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.hours else null end) as 'Hours_Not_Billable',
sum(case when h.BILLABLEFLAG <> 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.amount else null end) as 'Amount_Not_Billable',
sum(case when h.BILLABLEFLAG = 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.hours else null end) as 'Hours_Billable',
sum(case when h.BILLABLEFLAG = 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.amount else null end ) as 'Amount_Billable'
from Staff S
left join Hours H on S.Staff_ID = H.Staff_ID
where s.position = 'Assistant'
group by s.name

expected result is not getting

I have a data like this:
And I want this - I am trying with PIVOT but not getting the expected results:
Query is
SELECT AttendeeID,[Quantity1],[PROD1],[Quantity2],[PROD2],[Quantity3],[PROD3] FROM
(SELECT * ,
row_number() over(partition by AttendeeID order by AttendeeID)rn
from #ProductTestingwithPosition2) TT
PIVOT
(MAX(product) for ProductPosition in ([PROD1],[PROD2],[PROD3])) AS Tab2
PIVOT
(sum(Quantity) for QuantityPosition in ([Quantity1],[Quantity2],[Quantity3])) AS Tab3
I am getting this output:
Just use conditional aggregation:
SELECT AttendeeID,
MAX(CASE WHEN ProductPosition = 'PROD1' THEN product END) as prod1,
MAX(CASE WHEN QuantityPosition = 'QUANTITY1' THEN quantity END) as quantity1,
MAX(CASE WHEN ProductPosition = 'PROD2' THEN product END) as prod2,
MAX(CASE WHEN QuantityPosition = 'QUANTITY2' THEN quantity END) as quantity2,
MAX(CASE WHEN ProductPosition = 'PROD3' THEN product END) as prod3,
MAX(CASE WHEN QuantityPosition = 'QUANTITY3' THEN quantity END) as quantity3
FROM (SELECT ptp.* ,
row_number() over (partition by AttendeeID, ProductPosition order by AttendeeID) as seqnum
FROM #ProductTestingwithPosition2 ptp
) ptp
GROUP BY AttendeeID, seqnum;
PIVOT -- in addition to being non-standard -- is very finicky. Conditional aggregation is much more powerful and less prone to errors.

Combine Table in SQL

I have two tables would like to combine.
I would like the table will automatically add a row for image2 when there are new generalname in image1.
select B.Trsdate, count(B.Billno) As Billno, sum(B.pax) As Pax, sum(B.Grossamount) As GrossAmount, sum(B.discountamount) As Discount, sum(B.taxamount) As Tax, sum(B.servicechargeamount) As SCharge, sum(B.nettamount) As NettAmt, sum(B.rounddiff) As RDiff, sum(B.roundamt) As RoundAmt, sum(B.reversalYN) As RevBillNo, SUM(GD.CASH) AS 'P_CASH', SUM(GD.VISA) AS 'P_VISA', SUM(GD.MASTER) AS 'P_MASTER', SUM(GD.AMEX) AS 'P_Amex', SUM(GD.CityLedger) AS 'P_CityLedger', SUM(GD.OtherPayment) As 'P_Other'
from vpos_eod_bills As B
INNER JOIN
(
SELECT TrsNo,SUM(CASH) as CASH,SUM(Visa) as Visa, SUM(Master) as Master, SUM(Amex) AS Amex, SUM(CityLedger) as CityLedger, SUM(OtherPayment) as OtherPayment, SUM(Total) as Total FROM
(
select TrsNo, GENERALNAME,
(case WHEN(Generalname IN ('CASH'))
THEN
SUM(AMOUNT)
ELSE
0
END) as 'CASH',
(case WHEN(Generalname IN ('VISA'))
THEN
SUM(AMOUNT)
ELSE
0
END) as 'Visa',
(case WHEN(Generalname IN ('MASTER'))
THEN
SUM(AMOUNT)
ELSE
0
END) as 'Master',
(case WHEN(Generalname IN ('AMEX'))
THEN
SUM(AMOUNT)
ELSE
0
END) as 'Amex',
(case WHEN(Generalname = 'City Ledger' OR Generalname = 'CREDIT A/C' OR Generalname = 'BOSS' OR Generalname = 'ENTERTAINMENT')
THEN
SUM(AMOUNT)
ELSE
0
END) as 'CityLedger',
(case WHEN(Generalname not IN ('CASH','Voucher','VISA','MASTER','AMEX','JCB','City Ledger','CREDIT A/C','BOSS','ENTERTAINMENT') and (Generalname not like '%card%') and (Generalname not like '%Coupon%') and (Generalname not like '%GROUPON%') and (Generalname not like '%COURSE%'))
THEN
SUM(AMOUNT)
ELSE
0
END) as 'OtherPayment',
SUM(AMOUNT) as Total
from Vpos_eod_GeneralDetails
where BillType = 'P'
group by TrsNo, GeneralName
) As A
Group By A.trsno
)As GD ON GD.TrsNo = B.TrsNo
where B.PaidStatus = '1' and B.VoidStatus = '0' and (B.trsdate between '20200101' and '20200131')
group by B.trsdate

Sum all rows that are sum of a column sql 2012

I want to get a total sum of the results of my "total tested" "failed" and "passed" colums. I would usually handle these aggregates in SSRS, but I don't have that option at this time.
My current query:
select s.school_code, s.name, count(cd.Test_ID) as [Tested],
sum(case when cd.result = 'fail' then 1 Else 0 End) as 'Failed'
,sum(case when cd.result = 'pass' then 1 Else 0 End) as 'Passed'
FROM
[psi_db_8amSnapshot].[dbo].[Candidate_Data] cd
join [psi_db_8amSnapshot].[dbo].account_school s on s.school_id = cd.school_id
where s.School_code in
(
'1001',
'1002',
'1003' ,
'1004' ,
'1005' ,
'1006' ,
'1007' ,
'1008' ,
'1016' ,
'1009' ,
'1010' ,
'1012' ,
'1013' ,
'1014' ,
'1015'
)
and cd.[date] between '01-01-2016' and '05-01-2017' and cd.TestName = 'MN Dental Assistant State Licensure Examination'
group by s.school_code, s.name, test_id
I am looking to get a total off all the values in my three aggregate columns. So a sum of Tested, which should = 640, sum of passed = 327, sum of failed = 313.
I think you are looking for group by grouping sets as below:
Just replace your group by as below:
group by grouping sets ((s.school_code), (s.name), (test_id))
I would probably use with statements:
with NumberOfFailedResults as
(
Select count(cd.result) as NumberOfFailedResults from [psi_db_8amSnapshot].[dbo].[Candidate_Data] as cd where cd.Result = 'Failed'
),
NumberOfPassedResults as
(
Select count(cd.result) as NumberOfPassedResults from [psi_db_8amSnapshot].[dbo].[Candidate_Data] as cd where cd.Result = 'Passed'
)
Select NumberOfFailedResults, NumberOfPassedResults, ...
This should work for you.
select Q.school_code, Q.name, SUM(Q.Tested), SUM(Q.Failed), SUM(Q.Passed) from (
select s.school_code, s.name, count(cd.Test_ID) as [Tested],
sum(case when cd.result = 'fail' then 1 Else 0 End) as 'Failed'
,sum(case when cd.result = 'pass' then 1 Else 0 End) as 'Passed'
FROM
[psi_db_8amSnapshot].[dbo].[Candidate_Data] cd
join [psi_db_8amSnapshot].[dbo].account_school s on s.school_id = cd.school_id
where s.School_code in
(
'1001',
'1002',
'1003' ,
'1004' ,
'1005' ,
'1006' ,
'1007' ,
'1008' ,
'1016' ,
'1009' ,
'1010' ,
'1012' ,
'1013' ,
'1014' ,
'1015'
)
and cd.[date] between '01-01-2016' and '05-01-2017' and cd.TestName = 'MN Dental Assistant State Licensure Examination'
group by s.school_code, s.name, test_id)Q
GROUP BY Q.School_Code, Q.Name