SQL обновление в зависимости от значений из представления - PullRequest
0 голосов
/ 18 июня 2020

Я думал, что это должна быть довольно простая задача, но мне не удалось увидеть сложность.

У меня есть таблица, которую мне нужно рефакторинг, в одном из ее FK есть повторяющиеся записи, которые, похоже, не соответствуют быть, так как у них разный регистр для имен, скажем FTP и ftp, например

Итак, я построил представление, которое выводит строчные версии дубликатов с его идентификатором и количеством раз он был использован в таблице, которую я рефакторингу. Причина, по которой я делаю этот подсчет, заключается в том, что я могу назначить идентификатор версии записи, которая использовалась чаще всего, в надежде, что это не окажет такого большого влияния на пользовательский интерфейс, когда запись визуально изменяется

Итак, вывод представления выглядит примерно так:

enter image description here

Хорошо, поэтому здесь я хочу сохранить 'tagger' с id = 1 и mytag с id = 4, поскольку они используются чаще (countyCo)

Теперь у меня есть таблица tag, в которой хранятся все детали для 'tagger' и 'mytag' , а затем у меня есть таблица picture_tag, которая связывает теги с изображениями.

Вывод picture_tag может быть:

enter image description here

Я добавил name_aux с исходными именами из таблицы tag, чтобы их было легче связать

Я пробовал несколько запросов, но проблема, с которой я столкнулся, заключается в том, как чтобы сгруппировать все идентификаторы строк с «одинаковым» именем в таблице picture_tag, а затем назначить идентификатор с MAX countyCo для группы en пытается в представлении, которое имеет одинаковое значение

Пока все, что я сделал, не может использовать более одной записи и заканчивает назначением 'tagger' каждой записи, перезаписывая 'mytag'

Моя последняя попытка выглядела так:

UPDATE picture_tag SET tag_id = (SELECT id FROM duplicate_stuff WHERE (countyCo, name) IN (
SELECT MAX(countyCO), name FROM duplicate_stuff dst
JOIN picture_tag ptag
ON dst.id = ptag.tag_id
AND dst.name = LOWER(ptag.name_aux)
GROUP BY name))

Но подзапрос вернул более одного элемента.

Другая попытка была такой:

  UPDATE picture_tag ptag SET tag_id = (SELECT id FROM duplicate_stuff ds WHERE ds.name =
(SELECT LOWER(tag) FROM tag WHERE id = ds.id)
AND id = (SELECT id FROM tag WHERE id = ds.id)
ORDER BY ds.countyCo DESC
LIMIT 1
)
WHERE ptag.tag_id IN (SELECT id FROM duplicate_stuff)

Но конечно, ограничение 1 заставляет меня перезаписывать 'mytag', а также 'tagger'

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

В итоге я выбрал правильный алгоритм:

UPDATE picture_tag ptag
SET tag_id = (SELECT id FROM duplicate_stuff
WHERE name = LOWER(ptag.name_aux)
ORDER BY countyCo DESC
LIMIT 1)
WHERE LOWER(name_aux) IN (SELECT name FROM duplicate_stuff)

Или, чтобы избежать проблем с MS SQL и его пределом при использовании IN:

UPDATE picture_tag ptag
SET tag_id = (SELECT id FROM duplicate_stuff
WHERE name = LOWER(ptag.name_aux)
ORDER BY countyCo DESC
LIMIT 1)
WHERE EXISTS (SELECT name FROM duplicate_stuff WHERE name = LOWER(name_aux))
0 голосов
/ 18 июня 2020

Вы можете использовать ROW_NUMBER, чтобы получить наиболее часто используемые теги. Затем присоедините эту таблицу «дубликатов» к самой себе. И присоединяйтесь к таблице, которую вы хотите обновить.

Примерно так:

WITH cte_tags
as
(
SELECT *,ROW_NUMBER() over (PARTITION BY tagLower ORDER BY  Counter DESC ) as rn
FROM duplicate_stuff
)
UPDATE upd
SET TagId = tagMax.TagId
FROM cte_tags tagMax 
JOIN cte_tags tagNotMax on tagMax.tagLower = tagNotMax.tagLower and tagNotMax.rn>1
JOIN picture_tag upd on upd.tagId = tagNotMax.TagId
where tagmax.rn =1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...