Oracle merge adding records when matched - sql

I have a table that has an ID field with a trigger (so it's essentially an IDENTITY field) as my primary key. I mostly don't care about that.
The rest of the data are several linking keys, and I want to query my data, and if any of those keys have changed, add a new record with a new effective date. If all the keys are the same, then nothing should be added.
However, even when all of the keys match, it is adding new records. All of the fields I care about are exactly the same, so I'm essentially getting duplicate records, but with a new ID and new effective date.
I'll simplify my code a bit, but this is essentially what I have:
MERGE_TABLE (
merge_ID NUMBER(18) PRIMARY KEY NOT NULL,
asof_Date Date,
keyA varchar2(10 byte),
keyB varchar2(10 byte),
keyC varchar2(10 byte),
table_date Date)
There is a trigger on merge_ID on insert to use a sequence.
MERGE INTO merge_table mt
USING (
select keyA, keyB, keyC, table_date
from table -- it's actually a complex query, but it's getting data
) tbl
ON (rtrim(tbl.keyA) = rtrim(mt.keyA)
AND rtrim(tbl.keyB) = rtrim(mt.keyB)
AND rtrim(tbl.keyC) = rtrim(mt.keyC))
WHEN NOT MATCHED THEN
INSERT (asof_Date, keyA, keyB, keyC, table_date)
VALUES (sysdate, tbl.keyA, tbl.keyB, tbl.keyC, tbl.table_date)
If my MERGE_TABLE starts with the following data:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
then, after running it, I have the following data:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
13 3/22/2018 333 456 987 12/31/2017
14 3/22/2018 444 234 876 12/31/2017
15 3/22/2018 222 789 654 12/31/2017
My keys all matched, but it did an insert anyway. Why?
If KeyB had changed on the first record from 456 to 678, the data I would want is:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
13 3/22/2018 333 678 987 12/31/2017

Related

How to grab the latest data via time stamp, grab the sum of one column, eliminate dups, then sum other columns

DBMS = Hadoop, Using Teradata SQL Assistant
How do I grab all the distinct records from this table based on max(tstamp), sum qty1, sumqty2 and THEN delete duplicates record based on time1,time2,time3,docnum1?
Or how can I do multiple queries and join them together? Like query1 will grab the sum values for qty1 and qty2 for unique docnums for each day. Query2 will remove duplicates based on time1,time2,time3,docnum1.Then join those two tables together on docnum1 and date?
This is the original table. There are 20 location values (c1). Each Location has a set of aisles (c2). Timestamp (c3) can have duplicates and max(tstamp) to grab the latest and greatest. DocNum1 (c4) is the new combined doc# & DocuNum2# (c5) is the old number. qty1 and qty2 are unique whereas time1, time2, time3
Location
Aisle
Tstamp
DocNum1
DocNum2
qty1
qty2
time1
time2
time3
12
420
4/16/2021 12:22:01 PM
123
222
1
6
999
999
999
12
420
4/16/2021 11:22:01 PM
123
123
5
3
999
999
999
12
420
4/16/2021 10:22:01 PM
123
333
6
7
999
999
999
31
420
4/16/2021 12:22:01 AM
666
444
6
7
999
999
999
31
120
4/16/2021 3:22:01 PM
666
555
6
7
999
999
999
22
210
4/16/2021 01:22:01 PM
666
666
999
999
999
999
999
I used this
with query1 AS
(
SELECT *
, ROW_NUMBER() OVER(PARTITION BY location, aisle ORDER BY aisle, tstamp DESC) AS RowNum
FROM order_info
)
SELECT location
, aisle
, DocNum1
, DocNum2
, Qty1
, Qty2
, time1
, time2
, time3
FROM query1
JOIN date_db t2 ON to_date(tstamp) = t2.date_db
WHERE RowNum = 1
AND t2.yearweek >= 202207
I dont know where to place the sums or how to integrate into this.
What I want to do is this:
Location
Aisle
Tstamp
DocNum1
DocNum2
qty1
qty2
time1
time2
time3
12
420
4/16/2021 12:22:01 PM
123
222
12
16
999
999
999
31
420
4/16/2021 12:22:01 AM
666
444
6
7
999
999
999
31
120
4/16/2021 3:22:01 PM
666
555
6
7
999
999
999
22
210
4/16/2021 01:22:01 PM
666
666
999
999
999
999
999

How find duplicates of the same id but different date with SQL (Oracle)

I've got a datatable like that :
id
line
datedt
123
1
01/01/2021
123
2
01/01/2021
123
3
01/01/2021
777
1
13/04/2020
777
2
13/04/2020
123
1
12/04/2021
123
2
12/04/2021
888
1
01/07/2020
888
2
01/07/2020
452
1
05/01/2020
888
1
02/05/2021
888
2
02/05/2021
I'd like to obtain a result like that, ie : the nb of same id with differents dates.
Example we can find 123 with 2 diffents dates, 888 too, but only date for 777 and 452
id
nb
123
2
777
1
888
2
452
1
How could I get that ?
Hope it's clear :)
Thanks you
select id , count(distinct datedt) as nb
from table
group by id

Break values in one column into multiple rows

I am trying to explode values belonging to one id into multiple rows.
category_id subcategory_ids
123 111
123
333
465 444
555
The result I am trying to achieve should look like below-
category_id subcategory_ids
123 111
123 123
123 333
465 444
465 555
Below is for BigQuery Standard SQL
#standardSQL
SELECT category_id, subcategory_ids
FROM `project.dataset.table`,
UNNEST(subcategory_ids) subcategory_ids

MS Access: Update the values in a table to match the ID fields of another table

I have two tables in my MS Access database:
1) tblLines
LineID
Line
LineName
2) tblTripTimes
TripTimesID
Line
Time
The tblTripTimes times table was imported into MS Access from a transit software program, and tblLines I created in MS Access. The Line column in each table share identical values; however, I'd prefer the tblTripTimes.Line values be replaced with the primary key values in tblLines.LineID.
For example:
Before
tblLines tblTripTimes
--------------- ------------------------
LineID | Line TripId | Line | Time
1 1 234 3 13:00
2 2 235 1 09:00
3 2A 236 2 17:17
4 2B 237 2B 07:30
5 3 238 2A 21:36
After
tblLines tblTripTimes
--------------- ------------------------
LineID | Line TripId | Line | Time
1 1 234 5 13:00
2 2 235 1 09:00
3 2A 236 2 17:17
4 2B 237 4 07:30
5 3 238 3 21:36
I've tried creating an update query that would match tblTripTimes.Line with tblLines.Line, then replace the values in tblTripTimes.Line with the values in the tblLines.LineID column. Being a rookie I'm at a complete loss.
Can someone please help?!
You can use a simple update query:
UPDATE tblLines INNER JOIN tblTripTimes ON tblLines.Line = tblTripTimes.Line
SET tblTripTimes.Line = tblLines.LineID

