I have a Query that gives me the correct information, However the Data is not displaying Grouped and Summed, Possibly due to the joins and construction.
However if i change the order, then i end up with duplicated values because of the last Join Table having multiple lines. benefitdistribution, There is multiple values per PLU
This query provides me with the correct results, How would i go about Summing the output of this query without creating a view and then summing the view?
SELECT dbo.plumovement.deptno,
dbo.departmentdata.NAME AS DeptName,
dbo.groupdata.no AS GroupNo,
dbo.groupdata.NAME AS GroupName,
Sum(dbo.plumovement.qty) AS SalesQty,
Sum(dbo.plumovement.value) AS SalesValue,
Sum(dbo.plumovement.netvalue) AS NetValue,
Sum(dbo.plumovement.cost) AS Cost,
Sum(dbo.plumovement.vatvalue) AS VatValue,
Max(dbo.departmentdata.targetgp) AS TargetGP,
-- isNull(DistributionTotals.discountno, - 1) AS DiscountNo,
isNull(DistributionTotals.DiscountQty, 0) AS BenefitQty,
isNull(DistributionTotals.DiscountValue, 0) AS DiscountValue,
CASE
WHEN Sum(plumovement.cost) = 0 THEN 100
ELSE
(
( ( Sum(plumovement.netvalue) ) + ( Sum(plumovement.cost) ) ) / ( Sum(plumovement.netvalue) ) * 100 )
END AS [GP]
FROM dbo.plumovement
LEFT OUTER JOIN dbo.departmentdata
ON dbo.plumovement.deptno = dbo.departmentdata.no
LEFT OUTER JOIN dbo.groupdata
ON dbo.departmentdata.parentgroup = dbo.groupdata.no
LEFT OUTER JOIN (SELECT txnid,
pluno,
-- discountno,
Sum(qty) AS DiscountQty,
Sum(value) AS DiscountValue
FROM dbo.benefitdistribution
GROUP BY txnid,
pluno,
discountno) AS DistributionTotals
ON DistributionTotals.txnid = plumovement.txnid
AND DistributionTotals.pluno = plumovement.pluno
WHERE ( dbo.plumovement.movetype = 0 )
AND ( dbo.plumovement.termno > 0 )
AND ( dbo.plumovement.consolidatedtermno = 0 )
AND ( dbo.plumovement.processed = 1 )
AND ( plumovement.date BETWEEN '2022-10-01' AND '2022-11-01' )
GROUP BY dbo.groupdata.no,
dbo.groupdata.NAME,
dbo.plumovement.deptno,
dbo.departmentdata.NAME,
DistributionTotals.DiscountQty,
DistributionTotals.DiscountValue
Out putted results:
deptno
DeptName
GroupNo
GroupName
SalesQty
SalesValue
NetValue
Cost
VatValue
TargetGP
BenefitQty
DiscountValue
GP
1
Draught Beer + Cider
1
DRINK
-16
164.9
137.4167
-15.191
27.4833
40
0
0
88.94
1
Draught Beer + Cider
1
DRINK
-1
4.3373
3.6144
-0.8682
0.7229
40
1
0.1627
75.97
1
Draught Beer + Cider
1
DRINK
-6
25.65
21.375
-5.2092
4.275
40
2
0.45
75.62
1
Draught Beer + Cider
1
DRINK
-1
3.2442
2.7035
-0.8682
0.5407
40
2
1.2558
67.88
1
Draught Beer + Cider
1
DRINK
-4
7
5.8334
-5.1318
1.1666
40
2
3.5
12.02
1
Draught Beer + Cider
1
DRINK
-4
17.1
14.25
-3.4728
2.85
40
4
0.9
75.62
1
Draught Beer + Cider
1
DRINK
-4
7
5.8333
-5.1318
1.1667
40
4
7
12.02
9
Red Wine
1
DRINK
-1
-16.45
-13.7083
-1.4532
-2.7417
20
1
22
110.6
10
Rose Wine
1
DRINK
-1
3.55
2.9583
-0.7351
0.5917
45
0
0
75.15
10
Rose Wine
1
DRINK
-1
4.5058
3.7548
-1.4699
0.751
45
2
1.7442
60.85
To confirm there should be 1 line for each unique DeptNo for example
deptno
DeptName
GroupNo
GroupName
SalesQty
SalesValue
NetValue
Cost
VatValue
TargetGP
BenefitQty
DiscountValue
GP
1
Draught Beer + Cider
1
DRINK
-36
229.2315
191.0263
-35.873
38.2052
80
15
13.2685
79.00
The TargetGP does not need summing as this is just one value of the the "departmentdata.targetgp" as shown in the example.
The GP However needs to be calculated from the outputted summed results.
As it should be around 75-80 of the top of my head
Use a CTE:
with cte as (
SELECT dbo.plumovement.deptno,
dbo.departmentdata.NAME AS DeptName,
dbo.groupdata.no AS GroupNo,
dbo.groupdata.NAME AS GroupName,
Sum(dbo.plumovement.qty) AS SalesQty,
Sum(dbo.plumovement.value) AS SalesValue,
Sum(dbo.plumovement.netvalue) AS NetValue,
Sum(dbo.plumovement.cost) AS Cost,
Sum(dbo.plumovement.vatvalue) AS VatValue,
Max(dbo.departmentdata.targetgp) AS TargetGP,
-- isNull(DistributionTotals.discountno, - 1) AS DiscountNo,
isNull(DistributionTotals.DiscountQty, 0) AS BenefitQty,
isNull(DistributionTotals.DiscountValue, 0) AS DiscountValue,
CASE
WHEN Sum(plumovement.cost) = 0 THEN 100
ELSE
(
( ( Sum(plumovement.netvalue) ) + ( Sum(plumovement.cost) ) ) / ( Sum(plumovement.netvalue) ) * 100 )
END AS [GP]
FROM dbo.plumovement
LEFT OUTER JOIN dbo.departmentdata
ON dbo.plumovement.deptno = dbo.departmentdata.no
LEFT OUTER JOIN dbo.groupdata
ON dbo.departmentdata.parentgroup = dbo.groupdata.no
LEFT OUTER JOIN (SELECT txnid,
pluno,
-- discountno,
Sum(qty) AS DiscountQty,
Sum(value) AS DiscountValue
FROM dbo.benefitdistribution
GROUP BY txnid,
pluno,
discountno) AS DistributionTotals
ON DistributionTotals.txnid = plumovement.txnid
AND DistributionTotals.pluno = plumovement.pluno
WHERE ( dbo.plumovement.movetype = 0 )
AND ( dbo.plumovement.termno > 0 )
AND ( dbo.plumovement.consolidatedtermno = 0 )
AND ( dbo.plumovement.processed = 1 )
AND ( plumovement.date BETWEEN '2022-10-01' AND '2022-11-01' )
GROUP BY dbo.groupdata.no,
dbo.groupdata.NAME,
dbo.plumovement.deptno,
dbo.departmentdata.NAME,
DistributionTotals.DiscountQty,
DistributionTotals.DiscountValue
)
select
deptno,
DeptName,
GroupNo,
GroupName,
sum(SalesQty) as SalesQty,
sum(SalesValue) as SalesValue,
sum(NetValue) as NetValue,
sum(Cost) as Cost,
sum(VatValue) as VatValue,
sum(TargetGP) as TargetGP,
sum(DiscountNo) as DiscountNo,
sum(BenefitQty) as BenefitQty,
sum(DiscountValue) as DiscountValue,
sum(GP) as GP
from cte
group by deptno, DeptName, GroupNo, GroupName
Related
I am trying to write an SQL query that displays the course popularity,
in descending order.
Course popularity is measured in points, which determined as follows: For every survey:
a. if the votes difference > 10% of total votes, the more popular course gets 1 point, and the less popular course gets 0 points
b. if the votes difference <= 10% of total votes, each course gets 0.5
point
course_id
course_name
faculty
1001
economics_101
business
1002
algebra_101
math
1003
geometry_101
math
1004
management_101
business
1005
marketing_101
business
1006
physics_101
science
survey_id
option_a
option_b
votes_a
votes_b
2001
economics_101
geometry_101
61
34
2002
algebra_101
economics_101
31
68
2003
marketing_101
management_101
11
72
2005
management_101
algebra_101
43
54
2004
geometry_101
marketing_101
48
46
Result achieved so far:
course
popularity
economics_101
4
management_101
2
algebra_101
2
marketing_101
1
geometry_101
1
[NULL]
0
I managed to join it so far, would be great to have inputs on optimizing this query:
WITH x AS
(
WITH b AS
(
WITH a as
(
select * from course c
LEFT JOIN survey s
on c.course_name = s.option_a
UNION ALL
select * from course c
LEFT JOIN survey s
on c.course_name = s.option_b
)
SELECT a.*,
SUM(votes_a+votes_b) as total_votes,
CASE WHEN (a.votes_a - a.votes_b) > (0.1*SUM(votes_a+votes_b)) THEN 1
WHEN (a.votes_b - a.votes_a) <= (0.1*SUM(votes_a+votes_b)) THEN 0.5
ELSE 0
END AS 'Popularity_a',
CASE WHEN (a.votes_b - a.votes_a) > (0.1*SUM(votes_a+votes_b)) THEN 1
WHEN (a.votes_a - a.votes_b) <= (0.1*SUM(votes_a+votes_b)) THEN 0.5
ELSE 0
END AS 'Popularity_b'
FROM
a
GROUP BY
a.course_name ,
a.course_id,
a.faculty ,
a.survey_id ,
a.option_a ,
a.option_b ,
a.votes_a ,
a.votes_b
)
SELECT b.option_a as course,
b.Popularity_a as pop
FROM b
LEFT JOIN
course cx
ON b.option_a = cx.course_name
UNION ALL
SELECT b.option_b as course ,
b.Popularity_b as pop
FROM b
LEFT JOIN
course cx
ON b.option_b = cx.course_name
)
select
x.course ,
sum (x.pop) as popularity
from x
GROUP BY
x.course
order by popularity desc
Use UNION ALL to extract all courses and the respective points they get from the table survey and aggregate to get the popularity.
Then join to course:
WITH
cte AS (
SELECT option_a course_name,
CASE
WHEN votes_a - votes_b > 0.1 * (votes_a + votes_b) THEN 1.0
WHEN votes_b - votes_a > 0.1 * (votes_a + votes_b) THEN 0.0
ELSE 0.5
END points
FROM survey
UNION ALL
SELECT option_b,
CASE
WHEN votes_b - votes_a > 0.1 * (votes_a + votes_b) THEN 1.0
WHEN votes_a - votes_b > 0.1 * (votes_a + votes_b) THEN 0.0
ELSE 0.5
END
FROM survey
),
points AS (
SELECT course_name, SUM(points) total_points
FROM cte
GROUP BY course_name
)
SELECT c.*, COALESCE(p.total_points, 0) popularity
FROM course c LEFT JOIN points p
ON p.course_name = c.course_name
ORDER BY popularity DESC;
See the demo.
I have got one problem as follows:
ID NAME AMOUNT PARENTID
1 Adam 1000 0
2 John 2000 1
3 Clark 1500 2
4 Rita 1200 3
5 jack 1600 3
6 mark 1800 2
7 Finn 1500 6
8 Ryan 1100 6
So the data above is the result of a query with multiple joins
and it is a kind of hierarchy or tree something like this:
1
|
2
/ \
3 6
/ \ / \
5 4 7 8
and now I need to modify my query so that I get the following result
ID NAME AMOUNT PARENTID DownstreamSum
1 Adam 1000 0 10700
2 John 2000 1 8700
3 Clark 1500 2 2800
4 Rita 1200 3 0
5 jack 1600 3 0
6 mark 1800 2 2600
7 Finn 1500 6 0
8 Ryan 1100 6 0
So the logic is that the parent should have the sum of all the downstream child nodes in the DownstreamSum column.
for example:
id 6 should have the sum of amount of id 7 and 8
id 3 should have the sum of amount of id 4 and 5
but id 2 should have the sum of the amount of id 3 and the sum of amount of id 4 and 5
I tried with many possibilities with partition by and group by but I was not able to get the desired output.
Here is the query, please check.
SQL fiddle link
SELECT Y.*, X.TOTAL_AMOUNT FROM (
WITH hierarchy (PARENTID, ID) AS (SELECT PARENTID, ID
FROM Hierarchy_result
UNION ALL
SELECT h.PARENTID, bs.ID
FROM Hierarchy_result bs, hierarchy h WHERE bs.PARENTID=h.ID)
SELECT h.PARENTID AS PARENTID,
--SUM(FR.AMOUNT)
/*SUM((CASE WHEN FR.ID=h.PARENTID
THEN FR.amount
ELSE 0.0 END))*/
SUM(FR.amount) TOTAL_AMOUNT
FROM hierarchy h, Hierarchy_result FR WHERE FR.ID=h.ID
GROUP BY h.PARENTID
ORDER BY h.PARENTID) X, Hierarchy_result Y WHERE X.PARENTID(+) = Y.ID ORDER BY Y.ID;
A typical recursive CTE (available since Oracle 11gR2) will allow you to walk the branches to the leaves. Then a simple SUM() gives you the result you want. For example:
with
n (root_id, current_id, name, amount, parentid) as (
select id, id, name, amount, parentid from t
union all
select n.root_id, t.id, t.name, t.amount, t.parentid
from n
join t on t.parentid = n.current_id
)
select t.id, t.name, t.amount, t.parentid,
sum(n.amount) - t.amount as downstreamsum
from t
join n on n.root_id = t.id
group by t.id, t.name, t.amount, t.parentid
order by t.id
Result:
ID NAME AMOUNT PARENTID DOWNSTREAMSUM
--- ------ ------- --------- -------------
1 Adam 1000 0 10700
2 John 2000 1 8700
3 Clark 1500 2 2800
4 Rita 1200 3 0
5 jack 1600 3 0
6 mark 1800 2 2600
7 Finn 1500 6 0
8 Ryan 1100 6 0
See running example at db<>fiddle.
This query also calculates own and child sums and count:
with mcnt (
id, parentid, name, amount
,rnk
,level_members_cnt
,level_members_sum
,own_members_cnt
,own_members_sum
,child_members_cnt
,child_members_sum
) as (
select
p.id, p.parentid, p.name, p.amount
, row_number()over(partition by p.parentid order by p.id) rnk
, sum((select count(*) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) as level_members_cnt
, sum((select sum(m.amount) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) as level_members_sum
, (select count(*) from Hierarchy_result m where m.parentid=p.id) as own_members_cnt
, (select nvl(sum(m.amount),0) from Hierarchy_result m where m.parentid=p.id) as own_members_sum
, 0 as child_members_cnt
, 0 as child_members_sum
from Hierarchy_result p
where not exists(select null from Hierarchy_result child where p.id = child.parentid)
union all
select p.id, p.parentid, p.name, p.amount
, row_number()over(partition by p.parentid order by p.id) rnk
, sum((select count(*) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) level_members_cnt
, sum((select sum(m.amount) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) level_members_sum
, (select count(*) from Hierarchy_result m where m.parentid=p.id) as own_members_cnt
, (select nvl(sum(m.amount),0) from Hierarchy_result m where m.parentid=p.id) as own_members_sum
, mcnt.level_members_cnt + mcnt.child_members_cnt as child_members_cnt
, nvl(mcnt.level_members_sum,0) + nvl(mcnt.child_members_sum,0) as child_members_sum
from mcnt, Hierarchy_result p
where mcnt.parentid=p.id
and mcnt.rnk=1
)
select
id, parentid, name, amount, child_members_cnt, own_members_cnt
,child_members_cnt+own_members_cnt as total_cnt
,child_members_sum,own_members_sum
,child_members_sum+own_members_sum as total_sum
from mcnt
order by id;
Full example with sample data:
with Hierarchy_result ("ID", "NAME", "AMOUNT", "PARENTID") as (
select 1, 'Adam', 1000, 0 from dual union all
select 2, 'John', 2000, 1 from dual union all
select 3, 'Clark', 1500, 2 from dual union all
select 4, 'Rita', 1200, 3 from dual union all
select 5, 'jack', 1600, 3 from dual union all
select 6, 'mark', 1800, 2 from dual union all
select 7, 'Finn', 1500, 6 from dual union all
select 8, 'Ryan', 1100, 6 from dual
)
,mcnt (
id, parentid, name, amount
,rnk
,level_members_cnt
,level_members_sum
,own_members_cnt
,own_members_sum
,child_members_cnt
,child_members_sum
) as (
select
p.id, p.parentid, p.name, p.amount
, row_number()over(partition by p.parentid order by p.id) rnk
, sum((select count(*) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) as level_members_cnt
, sum((select sum(m.amount) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) as level_members_sum
, (select count(*) from Hierarchy_result m where m.parentid=p.id) as own_members_cnt
, (select nvl(sum(m.amount),0) from Hierarchy_result m where m.parentid=p.id) as own_members_sum
, 0 as child_members_cnt
, 0 as child_members_sum
from Hierarchy_result p
where not exists(select null from Hierarchy_result child where p.id = child.parentid)
union all
select p.id, p.parentid, p.name, p.amount
, row_number()over(partition by p.parentid order by p.id) rnk
, sum((select count(*) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) level_members_cnt
, sum((select sum(m.amount) from Hierarchy_result m where m.parentid=p.id))over(partition by p.parentid) level_members_sum
, (select count(*) from Hierarchy_result m where m.parentid=p.id) as own_members_cnt
, (select nvl(sum(m.amount),0) from Hierarchy_result m where m.parentid=p.id) as own_members_sum
, mcnt.level_members_cnt + mcnt.child_members_cnt as child_members_cnt
, nvl(mcnt.level_members_sum,0) + nvl(mcnt.child_members_sum,0) as child_members_sum
from mcnt, Hierarchy_result p
where mcnt.parentid=p.id
and mcnt.rnk=1
)
select
id, parentid, name, amount, child_members_cnt, own_members_cnt
,child_members_cnt+own_members_cnt as total_cnt
,child_members_sum,own_members_sum
,child_members_sum+own_members_sum as total_sum
from mcnt
order by id;
Result
ID PARENTID NAME CHILD_MEMBERS_SUM OWN_MEMBERS_SUM TOTAL_SUM CHILD_MEMBERS_CNT OWN_MEMBERS_CNT TOTAL_CNT
--- -------- ----- ----------------- --------------- ---------- ----------------- --------------- ----------
1 0 Adam 8700 2000 10700 6 1 7
2 1 John 5400 3300 8700 4 2 6
3 2 Clark 0 2800 2800 0 2 2
4 3 Rita 0 0 0 0 0 0
5 3 jack 0 0 0 0 0 0
6 2 mark 0 2600 2600 0 2 2
7 6 Finn 0 0 0 0 0 0
8 6 Ryan 0 0 0 0 0 0
ps. based on my another solution: Hierarchical Query - Counting records that belongs to Parent and Child Places
I have a data set that looks like:
cust city hotel_id amount
-------------------------------
A 1 252 3160
B 1 256 1893
C 2 105 2188
D 2 105 3054
E 3 370 6107
F 2 110 3160
G 2 150 1893
H 3 310 2188
I 1 252 3160
J 1 250 4000
K 3 370 5000
L 3 311 1095
Query to display the top 3 hotels by revenue (Sum of amount) for each city?
Since same hotel can be booked by other customer in same city so we need to sum the amount to find total amount.
Expected output:
city hotel_id amount
---------------------------
1 252 6320
1 250 4000
1 256 1893
2 105 5242
2 110 3160
2 150 1893
3 370 11107
3 310 2188
3 311 1095
SELECT
t.city, t.hotel_id, t.amount
FROM
(
SELECT city, hotel_id, SUM(amount) AS amount,
ROW_NUMBER() OVER (PARTITION BY city ORDER BY SUM(amount) DESC) AS rn
FROM yourTable
GROUP BY city, hotel_id
) t
WHERE t.rn <= 3
ORDER BY t.city, t.amount DESC;
Demo here:
Rextester
To get the total sum for each hotel_id you need to group by that column first, then group by the city for syntax purposes. The #tmp table here should have all of the data you need, so then you just have to select the top 3 entries for each city from there.
SELECT city, hotel_id, SUM(amount) AS 'total' INTO #tmp
FROM [table]
GROUP BY hotel_id, city
(SELECT TOP 3 *
FROM #tmp
WHERE city = 1)
UNION
(SELECT TOP 3 *
FROM #tmp
WHERE city = 2)
UNION
(SELECT TOP 3 *
FROM #tmp
WHERE city = 3)
I am trying to achieve a running deductive total, but the problem occurs when I have a zero row. I am using SQL Server 2012.
Here's a batch of my current results.
SuppressionDescription SuppressionPriority SuppressionPriorityOrder TotalRecords RecordsLost RunningTotal
Deceased_Bln 1 1 1376 2 1374
Pivotal Postcode Exclusions 9 2 1376 0 1374
Pivotal 3 Month Decline 11 3 1376 24 1352
Postcode exclusions (Complaints) 12 4 1376 0 1352
Gone Away (from Barcode on returned mail) 15 5 1376 30 1346
Pivotal prospects with a Do Not Mail flag 16 6 1376 234 1112
Email Suppression File 17 7 1376 7 1135
Opt outs & undeliverables from SMS system 18 8 1376 7 1362
Generic Phone Number Suppression 19 9 1376 245 1124
Exclude if not MR, MRS, MISS, MS, NULL 23 10 1376 0 1131
Total Prospects 9999 11 1376 0 1376
With my query, the first two rows calculate. A total of 1,376 less 2 leaves 1,374 and the second row has no RecordsLost, so the RunningTotal remains the same. So far so good.
But because Row 2 has a 0 count, it means row 3 (whilst it has a RecordsLost of 24) gets out of sync.
I've tried adding various case statements, to try and get totals for different scenario's, but it never quite works.
Here is my statement:
;WITH CTE AS (SELECT ID, SuppressionTypeID, ContactMethodType, SupplierName, SuppressionDescription
, SuppressionCount, TotalRecords, RecordsLost, SuppressionPriority, SuppressionPriorityOrder
, CASE WHEN SuppressionPriority = 9999
THEN TotalRecords
ELSE TotalRecords - RecordsLost END AS RowDiff
, CASE WHEN RecordsLost = 0
THEN LAG(RecordsLost, 1) OVER (PARTITION BY SupplierName, ContactMethodType ORDER BY SuppressionPriorityOrder)
ELSE RecordsLost END AS RecordsLostRoll
FROM #tmpSup
WHERE SupplierName = 'Freeman Grattan Holdings'
AND ContactMethodType = 'A'
)
SELECT SuppressionTypeID, ContactMethodType, SupplierName, SuppressionDescription
, SuppressionPriority, SuppressionPriorityOrder
, TotalRecords
, RecordsLost
, CASE WHEN SuppressionPriorityOrder = 1
THEN RowDiff
ELSE (LAG(RowDiff, 1, RowDiff)
OVER (PARTITION BY SupplierName, ContactMethodType ORDER BY SuppressionPriorityOrder)) - RecordsLost
END AS RunningTotal
FROM CTE
ORDER BY SupplierName
, ContactMethodType
, SuppressionPriority
I'd like to see the RunningTotal as:
1374
1374
1350
1350
1320
1086
1079
1072
827
827
1376 (for total Prospects)
Any suggestions and thanks in advance.
You can use a 'window frame' in the windowed function to achieve this:
SELECT
SuppressionPriorityOrder,
TotalRecords,
RecordsLost,
TotalRecords - SUM(RecordsLost) OVER
(
PARTITION BY SupplierName, ContactMethodType
ORDER BY SuppressionPriorityOrder ROWS UNBOUNDED PRECEDING -- this tells the SUM() to add up all preceding records (including the current row)
) RunningTotal
FROM
(
SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 1 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 2 AS RecordsLost UNION ALL
SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 2 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 0 AS RecordsLost UNION ALL
SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 3 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 24 AS RecordsLost UNION ALL
SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 4 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 0 AS RecordsLost UNION ALL
SELECT 'Freeman Grattan Holdings' AS SupplierName, 'A' AS ContactMethodType, 5 AS SuppressionPriorityOrder, 1376 AS TotalRecords, 30 AS RecordsLost
) x
Reference: link.
I try to simulate the best I could your data. Let me know if you need some changes on the sqlFiddle
SQL FIDDLE DEMO
I use another CTE to calculate the sum of lost records
WITH
LOST AS (
SELECT
SuppressionPriorityOrder,
(SELECT SUM(RecordsLost)
FROM tmpSup T2
WHERE T2.SuppressionPriorityOrder <= T1.SuppressionPriorityOrder) as TotalLost
FROM tmpSup T1
)
SELECT
T.*,
L.TotalLost,
CASE WHEN SuppressionPriority = 9999
THEN T.TotalRecords
ELSE (T.TotalRecords - L.TotalLost) END AS RunningTotal
FROM
tmpSup T INNER JOIN
LOST L ON T.SuppressionPriorityOrder = L.SuppressionPriorityOrder
Basically i have the following query and i am trying to distinguish only the unique ranks from this:
WITH numbered_rows
as (
SELECT Claim,
reserve,
time,
RANK() OVER (PARTITION BY ClaimNumber ORDER BY time asc) as 'Rank'
FROM (
SELECT cc.Claim,
MAX(csd.time) as time,
csd.reserve
FROM ClaimData csd WITH (NOLOCK)
JOIN Core cc WITH (NOLOCK)
on cc.ClaimID = csd.ClaimID
GROUP BY cc.Claim, csd.Reserve
) as t
)
select *
from numbered_rows cur, numbered_rows prev
where cur.Claim= prev.Claim
and cur.Rank = prev.Rank -1
The results set I get is the following:
Claim reserve Time Rank Claim reserve Time Rank
--------------------------------------------------------------------
11 0 12/10/2012 1 11 15000 5/30/2013 2
34 2000 1/21/2013 1 34 750 1/31/2013 2
34 750 1/31/2013 2 34 0 3/31/2013 3
07 800000 5/9/2013 1 07 0 5/10/2013 2
But what I only want to see the following: (have the Claim 34 Rank 2 removed because its not the highest
Claim reserve Time Rank Claim reserve Time Rank
--------------------------------------------------------------------
11 0 12/10/2012 1 11 15000 5/30/2013 2
34 750 1/31/2013 2 34 0 3/31/2013 3
07 800000 5/9/2013 1 07 0 5/10/2013 2
I think you can do this by just reversing your logic, i.e. order by time DESC, switching cur and prev in your final select and changing -1 to +1 in your final select, then just limiting prev.rank to 1, therefore ensuring that the you only include the latest 2 results for each claim:
WITH numbered_rows AS
( SELECT Claim,
reserve,
time,
[Rank] = RANK() OVER (PARTITION BY ClaimNumber ORDER BY time DESC)
FROM ( SELECT cc.Claim,
[Time] = MAX(csd.time),
csd.reserve
FROM ClaimData AS csd WITH (NOLOCK)
INNER JOIN JOIN Core AS cc WITH (NOLOCK)
ON cc.ClaimID = csd.ClaimID
GROUP BY cc.Claim, csd.Reserve
) t
)
SELECT *
FROM numbered_rows AS prev
INNER JOIN numbered_rows AS cur
ON cur.Claim= prev.Claim
AND cur.Rank = prev.Rank + 1
WHERE prev.Rank = 1;