Отображение нулевых значений в соединениях SQL Server

#sql-server #tsql #join

#sql-сервер #tsql #Присоединиться

Вопрос:

Я использую SQL Server. У меня есть 3 таблицы :

  1. tblUser
  2. tblAudit
  3. tblEnum

В tblAudit есть 4 столбца :

nUserId, nID: эти два столбца указывают на tblUser

vFromValue, vToValue: эти два столбца указывают на tblEnum

Теперь мне нужно показать фактические значения из tblUser и tblEnum на основе идентификаторов, присутствующих в таблице tblAudit. Запрос, который я написал, выглядит примерно так :

 SELECT A.aEventID,
U.tName AS MakerChecker,
U2.tName AS OnUser,
VLE.tDisplayName AS FromValue,
VLE2.tDisplayName AS ToValue,
A.dChangeTime AS Timestamp
FROM tblAudit A INNER JOIN tblUser U ON A.nUserId = U.aUserId
INNER JOIN tblUser U2 ON A.nID = U2.aUserId
INNER JOIN tblEnum VLE ON A.vFromValue = VLE.nIndex OR (A.vFromValue IS NULL)
INNER JOIN tblEnum VLE2 ON  A.vToValue = VLE2.nIndex OR (A.vToValue IS NULL)
  

Поскольку значения в таблице аудита имеют значение null для столбцов vFromValue и vToValue для некоторых строк, эти значения отображаются не как NULL, а как предыдущее значение.
Как я могу отобразить нулевые значения без изменений, изменив приведенный выше запрос? Пожалуйста, помогите.

Ответ №1:

Поскольку у tblAudit.vFromValue и tblAudit.vToValue есть NULL s, попробуйте это:

 SELECT A.aEventID,
       U.tName AS MakerChecker,
       U2.tName AS OnUser,
       VLE.tDisplayName AS FromValue,
       VLE2.tDisplayName AS ToValue,
       A.dChangeTime AS Timestamp
FROM 
     ( SELECT aEventID, nUserId, nID, dChangeTime  
            , COALESCE(vFromValue, -9999) AS vFromValue   --- some non-existent
            , COALESCE(vToValue, -999) AS vToValue        --- value
       FROM tblAudit
     ) AS A 
  INNER JOIN tblUser U
    ON A.nUserId = U.aUserId
  INNER JOIN tblUser U2 
    ON A.nID = U2.aUserId
  LEFT JOIN tblEnum VLE 
    ON A.vFromValue = VLE.nIndex
  LEFT JOIN tblEnum VLE2 
    ON  A.vToValue = VLE2.nIndex
  

или это:

 SELECT A.aEventID,
       U.tName AS MakerChecker,
       U2.tName AS OnUser,
       ( SELECT VLE.tDisplayName
         FROM tblEnum VLE 
         WHERE A.vFromValue = VLE.nIndex
       ) AS FromValue,
       ( SELECT VLE2.tDisplayName
         FROM tblEnum VLE2 
         WHERE A.vToValue = VLE.nIndex
       ) AS ToValue,
       A.dChangeTime AS Timestamp
FROM tblAudit AS A 
  INNER JOIN tblUser U
    ON A.nUserId = U.aUserId
  INNER JOIN tblUser U2 
    ON A.nID = U2.aUserId
  

Ответ №2:

Если я понимаю ваш вопрос — попробуйте использовать ЛЕВОЕ СОЕДИНЕНИЕ для двух последних строк (и удалите условия после ИЛИ).

Комментарии:

1. Сделал это 🙂 Не помогло. Однако вместо этого я попытался что-то еще, что решило проблему, но я думаю, что это не чистое решение, а служит цели. Публикуем это как ответ. Если кто-нибудь найдет лучшее решение, пожалуйста, опубликуйте его. Спасибо.