SELECT..CASE - Рефакторинг T-SQL - PullRequest
1 голос
/ 10 июня 2010

Могу ли я реорганизовать приведенные ниже операторы SQL CASE в отдельные для каждого случая?

SELECT 
  CASE RDV.DOMAIN_CODE  WHEN 'L' THEN CN.FAMILY_NAME  ELSE NULL END AS [LEGAL_FAMILY_NAME],
  CASE RDV.DOMAIN_CODE  WHEN 'L' THEN CN.GIVEN_NAME  ELSE NULL END AS [LEGAL_GIVEN_NAME],
  CASE RDV.DOMAIN_CODE  WHEN 'L' THEN CN.MIDDLE_NAMES  ELSE NULL END AS [LEGAL_MIDDLE_NAMES],
  CASE RDV.DOMAIN_CODE  WHEN 'L' THEN CN.NAME_TITLE  ELSE NULL END AS [LEGAL_NAME_TITLE],

  CASE RDV.DOMAIN_CODE  WHEN 'P' THEN CN.FAMILY_NAME  ELSE NULL END AS [PREFERRED_FAMILY_NAME],
  CASE RDV.DOMAIN_CODE  WHEN 'P' THEN CN.GIVEN_NAME  ELSE NULL END AS [PREFERRED_GIVEN_NAME],
  CASE RDV.DOMAIN_CODE  WHEN 'P' THEN CN.MIDDLE_NAMES  ELSE NULL END AS [PREFERRED_MIDDLE_NAMES],
  CASE RDV.DOMAIN_CODE  WHEN 'P' THEN CN.NAME_TITLE  ELSE NULL END AS [PREFERRED_NAME_TITLE]

FROM dbo.CLIENT_NAME CN
JOIN dbo.REFERENCE_DOMAIN_VALUE RDV 
ON CN.NAME_TYPE_CODE = RDV.DOMAIN_CODE AND RDV.REFERENCE_DOMAIN_ID = '7966'

Ответы [ 4 ]

1 голос
/ 10 июня 2010

Нет, вам потребуется 8 отдельных операторов как case, а другие подобные варианты можно использовать только в select для изменения результатов одного столбца, а не ряда столбцов.

1 голос
/ 10 июня 2010

Поскольку выражение CASE возвращает одно значение, вы не можете взять восемь выражений CASE, возвращающих 8 значений, и создать одно выражение CASE, которое возвращает все восемь.

1 голос
/ 10 июня 2010

Если RDV.DOMAIN_COD может только с помощью 'P' или 'L' использовать NULLIf.Это чище.

NULLIF ( expression , expression )

NULLIF эквивалентно искомому выражению CASE, в котором два выражения равны, а полученное выражение равно NULL.

SELECT
NullIf('P', RDV.DOMAIN_CODE) AS [LEGAL_FAMILY_NAME],
...
NullIf('L', RDV.DOMAIN_CODE) AS [PREFERRED_FAMILY_NAME],
...
0 голосов
/ 24 июня 2010

Менее эффективная альтернатива без случаев:

SELECT LEGAL_FAMILY_NAME, LEGAL_GIVEN_NAME, LEGAL_MIDDLE_NAMES, LEGAL_NAME_TITLE,
       PREFERRED_FAMILY_NAME, PREFERRED_GIVEN_NAME, PREFERRED_MIDDLE_NAMES, PREFERRED_NAME_TITLE
FROM dbo.REFERENCE_DOMAIN_VALUE RDV
LEFT OUTER JOIN
  ( SELECT
      NAME_TYPE_CODE, 
      FAMILY_NAME AS [LEGAL_FAMILY_NAME],
      GIVEN_NAME AS [LEGAL_GIVEN_NAME],
      MIDDLE_NAMES AS [LEGAL_MIDDLE_NAMES],
      NAME_TITLE AS [LEGAL_NAME_TITLE]
    FROM dbo.CLIENT_NAME
    WHERE NAME_TYPE_CODE = 'L') LN ON RDV.DOMAIN_CODE = LN.NAME_TYPE_CODE
LEFT OUTER JOIN
  ( SELECT
      NAME_TYPE_CODE, 
      FAMILY_NAME AS [PREFERRED_FAMILY_NAME],
      GIVEN_NAME  AS [PREFERRED_GIVEN_NAME],
      MIDDLE_NAMES AS [PREFERRED_MIDDLE_NAMES],
      NAME_TITLE AS [PREFERRED_NAME_TITLE]
    FROM dbo.CLIENT_NAME
    WHERE NAME_TYPE_CODE = 'P') PN ON RDV.DOMAIN_CODE = PN.NAME_TYPE_CODE
  WHERE RDV.REFERENCE_DOMAIN_ID = '7966'

Вы также можете использовать временную таблицу или табличную переменную со всеми 8 столбцами, а затем выполнить две вставки. Вы также можете использовать UNION ALL. Я предполагаю, что 8 случаев являются наиболее эффективным способом. Это особенно верно, если у вас есть какой-то ключ, для которого вам понадобится некоторый тип ClientID, юридические имена, предпочтительные имена, чтобы вы обернули MAX вокруг дел или чего-то еще и сгруппировали по ClientID ......

Вы можете сгенерировать скрипт SQL, используя syscols / INFORMATION_SCHEMA.columns с двумя случаями, когда для каждого столбца 'CASE WHEN DOMAIN_CODE =' 'P' 'THEN' + COLUMN_NAME + 'ELSE NULL END AS PREFERRED_' + COLUMN_NAME, а затем другой для L. Вы можете сделать LOOP так, чтобы один и тот же код выполнялся один раз для P и один раз для L и перевести его в один цикл. Затем вы можете выполнить EXEC-строку напрямую или распечатать ее и вставить в свой сценарий SQL. В любом случае, всего для 8 столбцов я бы вырезал / вставил выражения case ...

Но, в любом случае, T-SQL в целом ограничен способностью выполнять кеширование по столбцам. Либо вы генерируете скрипт, используя генератор кода (сделанный на t-sql или другом языке программирования), либо вы переосмысливаете свою проблему другим способом. Но во многих случаях вы получаете лучшую производительность благодаря дублированию кода вырезания / вставки. И во многих случаях не стоит создавать внешний генератор кода (т.е. только для 8 операторов case).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...