SQL Pivoting With rollup (or a row totals) - sql-server-2012

I have the following query with some g/l accounts and sum totals by month:
Select Month, [41100],[42000],[45100],[42200],[42300],[42400],[45200],
[45205]
from ( Select ACC_0 , (CONVERT(NUMERIC(12,2),(AMTLED_0))) as Amount , MONTH(ACCDAT_0) as Month
from x3v6.CICPROD.GACCENTRYD with(nolock)
where YEAR(ACCDAT_0) = YEAR(GETDATE())
) as s1
PIVOT (SUM(Amount) FOR ACC_0 IN ([41100],[42000],[45100],[42200],[42300],[42400],[45200],
[45205])) as pivot1
Which produces the following result set:
Month 41100 42000 45100 42200 42300 42400 45200 45205
1 3857806.91 19987.61 49876.84 49078.59 2173.63 NULL 375.00 68.52
2 4459775.79 5145.69 64442.41 58102.00 2684.40 NULL 230.00 NULL
3 4311142.03 8594.31 44220.72 33850.08 3116.75 141.00 1917.50 NULL
4 4413788.57 5613.67 58038.20 55359.25 4398.67 NULL 4796.38 132.00
5 4251083.15 4372.07 48488.03 53592.00 2869.86 127.00 110.00 128.00
6 4353075.16 9705.83 53925.37 64104.00 2304.65 2822.78 153.41 NULL
7 4549485.41 10054.92 61607.99 65136.00 1531.66 186.30 265.50 NULL
8 4239075.39 16917.10 43012.02 51591.25 1538.01 1690.91 350.00 NULL
9 4331439.41 39248.15 56368.41 74928.00 1858.82 694.32 160.00 66.00
10 3673909.02 12283.42 38928.66 28608.00 NULL NULL 120.00 NULL
I would like to get a TOTAL tally by each ROW in a column to the right. How would I accomplish this with the PIVOT syntax? I tried using a grouping sets, but it didn't work for me.
Version is SQL Server 2012.
Thanks

One simple way, would be to not use PIVOT, and instead, use the SUM aggregate with CASE expressions.
SELECT Month,
SUM(CASE WHEN ACC_0 = '41100' THEN Amount END) AS [41100],
SUM(CASE WHEN ACC_0 = '42000' THEN Amount END) AS [42000],
SUM(CASE WHEN ACC_0 = '45100' THEN Amount END) AS [45100],
SUM(CASE WHEN ACC_0 = '42200' THEN Amount END) AS [42200],
SUM(CASE WHEN ACC_0 = '42300' THEN Amount END) AS [42300],
SUM(CASE WHEN ACC_0 = '42400' THEN Amount END) AS [42400],
SUM(CASE WHEN ACC_0 = '45200' THEN Amount END) AS [45200],
SUM(CASE WHEN ACC_0 = '45205' THEN Amount END) AS [45205],
SUM(Amount) AS [Total]
FROM (SELECT ACC_0,
(CONVERT(NUMERIC(12,2),(AMTLED_0))) AS Amount,
MONTH(ACCDAT_0) AS Month
FROM x3v6.CICPROD.GACCENTRYD WITH (NOLOCK)
WHERE YEAR(ACCDAT_0) = YEAR(GETDATE())
-- only get the ACC_0 values you need so Total is correct
AND ACC_0 IN ('41100','42000','45100','42200','42300','42400','45200','45205')
) AS s1
GROUP BY Month

Related

How can I fetch total of Qty of Buy and Sale in month of July in single sql query

I want to find total buy and sell in single row for the specific month.
Below is the table
Month() function will help to group the month values.
SELECT
YEAR(TrDate) SaleYear,
MONTH(TrDate) SaleMonth,
SUM(CASE WHEN trType = 'B' THEN Qty END)) as TotalBuy,
SUM(CASE WHEN trType = 'S' THEN Qty END)) as TotalSale
FROM TableName
GROUP BY YEAR(TrDate), MONTH(TrDate)

tsql - pivot sum of employee

I have here a sample table data which i want to use pivot and make my DedCode data into column.
the AMount example is already computed to its total but how can i count the number of employee if it is same with branch,deptcode and emptype.
my sample table data.
expected output:
You can use conditional aggregation:
select branch, deptcode, emptype, sum(empcount) as empcount,
sum(case when dedcode = 'PHIC' then amount else 0 end) as phic,
sum(case when dedcode = 'SLOAN' then amount else 0 end) as sloan,
sum(case when dedcode = 'VLOAN' then amount else 0 end) as vloan
from t
group by branch, deptcode, emptype;

Query to show all months and show values where there are data for the corresponding months

