original data: orginal_table
MID STATE CALL_TIME RECORD_RANK
a 1 2020-12-18 09:00:00 1
a 2 2020-12-19 09:00:00 2
b 1 2020-12-18 09:00:02 1
c 1 2020-12-18 09:00:03 1
c 1 2020-12-19 09:00:03 2
c 1 2020-12-20 09:00:03 3
d 1 2020-12-19 09:00:00 1
The data I wanted to insert: insert_table
MID STATE CALL_TIME
a 2 2020-12-30 09:00:00
b 2 2020-12-19 09:00:02
c 1 2020-12-21 09:00:03
e 1 2020-12-30 09:00:00
f 1 2020-12-30 09:00:00
f 2 2020-12-31 09:00:00
Goal
- The original data will be inserted from the second data.
- For original and inserted data, the pair
MID and CALL_TIMEis unique. - There is no
RECORD_RANKcolumn in the inserted data butRECORD_RANKwill be calculated based onMID and CALL_TIME columnswhen inserted. When duplicated MID with different CALL_TIME, the value of RECORD_RANK with MID will be added by 1. The initial value is 1. - The earliest row in in insert_table is always later than the latest row in orginal_table with the same MID.
The expected example result as below:
MID STATE CALL_TIME RECORD_RANK
a 1 2020-12-18 09:00:00 1
a 2 2020-12-19 09:00:00 2
b 1 2020-12-18 09:00:02 1
c 1 2020-12-18 09:00:03 1
c 1 2020-12-19 09:00:03 2
c 1 2020-12-20 09:00:03 3
d 1 2020-12-19 09:00:00 1
a 2 2020-12-30 09:00:00 3
b 2 2020-12-19 09:00:02 2
c 1 2020-12-21 09:00:03 4
e 1 2020-12-30 09:00:00 1
f 1 2020-12-30 09:00:00 1
f 2 2020-12-31 09:00:00 2
Note
- mysql version: 5.5.47-log
I think it is possible to handle the logic in a single
insert, even in MySQL 5.x.The target rank is the number of rows that already exists in the target table for the same
mid, plus the number ofmidrows in the source table prior to the current row. You can compute that with correlated subqueries:This assumes that all new rows are more recent that existing rows, as mentioned in your question. But if you want otherwise, that's an easy fix to the first subquery:
Here is a demo based on the nice test case built by Akina.
Side note: in MySQL 8.0, we would use a window function instead of the second subquery, which would make the query much more efficient: