Selecting SUM of specific values but not altering report - sql-server-2005

For my report I have several different product codes. These product codes make up two different sections. 5870, 5730, and 5990 are one section (top half) and 5780 and everything less than 5700 make up another section (bottom half). I already have a code that combines 5780 and everything less than 5700 and that is:
SUM(SUM(PL.OriginalQuantity_Stk)) OVER
(PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
THEN PC.ProductCategoryCode
END)
)
A sample of this output is:
Product Category Code | Weight |
5870 | 100 |
5730 | 400 |
5990 | 200 |
5780 | 50 |
1111 | 50 |
2222 | 175 |
3333 | 500 |
4444 | 125 |
5870 = 100
5730 = 400
5990 = 200
Other= 900
That code does exactly what I need it to do for that part of the report. However, that code also generates the SUM of the other product codes which is great for that part of the report but for another calculation, I only need to use the product codes 5780 and everything less than 5700.
Right now I am trying to use the code:
(CASE WHEN PC.ProductCategoryCode = 5780 OR PC.ProductCategoryCode < 5700 THEN Sum(Sum(PL.OriginalQuantity_Stk)) OVER(PARTITION BY PC.ProductCategoryCode)
ELSE 0
END)
This makes the irrelevant product code's weight equal to zero but it doesn't take the total SUM of the product code's weight I need.
An example output of what I need now is:
Product Category Code | Weight |
5870 | 100 |
5730 | 400 |
5990 | 200 |
5780 | 50 |
1111 | 50 |
2222 | 175 |
3333 | 500 |
4444 | 125 |
5870 = 0
5730 = 0
5990 = 0
Other= 900
It doesn't necessarily have to equal 0, but I only need the 900 value because I will have to use that 900 for other calculations in this report. I hope that makes sense.
Let me know if I need to clarify more.
I am using Microsoft SQL Server 2005.
Whole Code:
SET NOCOUNT ON;
DECLARE #Credits Decimal(19,8);
DECLARE #Price Decimal(19,8);
DECLARE #Labor Decimal(19,8);
DECLARE #Packaging Decimal(19,8);
DECLARE #Overhead Decimal(19,8);
SET #Credits = 41000;
SET #Price = 1.57;
SET #Labor = 0;
SET #Packaging = 0;
SET #Overhead = 0;
SELECT
CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN 'Trimmings'
WHEN [PC].[ProductCategoryCode] = 5730 THEN 'Rib Tips'
WHEN [PC].[ProductCategoryCode] = 5990 THEN 'Skins'
ELSE [PC].[Description1]
END AS [Description]
, SUM(SUM(PL.OriginalQuantity_Stk)) OVER
(PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
THEN PC.ProductCategoryCode
END)
) AS [Total Weight]
, Sum(CASE WHEN [PC].[ProductCategoryCode] <> 5870 THEN [PL].[OriginalQuantity_Stk]
WHEN [PC].[ProductCategoryCode] <> 5730 THEN [PL].[OriginalQuantity_Stk]
WHEN [PC].[ProductCategoryCode] <> 5990 THEN [PL].[OriginalQuantity_Stk]
END) AS [Weight]
, #Credits - SUM(Sum([PL].[OriginalQuantity_Stk])) OVER () AS [Shrink]
, CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / #Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
WHEN [PC].[ProductCategoryCode] = 5730 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / #Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
WHEN [PC].[ProductCategoryCode] = 5990 THEN SUM(Sum([PL].[OriginalQuantity_Stk]) / #Credits) OVER (PARTITION BY [PC].[ProductCategoryCode])
ELSE Sum([PL].[OriginalQuantity_Stk]) / #Credits
END AS [Yield]
, CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost]
WHEN [PC].[ProductCategoryCode] = 5730 THEN [ICP].[UnitCost] - 0.25
WHEN [PC].[ProductCategoryCode] = 5990 THEN [ICP].[UnitCost] * 0
ELSE [ICP].[UnitCost]
END AS [UC]
, CASE
WHEN PC.ProductCategoryCode = 5870
THEN ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / #Credits)
WHEN PC.ProductCategoryCode = 5730
THEN (ICP.UnitCost - 0.25) * (Sum(PL.OriginalQuantity_Stk) / #Credits)
WHEN PC.ProductCategoryCode = 5990
THEN (ICP.UnitCost * 0) * (Sum(PL.OriginalQuantity_Stk) / #Credits)
ELSE ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / #Credits)
END AS [Value]
, SUM(ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / #Credits)) OVER
(PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
THEN PC.ProductCategoryCode
END)
) AS [Total Value]
, (CASE WHEN PC.ProductCategoryCode = 5780 OR PC.ProductCategoryCode < 5700 THEN Sum(Sum(PL.OriginalQuantity_Stk)) OVER(PARTITION BY PC.ProductCategoryCode)
ELSE 0
END) AS [Test]
FROM (((( IC_Products [PC]
INNER JOIN DC_Transactions [DCT]
ON [PC].ProductKey = [DCT].ProductKey)
INNER JOIN AR_Customers [ARC]
ON [DCT].CustomerKey = [ARC].CustomerKey)
INNER JOIN IC_ProductLots [PL]
ON [DCT].LotKey = [PL].LotKey)
LEFT OUTER JOIN IC_ProductCosts [ICP]
ON ICP.ProductKey=PC.ProductKey and ICP.ProductCostCode=5)
WHERE
([PL].ProductionDate >= { ts '2015-07-10 00:00:00' } AND ([PL].ProductionDate <= { ts '2015-07-10 00:00:00' } OR [PL].ProductionDate Is Null))
AND ((1=1) AND [ARC].CustomerKey IN (39) )
GROUP BY
CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN 'Trimmings'
WHEN [PC].[ProductCategoryCode] = 5730 THEN 'Rib Tips'
WHEN [PC].[ProductCategoryCode] = 5990 THEN 'Skins'
ELSE [PC].[Description1]
END
, [PC].ProductCategoryCode
, [ARC].CustomerKey
, CASE WHEN [PC].[ProductCategoryCode] = 5870 THEN [ICP].[UnitCost]
WHEN [PC].[ProductCategoryCode] = 5730 THEN [ICP].[UnitCost] - 0.25
WHEN [PC].[ProductCategoryCode] = 5990 THEN [ICP].[UnitCost] * 0
ELSE [ICP].[UnitCost]
END
, [ICP].UnitCost
, [PC].ProcessCode
ORDER BY
#Credits - SUM(Sum([PL].[OriginalQuantity_Stk])) OVER ()
, SUM(SUM(PL.OriginalQuantity_Stk)) OVER
(PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
THEN PC.ProductCategoryCode
END)
)
, SUM(ICP.UnitCost * (Sum(PL.OriginalQuantity_Stk) / #Credits)) OVER
(PARTITION BY (CASE WHEN PC.ProductCategoryCode IN (5870, 5730, 5990)
THEN PC.ProductCategoryCode
END)
)

I was able to use
SUM(SUM(case when PC.ProductCategoryCode IN (5870, 5730, 5990) THEN 0 else PL.OriginalQuantity_Stk END )) OVER()
To get the value I was looking for.

Related

Group the number of clients by age in ranges ("under 30" - "30 - 39" ...) group by products they have bought using Oracle SQL

Edited !!!!
Sorry I've been explaining myself wrong. So I tried to get an output like this which groups the number of clients by age in ranges ("under 30" - "30 - 39" ...) by products.
range
product1
product2
...
productn
under 30
272(clients)
250
30 to 39
380
310
40 to 49
410
450
...
...
...
Total
...
...
...
...
I have 3 tables
| main | | products | |clients |
| -------- | |---------| |--------- |
| main_id | |prod_id | | client_id |
| client_id | |prod_cat | | birth_date|
| product_id| |... | |... |
| ... |
Products
| prod_id || prod_cat || ... |
| -------- || -------- ||---- |
| 1 || Apple || |
| 2 || Tv || |
|... || ... ||... |
and here is what I've tried
select p.prod_cat ProdCat,
count(case when age_average < 30 then 1 end) under 30,
count(case when age_average between 30 and 39 then 1 end) 30 to 39,
count(case when age_average between 40 and 49 then 1 end) 40 to 49,
count(case when age_average between 50 and 59 then 1 end) 50 to 59,
count(case when age_average > 60 then 1 end) over 60,
round((months_between(sysdate,c.birth_date)/12)) age_average
from main m
inner join clients c on m.client_id = c.client_id
inner join products p on m.prod_id = p.prod_id
group by p.prod_cat
order by age_average
I got the error
> ORA-00904: "age_average": invalid id
There's no age_average column in any of those tables, so you'll have to calculate it first, and then re-use it in the rest of the query. Or, use it directly (the calculation, I mean) in every CASE.
Also, you'll have to enclose labels into double quotes; names you used are invalid.
with temp as
(select p.prod_cat prodcat,
round(avg(months_between(sysdate,c.birth_date)/12),1) age_average
from main m
inner join clients c on m.client_id = c.client_id
inner join products p on m.prod_id = p.prod_id
group by p.prod_cat
)
select prodcat,
count(case when age_average < 30 then 1 end) "under 30",
count(case when age_average between 30 and 39 then 1 end) "30 to 39",
count(case when age_average between 40 and 49 then 1 end) "40 to 49",
count(case when age_average between 50 and 59 then 1 end) "50 to 59",
count(case when age_average > 60 then 1 end) "over 60",
max(age_average) age_average
from temp
group by rollup(prodcat);
You seem to want the counts in each age range for the products, with the products in columns and the rows being the age range.
You need to list each product (or product category) separately. The idea is:
select (case when months_between(sysdate, c.birth_date) < 30 * 12 then 'under 30'
when months_between(sysdate, c.birth_date) < 40 * 12 then '30 to 39'
when months_between(sysdate, c.birth_date) < 50 * 12 then '40 to 49'
when months_between(sysdate, c.birth_date) < 60 * 12 then '50 to 59'
else 'over 60'
end) as age_range,
sum(case when product_cat = 'product1' then 1 else 0 end) as product1,
sum(case when product_cat = 'product2' then 1 else 0 end) as product1
from main m join
clients c
on m.client_id = c.client_id join
products p
on m.prod_id = p.prod_id
group by (case when months_between(sysdate, c.birth_date) < 30 * 12 then 'under 30'
when months_between(sysdate, c.birth_date) < 40 * 12 then '30 to 39'
when months_between(sysdate, c.birth_date) < 50 * 12 then '40 to 49'
when months_between(sysdate, c.birth_date) < 60 * 12 then '50 to 59'
else 'over 60'
end)
order by max(c.birth_date) desc;
Here is my solution
select p.prod_cat
count(case when (months_between(sysdate,c.birth_date)/12) < 30 then 1 end) "under 30",
count(case when (months_between(sysdate,c.birth_date)/12) 30 and 39 then 1 end) "30 to 39",
count(case when (months_between(sysdate,c.birth_date)/12) 40 and 49 then 1 end) "40 to 49",
count(case when (months_between(sysdate,c.birth_date)/12) 50 and 59 then 1 end) "50 to 59",
count(case when (months_between(sysdate,c.birth_date)/12) > 60 then 1 end) "over 60"
from main m
inner join clients c on m.client_id = c.client_id
inner join products p on m.prod_id = p.prod_id
group by p.prod_cat

How to count records by store, day wise and in 2 hours range period with pivot table format?

I have multiple stores records with user's punch records.
I would like to create a report for each store' day-wise which 2 hours have how many employees was working?
Clock In ID Last Name First Name In time Out time
912 Bedolla Jorge 1/1/2021 7:29 1/1/2021 11:31
912 Romero Gabriel 1/1/2021 10:55 1/1/2021 14:07
912 Bedolla Jorge 1/1/2021 12:00 1/1/2021 16:07
912 Zaragoza Daniel 1/1/2021 13:06 1/1/2021 14:57
912 Thaxton Christopher 1/1/2021 14:01 1/1/2021 16:57
912 Jones Elena 1/1/2021 14:01 1/1/2021 16:35
912 Zaragoza Daniel 1/1/2021 15:12 1/1/2021 17:09
912 Jones Elena 1/1/2021 16:45 1/1/2021 18:05
912 Smith Kirsten 1/1/2021 17:30 1/1/2021 20:01
912 Zaragoza Daniel 1/1/2021 17:41 1/1/2021 21:49
Looking for a result something like below. (below result data is incorrect)
store ForDate 0-2 2-4 4-6 6-8 8-10 10-12 12-14 14-16 16-18 18-20 20-22 22-0
912 2021-01-01 0 0 0 1 0 1 2 3 3 2 3 0
912 2021-01-02 0 0 2 1 2 3 2 4 2 3 3 0
912 2021-01-03 0 0 1 1 2 2 2 2 3 0 2 0
912 2021-01-04 0 0 2 0 2 1 2 2 3 3 1 0
912 2021-01-05 0 0 2 1 1 3 4 4 2 2 1 0
912 2021-01-06 0 0 2 0 2 1 2 3 3 2 3 0
912 2021-01-07 0 0 2 1 2 1 3 4 2 2 0 0
912 2021-01-08 0 0 2 2 2 1 3 2 1 2 1 0
912 2021-01-09 0 0 1 1 0 3 1 3 2 2 3 0
912 2021-01-10 0 0 2 2 1 2 2 1 1 2 2 0
I tried to solve with below query but it's wrong and stil it's just inTime but outTime is pending.
SELECT TOP 10 store, ForDate,
ISNULL([0], 0) + ISNULL([1], 0) AS [0-1],
ISNULL([2], 0) + ISNULL([3], 0) AS [2-3],
ISNULL([4], 0) + ISNULL([5], 0) AS [4-5],
ISNULL([6], 0) + ISNULL([7], 0) AS [6-7],
ISNULL([8], 0) + ISNULL([9], 0) AS [8-9],
ISNULL([10], 0) + ISNULL([11], 0) AS [10-11],
ISNULL([12], 0) + ISNULL([13], 0) AS [12-13],
ISNULL([14], 0) + ISNULL([15], 0) AS [14-15],
ISNULL([16], 0) + ISNULL([17], 0) AS [16-17],
ISNULL([18], 0) + ISNULL([19], 0) AS [18-19],
ISNULL([20], 0) + ISNULL([21], 0) AS [20-21],
ISNULL([22], 0) + ISNULL([23], 0) AS [22-23]
FROM (
select *
from
(
select store, CAST(InTime as date) AS ForDate, DATEPART(hour,InTime) AS OnHour, COUNT(*) AS Totals
from Punches
GROUP BY store, CAST(InTime as date),
DATEPART(hour,InTime)
) src
pivot
(
sum(Totals)
for OnHour in ([0],[1], [2], [3],[4], [5], [6],[7],[8], [9], [10],[11], [12], [13],[14], [15], [16],[17],[18], [19],[20],[21], [22], [23])
) piv
) t1
order by store, ForDate
Here is SQL Fiddle with data.
https://www.db-fiddle.com/f/jo4atDmmj8cshyK1CWWo7x/2
That is insane but worth trying
SELECT storeid, ForDate,
ISNULL([0], 0) + ISNULL([1], 0) AS [0-1],
ISNULL([2], 0) + ISNULL([3], 0) AS [2-3],
ISNULL([4], 0) + ISNULL([5], 0) AS [4-5],
ISNULL([6], 0) + ISNULL([7], 0) AS [6-7],
ISNULL([8], 0) + ISNULL([9], 0) AS [8-9],
ISNULL([10], 0) + ISNULL([11], 0) AS [10-11],
ISNULL([12], 0) + ISNULL([13], 0) AS [12-13],
ISNULL([14], 0) + ISNULL([15], 0) AS [14-15],
ISNULL([16], 0) + ISNULL([17], 0) AS [16-17],
ISNULL([18], 0) + ISNULL([19], 0) AS [18-19],
ISNULL([20], 0) + ISNULL([21], 0) AS [20-21],
ISNULL([22], 0) + ISNULL([23], 0) AS [22-23]
FROM (
select *
from
(
SELECT [Dates].StoreId, [Dates].ForDate, Hours.hour OnHour, COUNT(*) Totals FROM (
SELECT storeId, CAST(InTime as date) AS ForDate FROM Punches
UNION
SELECT storeId, CAST(OutTime AS date) AS ForDate FROM Punches
) [Dates] JOIN (
SELECT * FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)) hours([hour])
) [Hours] ON 1=1
JOIN
(
SELECT * FROM dbo.Punches
) p
ON p.StoreId = [Dates].StoreId
AND (DATEADD(HOUR, [Hours].[hour], CAST([Dates].ForDate AS DATETIME)) BETWEEN CAST(p.InTime AS DATETIME) AND CAST(p.Outtime AS DATETIME))
GROUP BY [Dates].StoreId, Dates.ForDate, [hour]
) src
pivot
(
sum(Totals)
for OnHour in ([0],[1], [2], [3],[4], [5], [6],[7],[8], [9], [10],[11], [12], [13],[14], [15], [16],[17],[18], [19],[20],[21], [22], [23])
) piv
) t1
order by storeid, ForDate
Let's go a bit deeper:
I generated all possible dates by this part:
SELECT storeId, CAST(InTime as date) AS ForDate FROM Punches
UNION
SELECT storeId, CAST(OutTime AS date) AS ForDate FROM Punches
And all possible hours by doing this:
SELECT * FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)) hours([hour])
Then I joined them to find all possible date-hours.
After that, I just joined them with punches and counted the punch if the generated date-hour is between inTime and OutTime by adding this condition:
(DATEADD(HOUR, [Hours].[hour], CAST([Dates].ForDate AS DATETIME)) BETWEEN CAST(p.InTime AS DATETIME) AND CAST(p.Outtime AS DATETIME))
The rest is exactly the same as your code
You can use simple CASE statement to get what you so far try-
SELECT StoreId, CAST(InTime as Date) as ForDate,
SUM(CASE WHEN DATEPART(hour,InTime) in (0,1) THEN 1 ELSE 0 END) AS [0-1],
SUM(CASE WHEN DATEPART(hour,InTime) in (2,3) THEN 1 ELSE 0 END) AS [2-3],
SUM(CASE WHEN DATEPART(hour,InTime) in (4,5) THEN 1 ELSE 0 END) AS [4-5],
SUM(CASE WHEN DATEPART(hour,InTime) in (6,7) THEN 1 ELSE 0 END) AS [6-7],
SUM(CASE WHEN DATEPART(hour,InTime) in (8,9) THEN 1 ELSE 0 END) AS [8-9],
SUM(CASE WHEN DATEPART(hour,InTime) in (10,11) THEN 1 ELSE 0 END) AS [10-11],
SUM(CASE WHEN DATEPART(hour,InTime) in (12,13) THEN 1 ELSE 0 END) AS [12-13],
SUM(CASE WHEN DATEPART(hour,InTime) in (14,15) THEN 1 ELSE 0 END) AS [14-15],
SUM(CASE WHEN DATEPART(hour,InTime) in (16,17) THEN 1 ELSE 0 END) AS [16-17],
SUM(CASE WHEN DATEPART(hour,InTime) in (18,19) THEN 1 ELSE 0 END) AS [18-19],
SUM(CASE WHEN DATEPART(hour,InTime) in (20,21) THEN 1 ELSE 0 END) AS [20-21],
SUM(CASE WHEN DATEPART(hour,InTime) in (22,23) THEN 1 ELSE 0 END) AS [22-23]
FROM Punches
GROUP BY StoreId, CAST(InTime as Date)
And for your final result use below query:-
Select StoreId,ForDate,
SUM(CASE WHEN [0-2]>0 THEN 1 ELSE 0 END) AS [0-2],
SUM(CASE WHEN [2-4]>0 THEN 1 ELSE 0 END) AS [2-4],
SUM(CASE WHEN [4-6]>0 THEN 1 ELSE 0 END) AS [4-6],
SUM(CASE WHEN [6-8]>0 THEN 1 ELSE 0 END) AS [6-8],
SUM(CASE WHEN [8-10]>0 THEN 1 ELSE 0 END) AS [8-10],
SUM(CASE WHEN [10-12]>0 THEN 1 ELSE 0 END) AS [10-12],
SUM(CASE WHEN [12-14]>0 THEN 1 ELSE 0 END) AS [12-14],
SUM(CASE WHEN [14-16]>0 THEN 1 ELSE 0 END) AS [14-16],
SUM(CASE WHEN [16-18]>0 THEN 1 ELSE 0 END) AS [16-18],
SUM(CASE WHEN [18-20]>0 THEN 1 ELSE 0 END) AS [18-20],
SUM(CASE WHEN [20-22]>0 THEN 1 ELSE 0 END) AS [20-22],
SUM(CASE WHEN [22-24]>0 THEN 1 ELSE 0 END) AS [22-24]
from
(SELECT StoreId,FirstName+LastName as Name, CAST(InTime as Date) as ForDate,
SUM(CASE WHEN DATEPART(hour,InTime) in (0,1) OR (DATEPART(hour,InTime)<0 AND DATEPART(hour,OutTime)>=1) THEN 1 ELSE 0 END) AS [0-2],
SUM(CASE WHEN DATEPART(hour,InTime) in (2,3) OR (DATEPART(hour,InTime)<2 AND DATEPART(hour,OutTime)>=2) THEN 1 ELSE 0 END) AS [2-4],
SUM(CASE WHEN DATEPART(hour,InTime) in (4,5) OR (DATEPART(hour,InTime)<4 AND DATEPART(hour,OutTime)>=4) THEN 1 ELSE 0 END) AS [4-6],
SUM(CASE WHEN DATEPART(hour,InTime) in (6,7) OR (DATEPART(hour,InTime)<6 AND DATEPART(hour,OutTime)>=6) THEN 1 ELSE 0 END) AS [6-8],
SUM(CASE WHEN DATEPART(hour,InTime) in (8,9) OR (DATEPART(hour,InTime)<8 AND DATEPART(hour,OutTime)>=8) THEN 1 ELSE 0 END) AS [8-10],
SUM(CASE WHEN DATEPART(hour,InTime) in (10,11) OR (DATEPART(hour,InTime)<10 AND DATEPART(hour,OutTime)>=10) THEN 1 ELSE 0 END) AS [10-12],
SUM(CASE WHEN DATEPART(hour,InTime) in (12,13) OR (DATEPART(hour,InTime)<12 AND DATEPART(hour,OutTime)>=12) THEN 1 ELSE 0 END) AS [12-14],
SUM(CASE WHEN DATEPART(hour,InTime) in (14,15) OR (DATEPART(hour,InTime)<14 AND DATEPART(hour,OutTime)>=14) THEN 1 ELSE 0 END) AS [14-16],
SUM(CASE WHEN DATEPART(hour,InTime) in (16,17) OR (DATEPART(hour,InTime)<16 AND DATEPART(hour,OutTime)>=16) THEN 1 ELSE 0 END) AS [16-18],
SUM(CASE WHEN DATEPART(hour,InTime) in (18,19) OR (DATEPART(hour,InTime)<18 AND DATEPART(hour,OutTime)>=18) THEN 1 ELSE 0 END) AS [18-20],
SUM(CASE WHEN DATEPART(hour,InTime) in (20,21) OR (DATEPART(hour,InTime)<20 AND DATEPART(hour,OutTime)>=20) THEN 1 ELSE 0 END) AS [20-22],
SUM(CASE WHEN DATEPART(hour,InTime) in (22,23) OR (DATEPART(hour,InTime)<22 AND DATEPART(hour,OutTime)>=22) THEN 1 ELSE 0 END) AS [22-24]
FROM Punches
GROUP BY StoreId,FirstName+LastName,CAST(InTime as Date)) detailsQuery
GROUP BY StoreId,ForDate

Find MAX value per group in SQL pivot

I have a calculated pivot table consisting of rate names and frequency booked per age group and gender segments, for each rate name:
I want to find the rate name with the most bookings for each segment, my code so far is:
select
/* Rate name */
rt.RateName
/* frequency of rate usage per age group */
,SUM(CASE WHEN res.AgeGroup > 0 AND res.AgeGroup <= 25 THEN 1 ELSE 0 END) AS [25 and Under]
,SUM(CASE WHEN res.AgeGroup > 25 AND res.AgeGroup <= 35 THEN 1 ELSE 0 END) AS [26-35]
,SUM(CASE WHEN res.AgeGroup > 35 AND res.AgeGroup <= 45 THEN 1 ELSE 0 END) AS [36-45]
,SUM(CASE WHEN res.AgeGroup > 45 AND res.AgeGroup <= 55 THEN 1 ELSE 0 END) AS [46-55]
,SUM(CASE WHEN res.AgeGroup > 55 AND res.AgeGroup <= 65 THEN 1 ELSE 0 END) AS [56-65]
,SUM(CASE WHEN res.AgeGroup > 65 AND res.AgeGroup <= 100 THEN 1 ELSE 0 END) AS [66-100]
/* Gender */
,SUM(CASE WHEN res.Gender = 1 THEN 1 ELSE 0 END) AS [Male]
,SUM(CASE WHEN res.Gender = 2 THEN 1 ELSE 0 END) AS [Female]
,SUM(CASE WHEN res.Gender = 0 THEN 1 ELSE 0 END) AS [No Gender]
FROM reservation res join rate rt on res.RateId = rt.RateId
group by rt.RateName
What would be the most optimal way to find the rate names with the biggest number of bookings per group? or should I take a different approach altogether? Any recommendations and suggestions are be highly appreciated
Don't use columns. Aggregate into groups. However, you need a separate query for each theme. For ages:
WITH r as (
SELECT rt.RateName
(CASE WHEN res.AgeGroup > 0 AND res.AgeGroup <= 25 THEN '25 and Under'
WHEN res.AgeGroup > 25 AND res.AgeGroup <= 35 THEN '[26-35]'
WHEN res.AgeGroup > 35 AND res.AgeGroup <= 45 '[36-45]'
WHEN res.AgeGroup > 45 AND res.AgeGroup <= 55 THEN '[46-55]'
WHEN res.AgeGroup > 55 AND res.AgeGroup <= 65 THEN '[56-65]'
WHEN res.AgeGroup > 65 AND res.AgeGroup <= 100 THEN '[66-100]'
ELSE 'OTHER'
END) as agegrp,
COUNT(*) as cnt
ROW_NUMBER() OVER (PARTITION BY rt.RateName, ORDER BY COUNT(*) DESC) as seqnum
FROM reservation res JOIN
rate rt
ON res.RateId = rt.RateId
GROUP BY rt.RateName
) r
SELECT r.*
FROM r
WHERE seqnum = 1;
You can use a similar query for genders.

