Sql 是否有一个CASE语句应用于多个列,以便将一个相似的输出值更改为另一个(但不同)相似的值?

Sql 是否有一个CASE语句应用于多个列,以便将一个相似的输出值更改为另一个(但不同)相似的值?,sql,sql-server,case,Sql,Sql Server,Case,我有几列没有指定。我希望它们是空白的 如果我希望更改不同列中的相同值,是否有更好的方法将case语句应用于整个查询而不是每一行?当前,我的查询如下所示,再加上几列: SELECT [user_name] ,[employee_number] ,CASE [veteran_status] WHEN 'not specified' THEN '' ELSE veteran_status END A

我有几列没有指定。我希望它们是空白的

如果我希望更改不同列中的相同值,是否有更好的方法将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应用于大量数据。

您可以将表本身连接起来,不包括“未指定”列。然而,这并不是一个巨大的收获,而是另一种观点

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'

您可以将表连接到自身,不包括“未指定”列。然而,这并不是一个巨大的收获,而是另一种观点

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'
您可以这样组合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 ...)
...
但是,这可能需要大量工作才能通过更传统的方法轻松实现。

您可以将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 ...)
...

但是,这可能需要大量的工作才能通过更传统的方法轻松实现。

没有任何方法可以将一个原则逻辑应用于select语句的多个/所有列,而不将它们应用于每一列

不过,您可以做的是编写比CASE语句更简洁的备选方案。从您的查询风格来看,我猜您使用的是MS SQL server,下面是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,如果


也就是说,CASE是标准的ANSII-SQL,在所有数据库中都可用。您可以选择。

您无法将一个原则逻辑应用于select语句的多个/所有列,而不将它们应用于每一列

不过,您可以做的是编写比CASE语句更简洁的备选方案。从您的查询风格来看,我猜您使用的是MS SQL server,下面是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,如果


也就是说,CASE是标准的ANSII-SQL,在所有数据库中都可用。您可以选择。

当您还希望解析具有相同值的空值时,以下解决方案将起作用。您仍然需要将其添加到引用的每个列中,但它使用的代码更少,总体上减少了冗余

ISNULL(NULLIF([veteran_status], ‘not specified’), ‘’) AS [veteran_status]

当您还希望解析具有相同值的空值时,以下解决方案将起作用。您仍然需要将其添加到引用的每个列中,但它使用的代码更少,总体上减少了冗余

ISNULL(NULLIF([veteran_status], ‘not specified’), ‘’) AS [veteran_status]

如果您对NULL感到满意,我认为这是有意义的,因为NULL表示未知,未指定也表示值未知;aka unknown你可以使用NULLIF,否则不,这是你将要得到的最简洁的。如果你对NULL感到满意,在我看来这是有意义的,因为NULL意味着未知,未指定也意味着值未知;aka unknown您可以使用NULLIF,否则不行,这是您将得到的最简洁的答案。这个答案是错误的。它不会产生相同的结果,因为海报的尝试不会消除像您这样的行,而是简单地显示一个空字符串,而不是为一个或多个列指定。为列显示不同的值与完全删除行之间存在差异。此查询将不会产生所需的结果。此答案是错误的。它不会产生相同的结果,因为海报的尝试不会消除像您这样的行,而是简单地显示一个空字符串,而不是为一个或多个列指定。为列显示不同的值与完全删除行之间存在差异。此查询不会产生所需的结果