I needed Capture multiple changes during the day but eliminating duplicates if occurs immediately.
Below is the snippet of sample data.
Source Data:
SEQ_ID ID LastName FirstName Updated_Time
50 1010 A A 01/06/2016 10:00
51 1010 B B 01/06/2016 11:00
52 1010 C C 01/06/2016 12:00
53 1010 D D 01/06/2016 15:00
54 1010 D D 01/06/2016 17:00
55 1010 D D 01/06/2016 18:00
56 1010 B B 01/06/2016 20:00
57 1010 B B 01/06/2016 21:00
58 1010 B B 01/06/2016 22:00
59 1010 B B 01/06/2016 23:00
100 2020 X X 01/06/2016 10:00
202 3030 TTT TTT 01/06/2016 10:00
201 3030 UUU UUU 01/06/2016 11:00
203 3030 VVV VVV 01/06/2016 12:00
210 3030 UUU UUU 01/06/2016 15:00
302 4000 KQ KQ 01/06/2016 07:00
300 4000 KQ KQ 01/06/2016 08:00
301 4000 KQ KQ 01/06/2016 09:00
303 4000 KQ KQ 02/06/2016 08:00
Result should be as below :
SEQ_ID ID LastName FirstName Updated_Time
50 1010 A A 01/06/2016 10:00
51 1010 B B 01/06/2016 11:00
52 1010 C C 01/06/2016 12:00
53 1010 D D 01/06/2016 15:00
56 1010 B B 01/06/2016 20:00
100 2020 X X 01/06/2016 10:00
202 3030 TTT TTT 01/06/2016 10:00
201 3030 UUU UUU 01/06/2016 11:00
203 3030 VVV VVV 01/06/2016 12:00
210 3030 UUU UUU 01/06/2016 15:00
302 4000 KQ KQ 01/06/2016 07:00
This is query I could come up with:
SELECT
[ID]
,[LastName]
,[FirstName]
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID, [Updated_Time])
- ROW_NUMBER() OVER (PARTITION BY ID,
CAST(HASHBYTES('SHA2_256', CONCAT(
ID
,[LastName]
,[FirstName]
)) AS binary(32)) ORDER BY ID ASC, [Updated_Time] ASC) [DWRecordGroupID]
FROM
xxxxxxx.xxxxxxx
order by ID , [Updated_Time] asc
Result of the Query:
ID LastName FirstName DWRecordGroupID
1010 A A 0
1010 B B 1
1010 C C 2
1010 D D 3
1010 D D 3
1010 D D 3
1010 B B 5
1010 B B 5
1010 B B 5
1010 B B 5
2020 X X 0
3030 TTT TTT 0
3030 UUU UUU 1
3030 VVV VVV 2
3030 UUU UUU 2
4000 KQ KQ 0
4000 KQ KQ 0
4000 KQ KQ 0
4000 KQ KQ 0
The idea is to eliminate duplicated based on ID and DWRecordGroupID. But somehow I am missing at the below part where the query gives me same group number and one of them gets eliminated randomly, which is incorrect.
ID LastName FirstName DWRecordGroupID
3030 TTT TTT 0
3030 UUU UUU 1
3030 VVV VVV 2
3030 UUU UUU 2
Any help is really appreciated.
Thanks in advance.
I think you can try this (X1 is your table):
SELECT ID, LAST_NAME, FIRST_NAME, UPDATED_TIME FROM (
SELECT ID, LAST_NAME, FIRST_NAME, UPDATED_TIME
, LAG(LAST_NAME) OVER (PARTITION BY ID ORDER BY UPDATED_TIME, SEQ_ID) AS LNAME_prec
, LAG(FIRST_NAME) OVER (PARTITION BY ID ORDER BY UPDATED_TIME, SEQ_ID) AS FNAME_prec
FROM X1
) X2
WHERE (LAST_NAME <>LNAME_prec AND FIRST_NAME <>FNAME_prec) OR (LNAME_prec IS NULL)
Output:
ID LAST_NAME FIRST_NAME UPDATED_TIME
----------- ---------- ---------- -----------------------
1010 A A 2016-06-01 10:00:00.000
1010 B B 2016-06-01 11:00:00.000
1010 C C 2016-06-01 12:00:00.000
1010 D D 2016-06-01 15:00:00.000
1010 B B 2016-06-01 20:00:00.000
2020 X X 2016-06-01 10:00:00.000
3030 TTT TTT 2016-06-01 10:00:00.000
3030 UUU UUU 2016-06-01 11:00:00.000
3030 VVV VVV 2016-06-01 12:00:00.000
3030 UUU UUU 2016-06-01 15:00:00.000
4000 KQ KQ 2016-06-01 07:00:00.000
This will obviously need to be adapted to incorporate however many columns you have in your table:
;WITH cte ( rownum, seq_id, id, last_name, first_name, updated_time )
AS (SELECT row_number()
OVER (
ORDER BY id, updated_time),
seq_id,
id,
last_name,
first_name,
updated_time
FROM #tbl)
SELECT t.*
FROM cte l
INNER JOIN #tbl t ON l.seq_id = t.seq_id
LEFT OUTER JOIN cte p ON l.rownum - 1 = p.rownum
AND l.id = p.id
AND l.last_name = p.last_name
AND l.first_name = p.first_name
WHERE p.seq_id IS NULL
The real difficulty comes from the fact that, in the end, you have to compare every non-sequence field (i.e. not seq_id and not updated_time) from one row against every non-sequence field from another row.
Note: This solution naively assumes changes to a particular ID are to be treated as a single collection of changes. So if seq_id 548 that comes in on 01/23/2017 for id 1010 has the same first_name, last_name as seq_id 56, it will not be picked up. It could be adapted to work IF the seq_id column could be guaranteed to be in sequence order (but your sample data did not have that).
You can use Row_number() and get the values of 1
;with CTE as (
select *, RowN = row_number() over (partition by lastname order by seq_id) from #yourduplicates
) select * from cte where RowN = 1
Your Input table:
create table #yourDuplicates (Seq_ID int, id int, lastname varchar(10), firstname varchar(10), updated_time datetime)
insert into #yourDuplicates
(SEQ_ID , ID , LastName , FirstName , Updated_Time ) values
( 50 , 1010 ,'A ', 'A ', '01/06/2016 10:00')
, ( 51 , 1010 ,'B ', 'B ', '01/06/2016 11:00')
, ( 52 , 1010 ,'C ', 'C ', '01/06/2016 12:00')
, ( 53 , 1010 ,'D ', 'D ', '01/06/2016 15:00')
, ( 54 , 1010 ,'D ', 'D ', '01/06/2016 17:00')
, ( 55 , 1010 ,'D ', 'D ', '01/06/2016 18:00')
, ( 56 , 1010 ,'B ', 'B ', '01/06/2016 20:00')
, ( 57 , 1010 ,'B ', 'B ', '01/06/2016 21:00')
, ( 58 , 1010 ,'B ', 'B ', '01/06/2016 22:00')
, ( 59 , 1010 ,'B ', 'B ', '01/06/2016 23:00')
, ( 100 , 2020 ,'X ', 'X ', '01/06/2016 10:00')
, ( 202 , 3030 ,'TTT', 'TTT', '01/06/2016 10:00')
, ( 201 , 3030 ,'UUU', 'UUU', '01/06/2016 11:00')
, ( 203 , 3030 ,'VVV', 'VVV', '01/06/2016 12:00')
, ( 210 , 3030 ,'UUU', 'UUU', '01/06/2016 15:00')
, ( 302 , 4000 ,'KQ ', 'KQ ', '01/06/2016 07:00')
, ( 300 , 4000 ,'KQ ', 'KQ ', '01/06/2016 08:00')
, ( 301 , 4000 ,'KQ ', 'KQ ', '01/06/2016 09:00')
, ( 303 , 4000 ,'KQ ', 'KQ ', '02/06/2016 08:00')
Related
Could someone help me with cte expresion? I have a table:
old_card
new_card
dt
111
555
2020-01-09
222
223
2020-02-10
333
334
2020-03-11
444
222
2020-04-12
555
666
2020-05-12
666
777
2020-06-13
777
888
2020-07-14
888
0
2020-08-15
999
333
2020-09-16
223
111
2020-10-16
I need to get all the changes of old_card to a new_card, since old_card number 111 to a new_card number 0. So I must get 5 records from this table having only a new_card = 0 as input parameter
old_card
new_card
dt
111
555
2020-01-09
555
666
2020-05-12
666
777
2020-06-13
777
888
2020-07-14
888
0
2020-08-15
I think of to do it using cte, but I get all the records from the source table and can't understand why. Here is my cte:
;with cte as(
select
old_card,
new_card,
dt
from
cards_transfer
where
new_card = 0
union all
select
t1.old_card,
t1.new_card,
t1.dt
from
cards_transfer t1
inner join
cte on cte.old_card = t1.new_card)
But I get 8 rows instead. Can someone tell me please what I did wrong?
You said you wanted from 111 onwards. So you need to add that "stop" condition
where cte.old_card <> 111
;with cte as(
select
old_card,
new_card,
dt
from
cards_transfer
where
new_card = 0
union all
select
t1.old_card,
t1.new_card,
t1.dt
from
cards_transfer t1
inner join
cte on cte.old_card = t1.new_card
where cte.old_card <> 111
)
I'm trying to get the Running total from the values from the previous months. And if the month is january I would like to get the total from the previous year and so forth.
I hope someone can help.
WITH CTE AS (SELECT COUNT(LZP.pv_zaaknummer) AS [Aantal LZP]
, YEAR(LZP.lzp_actief_vanaf) AS Jaar
, MONTH(LZP.lzp_actief_vanaf) AS Maand
FROM dm.crm_LZP_Vn_zaaktype_leefzorgplan_registrerenExtensionBase_hist AS LZP
WHERE LZP.LZP_actief_tot_LDTS > GETDATE()
GROUP BY YEAR(LZP.lzp_actief_vanaf)
, MONTH(LZP.lzp_actief_vanaf)
)
SELECT a.Jaar
, a.Maand
, a.[Aantal LZP]
, (
SELECT SUM(b.[Aantal LZP])
FROM CTE AS b
WHERE b.Jaar <= a.Jaar
) AS [Running Total 1]
, (
SELECT SUM(b.[Aantal LZP])
FROM CTE AS b
WHERE b.Jaar <= a.Jaar
AND b.Maand <= a.Maand
) AS [Running Total 2]
FROM CTE AS a
ORDER BY a.Jaar, a.Maand;
Results as of now, I'm getting the Totals per year and then the running totals per year:
Jaar Maand Aantal LZP Running Total 1 Running Total 2
2014 4 11 661 11
2014 5 52 661 63
2014 6 70 661 133
2014 7 76 661 209
2014 8 39 661 248
2014 9 86 661 334
2014 10 112 661 446
2014 11 120 661 566
2014 12 95 661 661
2015 1 57 3327 57
2015 2 109 3327 166
2015 3 196 3327 362
2015 4 200 3327 573
2015 5 169 3327 794
2015 6 233 3327 1097
2015 7 276 3327 1449
2015 8 224 3327 1712
2015 9 203 3327 2001
2015 10 291 3327 2404
2015 11 296 3327 2820
2015 12 412 3327 3327
2016 1 311 6062 368
2016 2 341 6062 818
2016 3 476 6062 1490
2016 4 440 6062 2141
2016 5 418 6062 2780
2016 6 500 6062 3583
2016 7 249 6062 4184
I would like it to be:
Running Total 3
11
63
133
209
248
334
446
566
661
718
827
1023
1223
1392
1625
1901
2125
2328
2619
2915
3327
3638
3979
4455
4895
5313
5813
6062
you could do it without subquery try
....................)
SELECT a.Jaar
, a.Maand
, a.[Aantal LZP],SUM([Aantal LZP]) over (order by jaar) [Running Total 1]
, SUM([Aantal LZP]) over (partition by jaar order by maand) [Running Total 2],
SUM([Aantal LZP]) over ( order by jaar,maand) [Running Total 3]
FROM CTE AS a
ORDER BY a.Jaar, a.Maand;
old version
SELECT a.Jaar
, a.Maand
, a.[Aantal LZP],(SELECT SUM(b.[Aantal LZP])
FROM CTE AS b
WHERE b.Jaar <= a.Jaar
) [Running Total 1],
(SELECT SUM(b.[Aantal LZP])
FROM CTE AS b
WHERE b.Jaar <= a.Jaar and Maand<=a.Maand
) [Running Total 2]
, (SELECT SUM(b.[Aantal LZP])
FROM CTE AS b
WHERE dateadd(year,jaar-1900,dateadd(month,maand-1,0)) <= dateadd(year,a.jaar-1900,dateadd(month,a.maand-1,0))
) [Running Total 3]
FROM CTE AS a
ORDER BY a.Jaar, a.Maand;
Found the Solution but now I must find to integrate it so it responds to my reportparameters Jaar and Maand
DECLARE #SalesTbl TABLE (Jaar int, Maand int, Aantal int, RunningTotal int)
DECLARE #Jaar int,
#Maand int,
#Aantal int,
#RunningTotal int
SET #RunningTotal = 0
DECLARE rt_cursor CURSOR
FOR
WITH CTE AS
(SELECT COUNT(LZP.pv_zaaknummer) AS [Aantal LZP]
, YEAR(LZP.lzp_actief_vanaf) AS Jaar
, MONTH(LZP.lzp_actief_vanaf) AS Maand
FROM dm.crm_LZP_Vn_zaaktype_leefzorgplan_registrerenExtensionBase_hist AS LZP
WHERE LZP.LZP_actief_tot_LDTS > GETDATE()
GROUP BY LZP.lzp_actief_vanaf
)
SELECT A.Jaar, A.Maand, SUM(A.[Aantal LZP])
FROM CTE AS A
GROUP BY Jaar, Maand
ORDER BY A.Jaar, A.Maand
OPEN rt_cursor
FETCH NEXT FROM rt_cursor INTO #Jaar, #Maand, #Aantal
WHILE ##FETCH_STATUS = 0
BEGIN
SET #RunningTotal = #RunningTotal + #Aantal
INSERT #SalesTbl VALUES (#Jaar, #Maand,#Aantal,#RunningTotal)
FETCH NEXT FROM rt_cursor INTO #Jaar, #Maand, #Aantal
END
CLOSE rt_cursor
DEALLOCATE rt_cursor
SELECT * FROM #SalesTbl
For this question:
Get the pids of products ordered through any agent who makes at least one order for a customer in Kyoto. Use joins this time; no sub-queries.
I was able to get the answer using a subquery:
select distinct pid
from orders
where aid in (
select aid
from orders
where cid in(
select cid
from customers
where city = 'Kyoto'
)
)
I cannot figure out how to do this using only joins however.
This code returns the aid's that i need to get the pid's however i can't come up with a way to get them without using a sub query:
select distinct o.aid
from orders o, customers c
where o.cid = c.cid
and c.city = 'Kyoto'
Here are the two tables i am using:
Customers:
cid name city discount
c001 Tiptop Duluth 10.00
c002 Basics Dallas 12.00
c003 Allied Dallas 8.00
c004 ACME Duluth 8.00
c005 Weyland-Yutani Acheron 0.00
c006 ACME Kyoto 0.00
and Orders:
ordno mon cid aid pid qty dollars
1011 jan c001 a01 p01 1000 450.00
1013 jan c002 a03 p03 1000 880.00
1015 jan c003 a03 p05 1200 1104.00
1016 jan c006 a01 p01 1000 500.00
1017 feb c001 a06 p03 600 540.00
1018 feb c001 a03 p04 600 540.00
1019 feb c001 a02 p02 400 180.00
1020 feb c006 a03 p07 600 600.00
1021 feb c004 a06 p01 1000 460.00
1022 mar c001 a05 p06 400 720.00
1023 mar c001 a04 p05 500 450.00
1024 mar c006 a06 p01 800 400.00
1025 apr c001 a05 p07 800 720.00
1026 may c002 a05 p03 800 740.00
MySQL client version: 5.0.24a
Hey Folks,
I have a table WorkOrders_errors that looks like this:
ID CO CAR NAME CAN BLN INDATE MODDATE EX
66897 461 57 KKLU KKLUSH9862088 AKLU6013312 1/27/2014 1:00 1/27/2014 1:00 -1
60782 461 57 KKLU KKLUHB21629300 AKLU6501153 1/26/2014 22:00 1/26/2014 22:00 1
74188 461 57 KKLU KKLUHB21629300 AKLU6501153 1/27/2014 10:00 1/27/2014 10:00 1
66645 461 57 KKLU KKLUSH8222080 AKLU6501744 1/26/2014 21:45 1/26/2014 21:45 1
63307 461 126 ZIMU ZIMUGOA321986 AMFU3037671 1/27/2014 1:15 1/27/2014 1:15 1
65081 461 24 CMDU CMDUAU1337382 AMFU3043761 1/26/2014 21:30 1/26/2014 21:30 1
72660 461 24 CMDU CMDUAU1337382 AMFU3043761 1/27/2014 9:30 1/27/2014 9:30 1
I need only the records with the most recent MODDATE, ie ID Record 74188, not 60782.
I have tried this a few ways, but without success. Most recently tried
SELECT * FROM (
SELECT * FROM WorkOrders_errors ORDER BY ModDate DESC) as tmp
GROUP BY can
ORDER BY can
'ALSO TRIED
SELECT t1.*
FROM WorkOrders_errors t1
WHERE t1.Can = (SELECT t2.Can
FROM WorkOrders_errors t2
WHERE t2.Can = t1.Can
ORDER BY t2.Can DESC
LIMIT 1)
These both seem to take a Huge amount of resources/time. The table only has about 80,000 rows.
Thanks anyone!
I have two tables:
table1 =tbl_main:
item_id fastec_qty sourse_qty
001 102 100
002 200 230
003 300 280
004 400 500
table2= tbl_dOrder
order_id item_id amount
1001 001 30
1001 002 40
1002 001 50
1002 003 70
How can I write a query so that the result of the tables are as follows:
sum(fastec_qty) sum(sourse_qty) difference1 sum(amount) difference2
1002 1110 -108 190 812
difference1 =sum(fastec_qty)-sum(sourse_qty);
difference2 =sum(fastec_qty)-sum(amount);
select sum(m.fastec_qty)
, sum(m.sourse_qty)
, sum(m.fastec_qty) - sum(m.sourse_qty)
, sum(o.amount)
, sum(m.fastec_qty) - sum(o.amount)
from tbl_main m
, tbl_dOrder o
where m.item_id = o.item_id
group by 1, 2, 3, 4, 5
SELECT sum(a.sourse_qty) as samount, sum(a.fastec_qty) AS amount,
sum(a.sourse_qty- a.fastec_qty) as sfd,
(select sum(ITEM_QTY) from TBL_DO )as qty,
sum(a.fastec_qty) - (select sum(ITEM_QTY) from TBL_DO ) AS difference
FROM tbl_main a group by 1,2,3,4,5
amount samount sfd qty difference
1002 1110 -108 190 812
Thanks All ,
I'll give you a hint, start by joining the tables on the item_id.
select item_id.tbl_main fastec_qty.tbl_main
, source_qty.tbl_main
, order_id.tbl_order
, amount.tbl_order
from tbl_main
, tbl_order
where item_id.tbl_main = item_id.tbl_order;
next step is to sum the three columns and finally do the subtraction.