#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть таблица A, которая содержит столбцы PK и Code. У меня есть таблица B, которая содержит столбцы PK, Data, Code и FK. Количество повторяющихся записей с одинаковыми данными и кодом в таблице B равно количеству повторяющихся записей с одинаковым кодом в таблице A.
Я хочу обновить FK в таблице B, чтобы каждая повторяющаяся запись (те же данные и тот же код) указывала на уникальный PK в таблице A на основе совпадающего кода в таблице A и таблице B.
Пример:
|Table A
| PK | Code|
|:-----------|------------:|
| 1 | v665 |
| 2 | v665 |
| 3 | v665 |
| 4 | v998 |
| 5 | y69 |
| 6 | y69 |
Table B
| PK | Data | Code | FK |
|:---|------------:|:----:|---:|
| 1 | some info | v665 | | <- should be updated to Table A PK 1
| 2 | some info | v665 | | <- should be updated to Table A PK 2
| 3 | some info | v665 | | <- should be updated to Table A PK 3
| 4 | important | v665 | | <- should be updated to Table A PK 1
| 5 | important | v665 | | <- should be updated to Table A PK 2
| 6 | important | v665 | | <- should be updated to Table A PK 3
| 7 | more stuff | v665 | | <- should be updated to Table A PK 1
| 8 | more stuff | v665 | | <- should be updated to Table A PK 2
| 9 | more stuff | v665 | | <- should be updated to Table A PK 3
| 10 | some data | v998 | | <- should be updated to Table A PK 4
| 11 | some more | v998 | | <- should be updated to Table A PK 4
Я перепробовал много решений, включая вложенные курсоры, но не смог получить желаемый результат.
Ответ №1:
Один из способов сделать это — использовать функцию row_number
window для создания уникального значения, которое можно использовать для объединения:
update b
set b.fk = a.pk
from (select b.*,
row_number() over (partition by b.code, b.data order by b.pk) as rn
from TableB b) b
join (select a.*,
row_number() over (partition by a.code order by a.pk) as rn
from TableA a) a
on a.code = b.code
and a.rn = b.rn
Комментарии:
1. Вау! Хороший запрос. Однако мне трудно понять это. Не могли бы вы немного объяснить, как это работает?
2. Ключом к пониманию инструкции update является понимание функции
row_number
window. Вы можете прочитать об этом здесь: msdn.microsoft.com/en-us/library/ms186734.aspx . Как только это станет немного понятнее, выполните 2 подзапроса по отдельности и посмотрите, какrn
генерируются значения. Вы заметите, что для каждой логической группировки (code
в таблицеA
и(code, data)
в таблицеB
— см.partition by
Предложения)row_number
каждая строка в этих группах будет иметь уникальный номер. Этот уникальный номер для каждой логической группы затем используется как часть условия соединения для правильного сопоставления строк.