Pivot and Sum of values in column based on specific row condition - sql

I have a sample table like this:
DaysInOp Zone_id DailyAvg RunNumber
0 9 5996.79891226986 1
0 15 0 1
0 3 12549.5152623033 1
0 12 -8400.75508952542 1
0 6 24766.7738319152 1
0 7 11737.3698582701 1
0 1 26395.0374347879 1
0 18 0.0218623184855433 1
0 10 1965.53524850589 1
0 4 9499.54051554152 1
0 13 6158.45142253444 1
Where DaysinOp could be from 0-300
and Zone ID=1-20 and DailyAvg= Variable and RunNumber =1-5
I would like output like:
Day # Run 1 Weight (lbs) Run 2 Weight (lbs) Run 3 Weight (lbs) Run 4 Weight (lbs)
0 15 5 55 1
1 17 16 612 34
2 19 55 1100 56
3 22 100 1230 456
Etc. … … … …
Where Each run weight is Sum of daily avg values of Zone ID (1-10).
Please let me know if this is possible.
I am trying pivot with sum condition? Any hints will be appreciated.

SELECT
DaysInOp,
SUM(CASE WHEN Zone_id BETWEEN 1 AND 10
AND RunNumber = 1 THEN DailyAvg END) AS Run1Weight,
SUM(CASE WHEN Zone_id BETWEEN 1 AND 10
AND RunNumber = 2 THEN DailyAvg END) AS Run2Weight,
SUM(CASE WHEN Zone_id BETWEEN 1 AND 10
AND RunNumber = 3 THEN DailyAvg END) AS Run3Weight,
SUM(CASE WHEN Zone_id BETWEEN 1 AND 10
AND RunNumber = 4 THEN DailyAvg END) AS Run4Weight,
SUM(CASE WHEN Zone_id BETWEEN 1 AND 10
AND RunNumber = 5 THEN DailyAvg END) AS Run5Weight
FROM
yourTable
GROUP BY
DaysInOp
Can be simplified by moving the Zone_id BETWEEN 1 AND 10 to a WHERE clause. If a day has no records in those zones, however, it won't appear in the results.
SELECT
DaysInOp,
SUM(CASE WHEN RunNumber = 1 THEN DailyAvg END) AS Run1Weight,
SUM(CASE WHEN RunNumber = 2 THEN DailyAvg END) AS Run2Weight,
SUM(CASE WHEN RunNumber = 3 THEN DailyAvg END) AS Run3Weight,
SUM(CASE WHEN RunNumber = 4 THEN DailyAvg END) AS Run4Weight,
SUM(CASE WHEN RunNumber = 5 THEN DailyAvg END) AS Run5Weight
FROM
yourTable
WHERE
Zone_id BETWEEN 1 AND 10
GROUP BY
DaysInOp

