Sql 根据一个条件选择多个列

Sql 根据一个条件选择多个列,sql,postgresql,select,case,conditional-statements,Sql,Postgresql,Select,Case,Conditional Statements,有没有办法根据一个条件生成多个列?我的看法是: SELECT CASE WHEN condition_column = 'condition true' and (condition_column2 = 'condition true' or condition_column3 = 'condition true') THEN column1 as new_column1 AND column2 as new_column2 AND column3 as new_column3 ELSE

有没有办法根据一个条件生成多个列?我的看法是:

SELECT

CASE WHEN condition_column = 'condition true' and (condition_column2 = 'condition true' or condition_column3 = 'condition true')

THEN column1 as new_column1
AND column2 as new_column2
AND column3 as new_column3

ELSE column2 as new_column1
AND column3 as new_column2
AND column1 as new_column3
我目前的做法是:

SELECT

CASE WHEN condition_column = 'condition true' and (condition_column2 = 'condition true' or condition_column3 = 'condition true')
THEN column1 ELSE column2 END AS new_column1,

CASE WHEN condition_column = 'condition true' and (condition_column2 = 'condition true' or condition_column3 = 'condition true')
THEN column2 ELSE column3 END AS new_column2,

CASE WHEN condition_column = 'condition true' and (condition_column2 = 'condition true' or condition_column3 = 'condition true')
THEN column3 ELSE column1 END AS new_column3

但在复杂的情况下,这将成为一个非常长的语句列表。

你必须尝试一种完全不同的方法其中一个

CTE/
左连接
/
全部联合
  • 选择列表中第一个案例的所有列
  • 从第二个案例中排除已选择的行
  • 使用CTE联合所有
  • tbl_id
    是此场景中的主键

    排列 数组只能保存相同基类型的值。如果所有相关列共享同一类型,则可以基于单个条件选择整个数组。要再次取消数组的测试,请使用如下子查询:

    SELECT tbl_id, a[1] AS new1, a[2] AS new2
    FROM (
       SELECT tbl_id, CASE WHEN TRUE THEN ARRAY[col1, col2]
                                     ELSE ARRAY[col2, col3] END AS a
       FROM   tbl
       ) x;
    
    如果您有不同类型的列,您可以将所有列强制转换为相同类型,通常是
    文本(也可以选择强制转换)到下一级别:

    SELECT tbl_id, a[1] AS new1, a[2] AS new2
    FROM (
       SELECT tbl_id, CASE WHEN TRUE THEN ARRAY[col1::text, col2::text]
                                     ELSE ARRAY[col2::text, col3::text] END AS a
       FROM   tbl
       ) x;
    
    记录 为了避免子查询级别和强制转换类型,可以使用记录类型。这里的障碍是Postgres只能使用最新的注册(已知)记录类型

    
    SELECT tbl_id, (CASE WHEN TRUE THEN (col1::text, col2::int)
                                   ELSE (col2::text, col3::int) END).*
    FROM   tbl;
    但是您可以使用注册的记录类型,例如隐式创建的表或视图类型或显式创建的记录类型。为了演示,我显式创建了一个类型:

    CREATE TYPE foo AS (new1 text, new2 int);
    
    然后,您可以基于单个
    大小写
    表达式选择多个列,并在同一步骤中取消对记录的测试:

    SELECT tbl_id, (CASE WHEN TRUE THEN (col1::text, col2::int)::foo
                                   ELSE (col2::text, col3::int)::foo END).*
    FROM   tbl;
    
    适用于任何类型的列(即使是相同类型的列)。括号是必需的

    对于临时查询,您不必保留新类型。改为创建一个临时表,该表随会话一起消失:

    CREATE TEMP TABLE foo (new1 text, new2 int);
    SELECT ...
    
    SELECT tbl_id, (CASE WHEN TRUE THEN (col1::text, col2::int)::foo
                                   ELSE (col2::text, col3::int)::foo END).*
    FROM   tbl;
    
    CREATE TEMP TABLE foo (new1 text, new2 int);
    SELECT ...