I have a query and it shows the months where there is corresponding data. However, I would like to show all of the months in the year and have the months where there are no data shown as zero.
There is my SQL Statement:
SELECT DATENAME(MONTH, hb_Disputes.OPENED) AS MonthValue,
COUNT(CASE WHEN REV_CLS = 2 THEN 1 END) AS SmallCommercialIndust,
COUNT(CASE WHEN REV_CLS <> 2 THEN 1 END) AS Residential
FROM hb_Disputes
WHERE (hb_Disputes.ASSGNTO = 'E099255') AND (YEAR(hb_Disputes.OPENED) = YEAR(GETDATE()))
GROUP BY hb_Disputes.OPENED
And this is my output:
I also have a table name MonthName that shows all of the months in a year and I know I may need to use this to accomplish what I'm trying to achieve but I'm not sure how to get there:
If you have data in the table for all months, but the where clause is filtering it out, then the simplest method is to extend the conditional aggregation:
SELECT DATENAME(MONTH, d.OPENED) AS MonthValue,
SUM(CASE WHEN d.ASSGNTO = 'E099255' AND d.REV_CLS = 2 THEN 1 ELSE 0 END) AS SmallCommercialIndust,
SUM(CASE WHEN d.ASSGNTO = 'E099255' AND d.REV_CLS <> 2 THEN 1 ELSE 0 END) AS Residential
FROM hb_Disputes d
WHERE YEAR(d.OPENED) = YEAR(GETDATE())
GROUP BY DATENAME(MONTH, d.OPENED)
ORDER BY MIN(d.OPENED);
Note: This does not fix the issue in all cases. It should just be a simple way to modify your query -- and will often work.

Oracle SQL Expression to Sum Payments for Six Months based on Selected Month

Basically what I'm trying to do is calculate the average percentage of CreditPayments and the average percentage of CashPayments over a projected period (Lookback 3 months then total all paymnents of the correct type in the previous six months)
So if Average (During Correct Lookback Period) was = 75% Credit & 25% Cash then for my outstanding A/R for that month I could anticapte what % will be Credit & what % will be cash. I'd like to run it for a 12 month period with the lookback changing for each MOS.
Right now my result is always 0, which is obviously wrong. I know the initial inner query is correct; however, the problem happens when the outer query runs. I think the problem lies with the T1. MOS, which I think is limiting the results. Any help would be greatly appreciated.
SELECT
T1.Facility Facility
, T1.CustType CustType
, T1.MOS MOS
, SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.CredPmts ELSE 0 END)/SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.Charges ELSE 0 END)
, SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.CashPmts ELSE 0 END)/SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.Charges ELSE 0 END)
FROM
(
SELECT
T.FACILITY Facility
, T.CUSTTYPE CustType
, trunc(to_date(T.SERVICEDATE,'j'),'MONTH') MOS
, SUM(CASE WHEN T.TYPE = 'C' THEN T.AMOUNT ELSE 0 END) Charges
, SUM(CASE WHEN (T.TYPE IN ('P1','62','12','75','P6','23') THEN T.AMOUNT ELSE 0 END CredPmts
, SUM(CASE WHEN (T.TYPE IN ('92','57','P3','P9','26','39') THEN T.AMOUNT ELSE 0 END CashPmts
FROM TRANSTABLE T
WHERE
T.FACILITY = '123'
AND T.SERVICEDATE BETWEEN to_char(ADD_MONTHS(to_date('20120101', 'yyyymmdd'),-9), 'j') AND to_char(to_date('20121231', 'yyyymmdd'), 'j')
GROUP BY
T.FACILITY
, T.CUSTTYPE
, trunc(to_date(T.SERVICEDATE,'j'),'MONTH')
)T1
GROUP BY
T1.Facility
, T1.CustType
, T1.MOS
There are mismatched parenthesis in the CASE WHEN clause of the outer query:
WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1))
all four places. Can you check it?

SQL problem with 12 subquery

Exists such db schema:
alt text http://img156.imageshack.us/img156/9017/2706.png
I need to write query.
For every doctor i need average cost of visit by month for 2009 year.
The result is (name_of_doctor, january, febriary, ..., december)
I know how to do this with 12 subquery. Exists another more convinient way?
Try the following. You may need to modify the date functions depending on your RDBMS. I have assumed MySQL, but the rest should be universal SQL.
SELECT doctors.name, monthly.average, monthly.month
FROM doctors JOIN (
SELECT AVG(cost), MONTH(visit_date) AS month FROM visits
WHERE YEAR(visit_date) GROUP BY MONTH(visit_date)
) AS monthly ON doctors.id = visits.id_doc
Note, this may only include months for doctors that have visits. So you may need to use IFNULL or COALESCE to clean up your output.
I would just do a normal select with a GROUP BY over the month and have your UI handle displaying it as 12 columns across. If you really need to do it though, then this should work:
SELECT
D.name,
AVG(CASE WHEN MONTH(V.visit_date) = 1 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 2 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 3 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 4 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 5 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 6 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 7 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 8 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 9 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 10 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 11 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 12 THEN V.cost ELSE NULL END)
FROM
Doctors D
INNER JOIN Visits V ON
V.id_doc = D.id AND
V.visit_date BETWEEN '2009-01-01' AND '2009-12-31'
GROUP BY
D.name
ORDER BY
D.name
You might need to change the date functions based on your RDBMS. Also, you may need to fiddle with the edge cases - if your dates have a time component it won't catch rows on 12/31.
Finally, I don't know if this changes between RDBMSs and I can't test right now, but if AVG counts a NULL as 0 cost instead of discounting them then you may need to do your own averag - SUM(CASE ... cost ... 0)/SUM(CASE ... 1 ... 0). I hope that makes sense.
You can do it easily as below - but it will list each months cost in a separate line .If you want the costs on the same line you can use a pivot statement .This is for SQL 2008 if you neede pivoting we can do it.If there is a performance problem use a range scan on date rather than use datepart
select d.name,datepart(month,v.visit_date) as month,
avg(v.cost) as avgcost
from visits as v inner join
doctors as d on v.id_doc=d.id
and datepart(year,v.visit_date)=2010
group by d.name,datepart(month,v.visit_date)