#sql-server #tsql
#sql-сервер #tsql
Вопрос:
У меня есть таблица: (ID int, matchPID char, PID char, set int, num char, QID char, QStatus char)
ID matchPID PID set num QID QStatus
1 00001230 xx123 1 234
2 00001229 xx234 1 214
3 00000054 xx654 1 NULL
4 00012000 xx125 2
5 00A53214 xx321 2
6 00000100 xx213 2
matchPID всегда (00-xxxxxx) x может быть char или int .
теперь мне нужно заполнить OID только одним значением для каждого набора в соответствии с [num] .
- Если для любого набора существует какое-либо значение в [num] , затем заполните OID с помощью PID, где существует [num] для того же набора, и заполните Qstatus = ‘fail’ в rest .
таким образом, OID может быть заполнен в id 1 или 2. (any1), затем проверьте наименьший идентификатор соответствия и заполните здесь. таким образом, в этом случае (set1) ожидаемый результат :
ID matchPID PID set num QID QStatus
1 00001230 xx123 1 234 NULL FAIL
2 00001229 xx234 1 214 xx234 NULL
3 00000054 xx654 1 NULL NULL FAIL
- если для какого-либо набора не найдено ни одного [num], выберите наименьший идентификатор соответствия и заполните QID с помощью PID и завершите остальные.
обратите внимание, что matchPID начинается с 00, а затем может быть 0> 1> 2>..> A> B> C> …. таким образом, ожидаемый результат для set2 :
ID matchPID PID set num QID QStatus
4 00012000 xx125 2 NULL NULL FAIL
5 00A53214 xx321 2 NULL NULL FAIL
6 00000100 xx213 2 NULL xx213 NULL
Спасибо
Комментарии:
1. Хорошая проблема. Что вы пробовали до сих пор?
2. уф. Я пытаюсь выполнить простую команду обновления с указанием, где существует, но это становится жутким и сложным. Мне нужен оператор clean update. Спасибо 🙂
3. К чему клонил Адриан, пожалуйста, покажите нам запрос, который вы пытались выполнить, и мы можем попытаться исправить / улучшить его.
4. Попробуйте обновить вопрос, опубликовав то, что вы пробовали до сих пор. Вы увидите, что людям здесь нравится видеть, что вы прилагаете к этому некоторые усилия.
5. Мне понравилась часть «без обещаний». Это двунаправленный
Ответ №1:
Вы хотели что-то подобное?:
;WITH setInfo AS (
SELECT [SET],
CASE WHEN EXISTS (SELECT 1 FROM tableA b
WHERE b.[set]=a.[set] AND num IS NOT NULL)
THEN 1 ELSE 0 END AS HasNum,
MIN(matchPID) AS MinMatchPID
FROM tableA a
GROUP BY [SET]
)
UPDATE a SET
QID = CASE WHEN s.HasNum = 0 AND a.matchPID = s.MinMatchPID THEN a.PID
WHEN s.HasNum = 0 AND a.matchPID != s.MinMatchPID THEN NULL
WHEN s.HasNum = 1 AND a.matchPID = (SELECT min(matchpid) FROM tableA b
WHERE b.[set] = a.[set]
AND b.num is not null
)
THEN a.PID
ELSE NULL
END,
QStatus = CASE WHEN s.HasNum = 0 AND a.matchPID = s.MinMatchPID THEN NULL
WHEN s.HasNum = 0 AND a.matchPID != s.MinMatchPID THEN 'FAIL'
WHEN s.HasNum = 1 AND a.matchPID = (SELECT min(matchpid) FROM tableA b
WHERE b.[set] = a.[set]
AND b.num is not null
)
THEN a.PID
ELSE 'FAIL'
END
FROM tableA a
JOIN setInfo s ON s.[set] = a.[set]
Комментарии:
1. Нет, я на самом деле сделал это в двух операторах обновления, первый — заботится о set1 в примере, а второй — заботится о set2 в примере. затем обновите Qstatus, где QID равен НУЛЮ.
2. Кстати, откуда берется «SetInfo»? Это всего лишь одна таблица TableA. Спасибо
3. SetInfo было общим табличным выражением, которое я создал для группировки по набору и использования в единой логике обновления. Это не другая таблица. Это похоже на временную таблицу, которая существует только на время выполнения запроса. Мне они нравятся больше, чем производные таблицы, потому что они определены выше основного запроса и сохраняют его более чистым. Существуют и другие потенциальные преимущества, такие как рекурсия, многократное присоединение к одному определению, наличие нескольких CTE, где более поздние могут ссылаться на более ранние…
4. ОТЛИЧНО ! Но это работает для набора # 2, тогда как в нем отсутствуют все значения set1. P.S. в QID ДОЛЖНО быть заполнено только одно значение каждого набора.
5. Я не уверен, что происходит сбой. Похоже, он работает с моим тестом, используя ваши данные. Я предполагал, что под «где существует [num] для того же набора» вы подразумевали, что правильные 3 символа Pid соответствуют значению Num в этом наборе. Я не уверен, какую строку вы бы обновили, если бы ни одно из значений num не совпадало. Если вы добавите больше деталей, возможно, я смогу изменить запрос, чтобы приспособить его для вас.