УДАЛИТЬ ТОП записи переменных с переменной из группы другой таблицы - PullRequest
0 голосов
/ 24 апреля 2020

Скажем, у меня есть две таблицы: A и B

Таблица A

+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
|  2 |    20 |
|  3 |    10 |
|  4 |     0 |
+----+-------+

Таблица B

+----+-------+
| id | value |
+----+-------+
|  1 |    20 |
|  2 |    10 |
|  3 |    30 |
|  4 |    20 |
|  5 |    20 |
|  6 |    10 |
+----+-------+

Если я сделаю SELECT value, COUNT(*) AS occurrence FROM A GROUP BY value, я получу:

+-------+------------+
| value | occurrence |
+-------+------------+
|    20 |          2 |
|    10 |          1 |
|     0 |          1 |
+-------+------------+

На основе этой группировки таблицы A я хочу удалить occurrence записей из таблицы B с теми же значениями. Другими словами, я хочу удалить из B 2 записи со значением 20, 1 запись со значением 10 и 1 запись со значением 0. (Другие условия включают «ничего не делать, если нет записи» и «сначала наименьший идентификатор», но я думаю, что эти условия довольно тривиальны по сравнению с основной частью этого вопроса.)

Таблица B после удаления должна быть:

+----+-------+
| id | value |
+----+-------+
|  3 |    30 |
|  5 |    20 |
|  6 |    10 |
+----+-------+

Из официальной ТОП документации , не Кажется, я не могу выполнить JOIN для использования в качестве выражения TOP.

1 Ответ

3 голосов
/ 24 апреля 2020

Мы могли бы использовать ROW_NUMBER с CTE здесь:

WITH cteA AS (
    SELECT value, COUNT(*) cnt
    FROM A
    GROUP BY value
),
cteB AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY value ORDER BY id) rn
    FROM B
)

DELETE
FROM cteB b
INNER JOIN cteA a
    ON b.value = a.value
WHERE
    b.rn <= a.cnt;

Лог c здесь заключается в том, что мы используем ROW_NUMBER для отслеживания порядка каждого значения в таблице B. Затем мы присоединяемся, чтобы ввести число каждого значения в таблице A, и мы удаляем только те записи B, для которых номер строки строго меньше или равен количеству A.

См. Демонстрационную ссылку ниже проверить правильность логики c. Обратите внимание, что я использую выбор там, а не удаление, но правильные строки предназначены для удаления.

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...