【问题标题】:Calculated rows in SQLSQL 中的计算行
【发布时间】:2018-11-09 21:48:17
【问题描述】:

我有一个表,其中有一个名为 metrics 的列,它有不同的可能指标:

Metric  Value
--------------
A       100
B       200
C       300

我想从这个基表中派生出另一个表,它可能有如下行:

Metric  Value
--------------
A       100
B       200
C       300
C/A     3
B/A     2

基本上保持原始行不变 + 根据现有值的组合添加一些新行。

我能想到的一种方法是: 1. 透视数据 2.把它放在一些临时表或CTE中 3.选择所有现有的指标列+我需要的新计算列 4. unpivot 最后一步的输出

有没有更好的方法来使用 SQL 实现这一点?或者也许任何其他可能的方式? 另外,redshift 不支持 Pivot 功能,除了使用 Case Statements 之外,还有其他解决方法吗?

【问题讨论】:

  • 您使用的是 Amazon Redshift、MS SQL Server 还是 PostgreSQL?
  • 你考虑过使用过程吗?
  • 我删除了不兼容的数据库标签。
  • 将额外的行放入第二个表中,为两个表的并集创建一个视图。
  • @jmelesky - 我同时使用 Redshift PostgreSQL 和 SQL Server,因此我有兴趣找到适用于两者或两者之一的解决方案。

标签: sql


【解决方案1】:

您可以将表格与自身连接起来,并将该操作应用于您喜欢的指标对。并且UNION ALL 包含原始指标的表格。

您的示例的一种可能性是(假设 Postgres):

SELECT metric,
       value
       FROM metrics
UNION ALL
SELECT concat(m1.metric, '/', m2.metric),
       m1.value / m2.value
       FROM metrics m1
            CROSS JOIN metrics m2
       WHERE (m1.metric,
              m2.metric) IN (('C',
                              'A'),
                             ('B',
                              'A'));

SQL Fiddle

当然,这可以扩展到三元,...通过添加另一个连接和几个不同的操作,通过添加其他查询和UNIONing 他们。

【讨论】:

    【解决方案2】:
    select 
    case when x1.metric = x2.metric 
        then x1.metric 
    else x1.metric || ' / ' || x2.metric end,
    case when x1.metric = x2.metric 
        then x1.value 
    else x1.value / x2.value end
    
    from mytable x1
    join mytable x2
      on x1.metric = x2.metric or x2.metric = 'A'
    

    这是一种方法,它使用纯标准的 sql。但是请注意,不同的 RDMBS 软件具有不同级别的标准一致性,并且可能不支持此处使用的某些功能。具体来说,字符串连接运算符|| 并非在所有数据库中都实现。一些数据库使用concat+函数代替。

    【讨论】:

      猜你喜欢
      • 2015-05-09
      • 1970-01-01
      • 2023-03-23
      • 2021-06-30
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多