UPDATE FROM in SQL with matching key

How can I UPDATE FROM in SQL? I want to copy the FamilyID from my FamilyGuardian table:
dbo.FamilyGuardian
PupilID FamilyID GuardianID
---------------------------------
1 100002 555
2 100003 556
3 100004 557
4 100005 558
5 100006 559
6 100007 1146
7 100008 561
8 100009 562
9 100010 563
10 100011 564
Into the Guardians table where GuardianID is equal.
dbo.Guardians
GuardianID Name FamilyID
---------------------------------
555 Smith NULL
556 Patel NULL
557 Andrews NULL
558 Brown NULL
559 Abdul NULL
dbo.Guardians after INSERT FROM
GuardianID Name FamilyID
--------------------------------
555 Smith 100002
556 Patel 100003
557 Andrews 100004
558 Brown 100005
559 Abdul 100006
you have to use an UPDATE query
UPDATE T1
SET T1.FamiltyID = T2.FamilyID
FROM dbo.Guardians AS T1 INNER JOIN dbo.FamilyGuardian AS T2
ON T1.GuardianID = T2.GuardianID
There is no such thing as INSERT FROM - you're looking for UPDATE, not INSERT:
Update G
Set FamilyId = F.FamilyId
From FamilyGuardian F
Join Guardian G On G.GuardianId = F.GuardianId
You might use an updateable CTE for this
WITH UpdateableCTE AS
(
SELECT g.FamilyID
,fg.FamilyID AS newValue
FROM dbo.Guardians AS g
INNER JOIN dbo.FamilyGuardian AS fg ON g.GuardianID=fg.GuardianID
)
UPDATE UpdateableCTE SET FamilyID=newValue;
But you must be aware, that this design is - uhm - weak...
What would happen if one Guard is responsible for more than one family? What happens, if the information on one side changes, but the other side does not change?
I think, this should not get into a physically defined column at all. This should be taken with a JOIN whenever you read this data.
you mean an UPDATE, not an INSERT, right?
In that case you should use an structue like:
UPDATE dbo.Guardians
SET FamilyID = (SELECT DISTINCT FamilyID FROM dbo.FamilyGuardian fg WHERE fg.GuardianID = GuardianID )
Notice that the DISTINCT is only necessary when there are more than 1 familyId per guardianId.