Getting Complex Result With Balance - sql

I have the two tables Issue and Received. I want to get result with same row of issue.
Issue table:
NO
LCODE
PCS
1
L0001
10
2
L0002
25
3
L0003
75
4
L0004
12
5
L0005
15
Received table:
NO
LCODE
PCS
1
L0001
5
2
L0001
5
3
L0003
48
4
L0003
12
5
L0003
15
Wanted result:
NO
LCODE
ISSPCS
RECPCS
BAL
1
L0001
10
5
5
2
L0001
0
5
0
3
L0003
75
48
27
4
L0003
0
12
15
5
L0003
0
15
0
6
L0004
12
0
12
7
L0005
15
0
15
SELECT ROW_NUMBER() OVER(PARTITION BY i.LCODE ORDER BY i.LCODE) as NO,
i.LCODE,i.PCS as ISSPCS,r.PCS as RECPCS,(i.PCS-r.PCS) as BAL
FROM Issue i
LEFT JOIN Received r ON i.LCODE = r.LCODE
Find The Best Way To Getting This Result Thank you.

Try this code:
SELECT ROW_NUMBER() OVER ( ORDER BY i.LCODE ASC, RunninngSum ASC) AS [NO]
, i.LCODE
, CASE WHEN RunninngSum > r.PCS THEN 0 ELSE i.PCS
END AS ISSPCS
, ISNULL( r.PCS, 0) AS RECPCS
, i.PCS - ISNULL( RunninngSum, 0) as BAL
FROM Issue i
LEFT JOIN Received r ON i.LCODE = r.LCODE
CROSS APPLY (
SELECT SUM( r1.PCS) AS RunninngSum
FROM Received r1
WHERE r1.LCODE = r.LCODE AND r1.[NO] <= r.[NO]
)x

Related

Cumulative sum in SQL using window function

QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
35
20
35
2
1
0
15
35
3
1
0
58
35
4
1
0
18
35
5
1
0
40
35
1
2
35
20
35
2
2
0
15
35
3
2
0
CUM SUM should be MIN(QTY, STOCK-SUM(all rows in cumsum before the current row)) for every other row and for 1st row it should be MIN(QTY, STOCK-SUM(0))=> MIN(QTY,STOCK)
QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
5
20
35
2
1
-10
15
35
3
1
-30
58
35
4
1
-7
18
35
5
1
-24
40
35
1
2
5
20
35
2
2
-10
15
35
3
2
-30
After, I tried I am getting the above output
SELECT sum(qty-stock) over (
partition by ID KEY
ORDER BY rnk
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as CUM SUM
FROM TABLE
Need to get correct cumsum value using a window function in the existing table
You may use a rolling SUM() here, using SUM() as an analytic function:
SELECT *, SUM(QTY - STOCK) OVER (PARTITION BY ID_KEY ORDER BY RNK) AS CUM_SUM
FROM yourTable
ORDER BY ID_KEY, RNK;

SQL Temp table Array to perfrom rolling caluclations

I wish to use some sort of SQL array to subtract values from a certain row (QTYOnHand) that decreases that row value every time and throws it into a rolling calculation for the other rows. I've been thinking of some sort of Self Join/Temp Table solution, but not sure how to formulate. Also, All the results will be partitioned by the ItemID below. Help would be appreciated.
Here's some data, If I do a simple row by row subtraction I will get this: 17-3 = 14, 17-5 = 12 and so on.
(Item_ID) (ItemQty) (QTYOnHand) (QtyOnHand - ItemQty)
123 3 17 14
123 5 17 12
123 4 17 13
456 7 12 5
456 8 12 4
456 2 12 10
456 3 12 9
789 2 6 4
789 2 6 4
789 2 6 4
These are the results that I want, where I subtract every next value from the new QTYOnHand-ItemQty column value. Looks like 17-3 then 14 -5 then 9 -4 for Item_ID (123):
(Item_ID) (ItemQty) (QTYOnHand) (QtyOnHand - ItemQty)
123 3 17 14
123 5 17 9
123 4 17 5
456 7 12 5
456 8 12 -3
456 2 12 -5
456 3 12 -8
789 2 6 4
789 2 6 2
789 2 6 0
try the following:
;with cte as
(
select *, ROW_NUMBER() over (partition by Item_ID order by Item_ID) rn
from YourTable
)
, cte2 as
(
select Item_ID, ItemQty, QTYOnHand, Case when rn = 1 then QTYOnHand else 0 end - ItemQty as calc, rn
from cte
)
select Item_ID, ItemQty, QTYOnHand, sum(calc) over (partition by Item_ID order by rn) as [QtyOnHand - ItemQty]
from cte2 t1
Please find the db<>fiddle here.

Compare Current Row with Previous/Next row in SQL Server

I have a table named team and it like below: I just added a row_number in the 3rd column
RaidNo OutComeID RN
2 15 1
4 15 2
6 14 3
8 16 4
10 16 5
12 14 6
14 16 7
16 15 8
18 15 9
20 16 10
22 12 11
24 16 12
26 16 13
28 16 14
30 15 15
32 14 16
34 13 17
When the OutcomeId came as 16 then start with one and 16 comes consecutively, add one by one. And the results be like
RaidNo OutComeID RN Result
2 15 1 0
4 15 2 0
6 14 3 0
8 16 4 1
10 16 5 2
12 14 6 0
14 16 7 1
16 15 8 0
18 15 9 0
20 16 10 1
22 12 11 0
24 16 12 1
26 16 13 2
28 16 14 3
30 15 15 0
32 14 16 0
34 13 17 0
Help me to get the result.
You can use the following query:
SELECT RaidNo, OutComeID, RN,
CASE
WHEN OutComeID <> 16 THEN 0
ELSE ROW_NUMBER() OVER (PARTITION BY OutComeID, grp ORDER BY RN)
END AS Result
FROM (
SELECT RaidNo, OutComeID, RN,
RN - ROW_NUMBER() OVER (PARTITION BY OutComeID ORDER BY RN) AS grp
FROM mytable) AS t
ORDER BY RN
Field grp identifies slices (also called islands) of consecutive records having the same OutComeID value. The outer query uses grp in order to enumerate each record that belongs to a '16' slice. The records that belong to the other slices are assigned value 0.
Demo here

Find duplicates on multiple columns in a SQL

I want to find the batchID who are having subjectID(0,1,2) only, pls help me, thanks in advance
I need answer BatchID=12 and BatchID=51, what can I do in sql
MyTable
uid BatchID SubjectID
6 2 0
7 2 1
8 2 2
9 2 4
10 3 0
11 3 1
12 4 5
13 4 0
14 5 5
15 6 5
17 7 0
18 7 1
19 7 2
26 12 0
27 12 1
28 12 2
29 1 0
30 1 1
31 1 4
62 45 5
63 46 0
64 46 1
65 46 4
107 49 6
108 49 2
109 49 4
110 50 1
111 50 3
116 0 1
117 0 4
118 51 0
119 51 1
120 51 2
You can use conditional aggregation for this:
select batchId
from your_table
group by batchId
having count(distinct case when subjectID in (0,1,2) then subjectID end) = 3
and count(case when subjectID not in (0,1,2) then 1 end) = 0
Explanation:
Group by batchId - Aggregate on batchId
count(distinct case when subjectID in (0,1,2) then subjectID end) - Produces 3 only if all three of them are present for this batchId
count(case when subjectID not in (0,1,2) then 1 end) - Produces 0 if there is no other subjectID except 0,1,2 assuming nulls are not allowed in the subjectId column.
You can use Row_Number()
;with cte as (
select *, RowN = row_number() over (partition by batchid order by uid) from #yourbatch where subjectid in (0,1,2)
) select distinct BatchId from cte where RowN > 1

T-SQL recursion

I have a set of data that looks like below
Name Time Perc Group Mode Control Cancelled
A 10:52 10.10 10 0 1 0
B 09:00 10.23 10 1 1 1
C 12:02 12.01 12 0 1 1
D 10:45 12.12 12 1 7 1
E 12:54 12.56 12 1 3 0
F 01:01 13.90 13 0 11 1
G 02:45 13.23 13 1 12 1
H 09:10 13.21 13 1 1 0
I need an output like below;
Group Perc Cancelled
10 20.33 1
12 36.69 2
13 40.34 2
What I'm getting was something like;
Group Perc Cancelled
10 20.33 5
12 36.69 5
13 40.34 5
I don't know what to call this, I have something in my mind to call it like CTE?, but I really can't figure it out.
Here's my source;
SELECT Group, SUM(Perc), Cancelled FROM
(SELECT Group, Perc, (SELECT COUNT(*) FROM tblName WHERE Cancelled=1) AS Cancelled FROM tblName WHERE 1=1 AND Group>=10)dt
GROUP BY Group, Cancelled
From your example, you don't need the nested query, any recursion, etc...
SELECT
Group,
SUM(Perc) AS total_perc,
SUM(cancelled) AS total_cancelled
FROM
tblName
WHERE
1=1
AND Group >= 10
GROUP BY
Group
If you did have some different data, then you might want to use something like...
SUM(CASE WHEN cancelled > 0 THEN 1 ELSE 0 END) AS total_cancelled