Есть ли оператор CASE, который нужно применить к нескольким столбцам, чтобы аналогичное выходное значение было изменено на другое (но другое) подобное значение? - PullRequest
2 голосов
/ 23 марта 2019

У меня есть несколько столбцов с надписью «Не указано». Я бы хотел, чтобы они были пустыми.

Есть ли лучший способ применить оператор case к моему ВСЕМУ запросу, а не к каждой строке, если я хочу изменить одно и то же значение в разных столбцах? В настоящее время мой запрос выглядит так (плюс несколько столбцов):

       SELECT  
         [user_name]
        ,[employee_number]
        ,CASE [veteran_status] WHEN 'not specified' THEN ''
         ELSE veteran_status
         END AS veteran_status

        ,CASE [ethnic_origin] WHEN 'not specified' THEN ''
       ELSE ethnic_origin 
       END AS ethnic_origin

         ,CASE [gender] WHEN 'not specified' THEN ''
       ELSE gender
       END AS gender

        FROM table.HR

Я получаю правильный вывод с инструкциями case, но хочу посмотреть, есть ли более эффективный способ применить CASE к массовому количеству.

Ответы [ 4 ]

1 голос
/ 23 марта 2019

Ну, вы можете объединить операторы UNPIVOT и PIVOT следующим образом:

with t1 as (
select user_name
     , employee_number
     , col
     , nullif(value,'not specified') value
  from HR unpivot(value for col in (veteran_status, ethnic_origin, gender)) as x
)
select *
  from t1
  pivot (max(value) for col in (veteran_status, ethnic_origin, gender)) x;

Если ваши столбцы не относятся к одному и тому же типу данных, вам может потребоваться предварительно подготовить их, приведя их к одному и тому же типу данных:

with t0 as (
select user_name
     , employee_number
     , cast(veteran_status as varchar(30)) veteran_status 
     , cast(ethnic_origin as varchar(30)) ethnic_origin 
     , cast(gender as varchar(30)) gender
  from HR
), t1 as (... from t1 ...)
...

Однако, это может быть ЛОТ работы для чего-то легко достижимого более обычными способами.

0 голосов
/ 24 марта 2019

Следующее решение будет работать, когда вы также захотите разрешить NULL с тем же значением.Вам все равно нужно будет добавить это к каждому столбцу, на который есть ссылка, но он использует меньше кода и снижает избыточность в целом.

ISNULL(NULLIF([veteran_status], ‘not specified’), ‘’) AS [veteran_status]
0 голосов
/ 23 марта 2019

Невозможно использовать один принцип (логику) для нескольких / всех столбцов оператора выбора, не помещая их для каждого столбца.

Что вы можете сделать, так это написать альтернативы, которые болеекраткое, чем CASE утверждение.Исходя из вашего стиля запросов, я полагаю, вы используете сервер MS SQL, вот одна альтернатива для MS SQL Server

SELECT  
     [user_name]
    ,[employee_number]
    ,iif([veteran_status] = 'not specified', '', [veteran_status]) veteran_status
    ,iif([ethnic_origin] = 'not specified', '', [ethnic_origin]) ethnic_origin
    ,iif([gender] = 'not specified', '', [gender]) gender
FROM table.HR

Для Oracle есть аналогичная функция под названием decode , Mysql эквивалент называется , если

При этом CASE - это стандартный ANSII SQL, доступный во всех базах данных.Выбор за вами.

0 голосов
/ 23 марта 2019

Вы можете присоединить таблицу к себе, исключая столбцы «не указано». Однако огромного выигрыша нет, это альтернативная перспектива.

SELECT  
         user_name
        ,employee_number
        ,veteran_status
        ,ethnic_origin
        ,gender

FROM table.HR hr
        LEFT JOIN table.HR hrvs ON hrvs.employee_number = hr.employee_number  AND hrvs.veteran_status <> 'not specified'
        LEFT JOIN table.HR hreo ON hreo.employee_number = hr.employee_number  AND hreo.ethnic_origin <> 'not specified'
        LEFT JOIN table.HR hrge ON hrge.employee_number = hr.employee_number  AND hrge.gender <> 'not specified'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...