При использовании левого соединения как представить данные, различающие пустые строковые значения и несуществующие значения? - PullRequest
0 голосов
/ 25 января 2019

Мне нужно создать таблицу со столбцами из разных таблиц в разных средах баз данных, сопоставив их с общим ключом для этих таблиц. Многие из этих значений имеют законную причину быть пустыми, но в некоторых средах они даже не существуют, что является проблемой, которую я должен определить, например, путем вставки пользовательской строки, например, «\\ NULL ///"...

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

Сейчас я пытаюсь написать SQL для представления определенного набора параметров в 2D-таблице (среда и таблица значений параметра x-ref), чтобы идентифицировать проблемные значения, отсутствие некоторых параметров в целом.

SELECT x0.envName,
       x1.param1,
       x2.param2,
       x3.param3
FROM ( ( (
            (SELECT envName
             FROM paramTable
             GROUP BY envName) x0
          LEFT JOIN
            ( SELECT envName,
                     parameterValue AS param1
             FROM paramTable
             WHERE parameterName='param1' ) x1 ON x1.envName = x0.envName )
        LEFT JOIN
          ( SELECT envName,
                   parameterValue AS param2
           FROM paramTable
           WHERE parameterName='param2' ) x2 ON x2.envName = x0.envName )
      LEFT JOIN
        ( SELECT envName,
                 parameterValue AS param3
         FROM paramTable
         WHERE parameterName='param3' ) x3 ON x3.envName = x0.envName)

Если моя таблица параметров выглядит следующим образом:

+ paramTable
=================================================
envName         | paramName     | paramValue    |
-------------------------------------------------
env1            | param1        | abcdef        |
env1            | param2        | 123456        |
env1            | param3        | A73BB2        |
env2            | param1        | klmnop        |
env2            | param2        | 987654        |
env2            | param3        |               |
env3            | param2        | uvwxyz        |

Тогда результирующая таблица из этого запроса не будет различать пустые строковые значения (например, как param3 в env2) от несуществующих значений (например, param1 и param3 в env3):

+ ResultQueryResult
=================================================================
envName         | param1        | param2        | param3        |
-----------------------------------------------------------------
env1            | abcdef        | 123456        | A73BB2        |
env2            | klmnop        | 987654        |               |
env3            |               | uvwxyz        |               |

Я бы хотел изменить SQL таким образом, чтобы в результате запроса я получил что-то вроде этого:

+ PreferedQueryResult
=================================================================
envName         | param1        | param2        | param3        |
-----------------------------------------------------------------
env1            | abcdef        | 123456        | A73BB2        |
env2            | klmnop        | 987654        |               |
env3            | <<<!NULL!>>>  | uvwxyz        | <<<!NULL!>>>  |

Ответы [ 4 ]

0 голосов
/ 25 января 2019

Я пытался переписать ваш запрос:

SELECT x0.envName,
       CASE WHEN x1.parameterName='param1' THEN x1.param1 ELSE '<<!NULL!>>' END AS param1,
       CASE WHEN x1.parameterName='param2' THEN x1.param1 ELSE '<<!NULL!>>' END AS param2,
       CASE WHEN x1.parameterName='param3' THEN x1.param1 ELSE '<<!NULL!>>' END AS param3
FROM (SELECT envName
      FROM paramTable
      GROUP BY envName) x0
        LEFT JOIN paramTable x1
            ON x1.envName = x0.envName
0 голосов
/ 25 января 2019

Включить в результат поле NOT NULL из внутренней таблицы.Затем, когда это поле равно NULL, вы знаете, что внутренняя строка не существует (в отличие от того, что ее NULL-способные поля имеют значение NULL).

При присоединении к первичному ключу, который должен быть NOT NULL, вы можете использовать одно из полей PK (в вашем случае это envName / paramName).В противном случае вы можете просто «придумать» свое поле, отличное от NULL, присоединившись к подзапросу:

...
LEFT JOIN (SELECT 1 inner_exists, <other fields> FROM inner ...) Q
    ON ...

Избегайте использования «магических» значений, так как вы никогда не знаете, могут ли они быть на самом делепредставить в реальных данных.Или, если вы идете по этому пути, используйте что-то, что вряд ли будет присутствовать, например, GUID.

0 голосов
/ 25 января 2019
   DECLARE @paramTable TABLE (envName  varchar(15), parameterName varchar(15), parameterValue varchar(15) )
   INSERT INTO @paramTable (envName, parameterName, parameterValue)
   VALUES 
       ('env1','param1','abcdef') 
      ,('env1','param2','123456') 
      ,('env1','param3','A73BB2') 
      ,('env2','param1','klmnop') 
      ,('env2','param2','987654') 
      ,('env2','param3',''   )  
      ,('env3','param2','uvwxyz') 

   select x0.envName, ISNULL(x1.param1,'<<!NULL!>>') as param1, ISNULL(x2.param2,'<<!NULL!>>') as param2,ISNULL(x3.param3,'<<!NULL!>>') as param3
   from
   (
     (
       (
         (select envName from @paramTable group by envName) x0      
         left join
         (
           select envName, parameterValue as param1 from @paramTable where parameterName='param1'
         ) x1
         on x1.envName = x0.envName
       )

       left join
       (
         select envName, parameterValue as param2 from @paramTable where parameterName='param2'
       ) x2
       on x2.envName = x0.envName
     )

     left join (
       select envName, parameterValue as param3 from @paramTable where parameterName='param3'
     ) x3
     on x3.envName = x0.envName
   )

Результат:

           envName         param1          param2          param3
    --------------- --------------- --------------- ---------------
    env1            abcdef          123456          A73BB2
    env2            klmnop          987654          
    env3            <<!NULL!>>      uvwxyz          <<!NULL!>>
0 голосов
/ 25 января 2019

Вы можете просто использовать специальную константу, такую ​​как <<<!NULL!>>> и изменить:

select paramValue

от

select nvl(paramValue,'<<<!NULL!>>>')

ИЛИ добавить логические столбцы (для каждого параметра):

заменить

select paramValue

от

select
    case when paramValue is null
    then True
    else False
    end as isParamValueNull,
    paramValue
...