Find duplicates on multiple columns in a SQL - 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

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;

Getting Complex Result With Balance

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

Update sequence in table - Oracle

I have a table:
table1
u_a_id element_id my_seq line_num
1 HI01-01 1 30
1 HI01-02 1 30
1 HI01-01 1 31
1 HI01-02 1 31
1 HI02-03 1 31
1 HI02-04 1 31
2 HI01-01 1 40
2 HI01-02 1 40
2 HI02-01 1 40
2 HI02-02 1 40
2 HI02-03 1 40
2 HI02-04 1 40
2 HI03-02 1 41
2 HI03-03 1 41
2 HI05-04 1 41
2 HI05-05 1 41
I need to update my_seq if a new HI01 appears in the same u_a_id or the counter for HI changes, for ex. HI01 -> HI02 for each u_a_id order by line_num.
I have this query, however this gives seq as 1 even for second instance of HI01-01 in u_a_id = 1:
select t.*,
dense_rank() over (partition by u_a_id order by substr(element_id, 1, 4)) as new_my_seq
from table1 t
The output would look like:
u_a_id element_id my_seq line_num
1 HI01-01 1 30
1 HI01-02 1 30
1 HI01-01 2 31
1 HI01-02 2 31
1 HI02-03 3 31
1 HI02-04 3 31
2 HI01-01 1 40
2 HI01-02 1 40
2 HI02-01 2 40
2 HI02-02 2 40
2 HI02-03 2 40
2 HI02-04 2 40
2 HI03-02 3 41
2 HI03-03 3 41
2 HI05-04 4 41
2 HI05-05 4 41
Is there a way in Oracle SQL to achieve this?
I think you just want:
select t.*,
dense_rank() over (partition by u_a_id
order by line_num,
substr(element_id, 1, 4)
) as my_seq
from t;
You may want to order by line_num instead of substr(element_id, 1, 4) and place substr(element_id, 1, 4) in partition by.
select t.*,
dense_rank() over (partition by u_a_id, substr(element_id, 1, 4) order by line_num) as new_my_seq
from table1 t

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

Running total of rows by ID

I have a list of IDs, transactions, and the date of those transactions. I want to create a count of each transaction within each ID.
The starting table I have is looks something like this:
id trxn_dt trxn_amt
1 10/31/2014 58
1 11/9/2014 34
1 12/10/2014 12
2 7/8/2014 78
2 11/20/2014 99
3 1/5/2014 120
4 2/17/2014 588
4 2/18/2014 8
4 3/9/2014 65
4 4/25/2014 74
and I want the end result to look something like this:
id trxn_dt trxn_amt trxn_count
1 10/31/2014 58 1
1 11/9/2014 34 2
1 12/10/2014 12 3
2 7/8/2014 78 1
2 11/20/2014 99 2
3 1/5/2014 120 1
4 2/17/2014 588 1
4 2/18/2014 8 2
4 3/9/2014 65 3
4 4/25/2014 74 4
Count(distinct(id)) would only give me the overall number of distinct IDs and not a running total by each ID that restarts at each new ID.
Thank you!
In SQL-Server you can use ROW_NUMBER in following:
SELECT id,
trxn_dt,
trxn_amt,
ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Id, trxn_dt) AS trxn_count
FROM StarningTable
In MySQL you can do in following:
SELECT
t.id,
t.trxn_dt,
t.trxn_amt,
#cur:= IF(id=#id, #cur+1, 1) AS RowNumber,
#id := id
FROM
StarningTable t
CROSS JOIN
(SELECT #id:=(SELECT MIN(id) FROM StarningTable t), #cur:=0) AS init
ORDER BY
t.id
using Row_number we can achieve this
Select *,
ROW_NUMBER()OVER(PARTITION BY id ORDER BY (SELECT NULL))trxn_count
from Transactions