SQL SERVER: заполнение столбца на основе других других столбцов

#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] .

  1. Если для любого набора существует какое-либо значение в [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
  
  1. если для какого-либо набора не найдено ни одного [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 не совпадало. Если вы добавите больше деталей, возможно, я смогу изменить запрос, чтобы приспособить его для вас.