SQL - Calculate 2 columns and view result to another to column

Hi I have this query where I can get my customer balance to be use as reporting later. But I am kinda stuck on this part where the 2 columns should calculate and view the result to another column the harder part is they are on the different row. So here's my query
SELECT ROW_NUMBER() OVER( ORDER BY DR.id ) AS 'NO.' ,
CONVERT(VARCHAR(13), CAST(DR.doc_date AS DATE), 100) AS 'DOC DATE',
v.which AS 'DOC TYPE',
CASE WHEN
v.which IN ('NET TOTAL', 'DELL/COL/CHARGE') THEN V.val
END AS DEBIT,
CASE WHEN
v.which IN ('CDW', 'PAYMENT') THEN V.val
END AS CREDIT,
CAST(v.val AS float) + CAST(v.val AS float) AS 'BALANCE'
FROM [dbo].[doc_customer] DC
LEFT JOIN [dbo].[doc_rent] DR ON DR.doc_sourced_customer_id = DC.id
LEFT JOIN [dbo].[slip_rent] SR ON SR.doc_sourced_doc_rent_id = DR.id
LEFT JOIN [dbo].[slip_rent_payment] SP ON SP.doc_sourced_rent_id = DR.id OUTER APPLY
(VALUES ('NET TOTAL', SR.net_total),
('DELL/COL/CHARGE', SR.dell_col_charge),
('CDW', SR.CDW),
('PAYMENT', sp.amount)
) v(which, val)
WHERE DC.id = '1-1---1-1-1---1--1~1'
AND DR.deleted = 0
AND DR.void = 0
AND v.val IS NOT NULL
AND v.val <> '' ;
As u can see in my query I can get the DEBIT and CREDIT value but my problem is
on how to get total of their calculation.
My Desired Output
| NO. | DOC DATE | DOC TYPE | DEBIT | CREDIT | BALANCE
-------------------------------------------------------------
1 | 1 | Mar 28 2017 | NET TOTAL | 341 | NULL |
2 | 2 | Mar 28 2017 | PAYMENT | NULL | 4000 | -3659
3 | 3 | Oct 16 2017 | NET TOTAL | 150 | NULL | -3509
4 | 4 | Oct 16 2017 | CDW | NULL | 50 | -3559
5 | 5 | Oct 16 2017 | PAYMENT | NULL | 150 | -3709
Here's the link for my desired output sql desired output
if this is SQL Server 2012 or higher, you want ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW like this (notice you need an indexer, so I chose [No.] :
SELECT [NO.], Debit, Credit,
SUM(coalesce(Debit,0) - coalesce(Credit,0)) OVER(ORDER BY [NO.]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS BALANCE
FROM
(
SELECT ROW_NUMBER() OVER( ORDER BY DR.id ) AS 'NO.' ,
CONVERT(VARCHAR(13), CAST(DR.doc_date AS DATE), 100) AS 'DOC DATE',
v.which AS 'DOC TYPE',
CASE WHEN
v.which IN ('NET TOTAL', 'DELL/COL/CHARGE') THEN V.val
END AS DEBIT,
CASE WHEN
v.which IN ('CDW', 'PAYMENT') THEN V.val
END AS CREDIT,
CAST(v.val AS float) + CAST(v.val AS float) AS 'BALANCE'
FROM [dbo].[doc_customer] DC
LEFT JOIN [dbo].[doc_rent] DR ON DR.doc_sourced_customer_id = DC.id
LEFT JOIN [dbo].[slip_rent] SR ON SR.doc_sourced_doc_rent_id = DR.id
LEFT JOIN [dbo].[slip_rent_payment] SP ON SP.doc_sourced_rent_id = DR.id OUTER APPLY
(VALUES ('NET TOTAL', SR.net_total),
('DELL/COL/CHARGE', SR.dell_col_charge),
('CDW', SR.CDW),
('PAYMENT', sp.amount)
) v(which, val)
WHERE DC.id = '1-1---1-1-1---1--1~1'
AND DR.deleted = 0
AND DR.void = 0
AND v.val IS NOT NULL
AND v.val <> ''
) a

Query for Dedit/Credit Transactions

Here is Query I am using :
select Date2,
sum(case when Type='Debit' then Amount else 0 end)as DebitAmount,
sum(case when Type='Credit' then Amount else 0 end)as CreditAmount,
((sum(case when Type='Debit' then Amount else 0 end))-sum(case when Type='Credit' then Amount else 0 end)) as Balance
from MainTransaction
group by MainTransaction.Date2
order by Date2
OutPut :
Date | Debit | Credit | Balance
-----------+---------+--------+-----------
2015-02-10 | 0.0 | 0 | 0.0
2015-02-12 | 19200.0 | 0 | 19200.0
2015-03-01 | 62000.0 | 0 | 62000.0
2015-03-08 | 999.0 | 0 | 999.0
2015-03-09 | 10064.0 | 0 | 10064.0
What I want it to display total balance as well , I mean like date is 11.03.2015 it will also display total debit till date 11.03.2015 -credit till date 11.03.2015..
What should I do .. I simply can't do sum as I am using group by date2..
Set {0} = '2015-03-11'
select ifnull(mt.Date2, mt.Date2s),
sum(case when mt.Type='Debit' then mt.Amount else 0 end)as DebitAmount,
sum(case when mt.Type='Credit' then mt.Amount else 0 end)as CreditAmount,
((sum(case when mt.Type='Debit' then mt.Amount else 0 end))-sum(case when mt.Type ='Credit' then mt.Amount else 0 end)) as Balance
from (
select mt.*, sd.*
from MainTransaction as mt
left join
(select {0} as Date2s) as sd On mt.date2 = sd.Date2s
where mt.date2 < {0}
union all
select mt.*, sd.*
from (select {0} as Date2s) as sd
left join
MainTransaction as mt On mt.date2 = sd.Date2s
where mt.date2 is null
) as mt
group by ifnull(mt.Date2, mt.Date2s)
order by ifnull(mt.Date2, mt.Date2s)