#MatBailie provided the manual pivot, here's the same query using the pivot operator:
with t1 as (
select DaysInOp
, case when zone_id between 1 and 10 then dailyavg end rw
, RunNumber
from table1
)
select DaysInOp [Day #]
, [1] [Run 1 Weight (lbs)]
, [2] [Run 2 Weight (lbs)]
, [3] [Run 3 Weight (lbs)]
, [4] [Run 4 Weight (lbs)]
, [5] [Run 5 Weight (lbs)]
from t1
pivot (sum(rw)
for RunNumber in ([1],[2],[3],[4],[5])) pvt

Related

How to Replace NULL Value with 0 (Zero)?

I've just got myself stuck with some SQL query and I'm quite new on this.
I'm using pivot in my query.
This is my SELECT query:
SELECT *
FROM
(SELECT lg.domainNameID AS [Domain ID], COUNT(lg.domainNameID) AS [Fix Count]
FROM tbl_ATT_Request r
INNER JOIN tbl_ATT_Login lg ON lg.workdayID = r.workdayID
WHERE r.requestCategoryID = 1
GROUP BY lg.domainNameID) slct
and this is the output:
Domain | Fix Count
-------+-----------
1 1
2 1
4 2
5 1
And this is my query with PIVOT.
SELECT *
FROM
(SELECT lg.domainNameID AS [Domain ID], COUNT(lg.domainNameID) AS [Fix Count]
FROM tbl_ATT_Request r
INNER JOIN tbl_ATT_Login lg ON lg.workdayID = r.workdayID
WHERE r.requestCategoryID = 1
GROUP BY lg.domainNameID) slct
PIVOT
(SUM(slct.[Fix Count])
FOR slct.[Domain ID] IN ([1],[2],[3],[4],[5])
) AS pvt
This is the output:
1 | 2 | 3 | 4 | 5
1 1 NULL 2 1
Now my problem is how can I replace the NULL values with 0.
Just use conditional aggregation:
SELECT SUM(CASE WHEN Domain_Id = 1 THEN Fix_Count ELSE 0 END) as d_1,
SUM(CASE WHEN Domain_Id = 2 THEN Fix_Count ELSE 0 END) as d_2,
SUM(CASE WHEN Domain_Id = 3 THEN Fix_Count ELSE 0 END) as d_3,
SUM(CASE WHEN Domain_Id = 4 THEN Fix_Count ELSE 0 END) as d_4,
SUM(CASE WHEN Domain_Id = 5 THEN Fix_Count ELSE 0 END) as d_5
FROM (SELECT lg.domainNameID AS Domain_ID, COUNT(*) AS Fix_Count
FROM tbl_ATT_Request r JOIN
tbl_ATT_Login lg
ON lg.workdayID = r.workdayID
WHERE r.requestCategoryID = 1
GROUP BY lg.domainNameID
) d

How I can convert those colum to row?

after convert, it should be
month 1 2 3 4 5 6 7 8 9 10 11 12
planqty 0 0 6230 0 0 0 0 0 0 0 0 0
actqty 0 0 2631 0 0 0 0 0 0 0 0 0
I will be so appreciated if you can help.
You want APPLY (i.e. CROSS APPLY) in order to convert columns to row wise.
select
qtynames as Month,
max(case when dt = '01' then qty end) [01],
max(case when dt = '02' then qty end) [02],
max(case when dt = '03' then qty end) [03],...
from table t cross apply (
values ('month', dt, 'planqty', planqty), ('month', dt, 'actqty', actqty)
)a(mnames, dates, qtynames, qty)
group by qtynames

SQL Calculations based by field type and group by the type

Database includes FamID, TicketType and Amt
I want to get a calculation for total amount for each tickettype for each family and sort by family high to low based on total for all tickettypes.
Database values are:
FamID TicketType Amt
1 1 10
1 1 10
1 2 20
1 3 30
2 2 20
2 1 10
2 1 10
2 1 10
2 3 30
3 3 30
3 3 30
3 3 30
Would like results to be
Family Type 1 Type 2 Type 3 Total
3 0 0 90 90
2 30 20 30 80
1 20 20 30 70
Am I trying to do too much?
You never specified your RDBMS, but the following pivot query should work across most major ones with little modification:
SELECT t.`Type 1`, t.`Type 2`, t.`Type 3`,
(t.`Type 1` + t.`Type 2` + 2*t.`Type 3`) AS Total
FROM
(
SELECT FamID AS Family,
SUM(CASE WHEN TicketType = 1 THEN Amt ELSE 0 END) AS `Type 1`,
SUM(CASE WHEN TicketType = 2 THEN Amt ELSE 0 END) AS `Type 2`,
SUM(CASE WHEN TicketType = 3 THEN Amt ELSE 0 END) AS `Type 3`,
FROM Tickets
GROUP BY FamID
) t
ORDER BY t.Total DESC

How to turn repeated ranking(1-5) row data to column data in TSQL

I have a table data:
ID Sale Weekday
1 12 1
2 15 2
3 16 3
4 17 4
5 18 5
6 11 1
7 13 2
8 14 3
9 15 4
10 20 5
11 25 1
12 14 2
13 18 3
14 21 4
15 11 5
.. ..
I'd like to turn it into:
Mo Tu We Th Fr
12 15 16 17 18
11 13 14 15 20
25 14 18 21 11
..
Thank you!
Try this
SELECT SUM(case when Weekday = 1 then Sale else 0 end) as mn,
SUM(case when Weekday = 2 then Sale else 0 end) as Tu,
SUM(case when Weekday = 3 then Sale else 0 end) as We,
SUM(case when Weekday = 4 then Sale else 0 end) as Th,
SUM(case when Weekday = 5 then Sale else 0 end) as Fr
FROM
(
SELECT *,
Row_number()OVER(partition by weekday ORDER BY ID ) as seq_no
FROM tablename
) A
Group by seq_no
As mentioned in sample data if your table has all 5 days for all the week
SELECT SUM(case when Weekday = 1 then Sale else 0 end) as mn,
SUM(case when Weekday = 2 then Sale else 0 end) as Tu,
SUM(case when Weekday = 3 then Sale else 0 end) as We,
SUM(case when Weekday = 4 then Sale else 0 end) as Th,
SUM(case when Weekday = 5 then Sale else 0 end) as Fr
FROM
(
SELECT *,
( ( Row_number()OVER(ORDER BY ID ) - 1 ) / 5 ) + 1 seq_no
FROM tablename
) A
Group by seq_no
SQL FIDDLE DEMO
You could use the pivot operator together with a partitioned row_number like this:
select
max([1]) as 'Mo',
max([2]) as 'Tu',
max([3]) as 'We',
max([4]) as 'Th',
max([5]) as 'Fr'
from
(
select *, row_number() over (partition by weekday order by id) rn
from your_table
) a
pivot (max(sale) for weekday in ([1],[2],[3],[4],[5])) p
group by rn;

Group by in Subquery

I have a table AssignmentMaster in that I have following columns with data
AssignmentID PaidAmount RefundAmount UserID
1 20 0 1
2 10 5 1
3 30 7 2
4 25 0 3
5 35 15 3
6 10 3 1
7 5 0 3
8 10 0 3
Now I want to find out the TotalNumberofAssignment with respect to userID, i.e. result should be:
UserID TotalAssignment TotalAssignmentofRefundAmount TotalPaidAmount TotalRefundAmount
1 3 2 40 8
2 1 1 30 7
3 4 1 75 15
How I can get above given result in MSSQL.
your any help will help me lot.
SELECT
UserID,
COUNT(AssignmentID) AS TotalAssignment,
SUM(SIGN(RefundAmount)) AS TotalAssignmentofRefundAmount,
SUM(PaidAmount) AS TotalPaidAmount,
SUM(RefundAmount) AS TotalRefundAmount
FROM
MyTable
GROUP BY
UserID
Note:
SIGN(RefundAmount) works if RefundAmount is always >= 0.
If not, change to
SUM(CASE WHEN RefundAmount <> 0 THEN 1 ELSE 0 END) AS TotalAssignmentofRefundAmount
Select UserID,
count(1) as TotalAssignment,
sum( case when RefundAmount = 0 then 0 else 1 end) as TotalAssignmentofRefundAmount,
sum(PaidAmount) as TotalPaidAmount ,
sum(RefundAmount) as TotalRefundAmount
From AssignmentMaster
Group by UserID
To show how to do this using nested SQL:
Select UserTotals.UserID, UserTotals.TotalAssignment,
Refunds.TotalAssignmentofRefundAmount,
UserTotals.TotalPaidAmount, UserTotals.TotalRefundAmount
From (select UserID,
Count(AssignmentID) [TotalAssignment],
Sum(PaidAmount) [TotalPaidAmount],
sum(RefundAmount) [TotalRefundAmount]
From #AssignmentMaster
Group By UserID
) [UserTotals] Left Join
(Select UserID,
Count(AssignmentID) [TotalAssignmentofRefundAmount]
From #AssignmentMaster
Where RefundAmount > 0
Group By UserID
) [Refunds] On Refunds.UserID = UserTotals.UserID
select UserId, count (AssignmentID) as TotalAssignment,
sum(case when RefundAmount = 0 then 0 else 1 end) as TotalAssignmentofRefundAmount,
sum(PaidAmount) as TotalPaidAmound,
sum(RefundAmount) as TotalRefundAmount
from AssignmentMaster
group by UserID;