I have two tables as below.
I want to update table_a.fid to table_b.id when table_a.name=table_b.name and table_a.value=table_b.value and table_b.id is not set to other table_a.fid
table_a (a):
id(int) name(varchar) value(varchar) fid(int)
1 name_a value_1 0
2 name_a value_1 0
3 name_a value_1 0
4 name_b value_2 0
5 name_c value_3 0
table_b (b):
id(int) name(varchar) value(varchar)
1 name_a value_1
2 name_a value_1
3 name_b value_2
4 name_b value_2
table_a expected results:
id name value fid
1 name_a value_1 1 // b.id(1,2) matched, so set the first b.id(1) to a.fid(1)
2 name_a value_1 2 // b.id(1,2) matched and b.id(1) already set to a.fid(1), so set the second b.id(2) to a.fid(2)
3 name_a value_1 0 // b.id(1,2) matched and b.id(1,2) already set to a.fid(1,2), so is 0
4 name_b value_2 3 // b.id(3,4) matched. so set the first b.id(3) to a.fid
5 name_c value_3 0 // b not matched
2
Answers
If you are using mysql 8.0 or higher then you can use window function
ROW_NUMBER()
to assign an order number to rows within a related record set, and then use this unique identifier for joining as well :Results :
Demo here
For MySQL 5.7,try the query below. Note: the user variable @row_number defines row number for a row of the current name, and the @row_number value is reset to 1 when @current_name meets a different name in the row.
Note, the above query is written supposing rows with the same
NAME
are in consecutive order. If that’s not case, use a derived table with ORDER BY clause instead of the base table.Take the case below for example.Let’s try the original method:
As denoted above, the result we get is not right. Let’s query a derived table with an ORDER BY clause (i.e.
select * from table_x order by name,id
) instead of the base table: