【问题标题】:Using SQL CASE/WHEN output for calculation使用 SQL CASE/WHEN 输出进行计算
【发布时间】:2016-08-17 07:05:11
【问题描述】:

我想使用以下查询将各种货币的金额转换为美元:

SELECT 
    currency, 
    CASE currency 
      WHEN 'SAR' THEN 0.266
      WHEN 'EGP' THEN 0.113
      WHEN 'USD' THEN 1
      WHEN 'JOD' THEN 1.411
      WHEN 'GBP' THEN 1.311
      WHEN 'BHD' THEN 2.652
      WHEN 'AED' THEN 0.272
      WHEN 'EUR' THEN 1.111
      WHEN 'QAR' THEN 0.275
      WHEN 'KWD' THEN 3.315
      ELSE 0 
    END as in_usd,
    SUM(amount)*in_usd as total_in_usd
FROM 
    mytable
WHERE 
    created_at >= current_date - '7 days'::INTERVAL 
GROUP BY 
    currency

这会失败并显示消息in_usd does not exist

预期输出是货币列表及其总数:

currency total_in_usd
USD      100.00
AED      59.00
GBP      143.01
...

【问题讨论】:

    标签: sql amazon-redshift


    【解决方案1】:

    CASE 表达式部分放入派生表中。对结果执行GROUP BY

    select currency, in_usd, SUM(amount) * in_usd as total_in_usd
    from
    (
    SELECT 
        currency, 
        CASE currency 
          WHEN 'USD' THEN 1
          WHEN 'SAR' THEN 0.266
          WHEN 'EGP' THEN 0.113
          WHEN 'USD' THEN 1
          WHEN 'JOD' THEN 1.411
          WHEN 'GBP' THEN 1.311
          WHEN 'BHD' THEN 2.652
          WHEN 'AED' THEN 0.272
          WHEN 'EUR' THEN 1.111
          WHEN 'QAR' THEN 0.275
          WHEN 'KWD' THEN 3.315
          ELSE 0 
        END as in_usd,
        amount
    FROM 
        mytable
    WHERE 
        created_at >= current_date - '7 days'::INTERVAL 
    )
    GROUP BY 
        currency, in_usd
    

    【讨论】:

      【解决方案2】:

      您几乎拥有正确的结构 - 一个小的调整应该可以使其正常工作。求和时乘以货币换算 -

      SELECT 
          currency, 
          SUM(amount)*
            (CASE currency 
                WHEN 'SAR' THEN 0.266
                WHEN 'EGP' THEN 0.113
                WHEN 'USD' THEN 1
                WHEN 'JOD' THEN 1.411
                WHEN 'GBP' THEN 1.311
                WHEN 'BHD' THEN 2.652
                WHEN 'AED' THEN 0.272
                WHEN 'EUR' THEN 1.111
                WHEN 'QAR' THEN 0.275
                WHEN 'KWD' THEN 3.315
                ELSE 0 
            END) as total_in_usd
      FROM 
          mytable
      WHERE 
          created_at >= current_date - '7 days'::INTERVAL 
      GROUP BY 
          currency
      

      【讨论】:

      • 这很好用..而且没有子查询!非常感谢
      【解决方案3】:

      来自documentation

      直到整个目标列表被解析后,别名才会被识别,这意味着您不能在目标列表中的其他地方引用别名。例如,以下语句将失败:

      select (qtysold + 1) as q, sum(q) from sales group by 1;
      ERROR:  column "q" does not exist
      

      您可以使用子选择解决此问题:

      SELECT inner.currency, inner.in_usd, inner.sum_amount*inner.in_usd as total_in_usd
      from (
          SELECT 
              currency, 
              CASE currency 
                WHEN 'SAR' THEN 0.266
                WHEN 'EGP' THEN 0.113
                WHEN 'USD' THEN 1
                WHEN 'JOD' THEN 1.411
                WHEN 'GBP' THEN 1.311
                WHEN 'BHD' THEN 2.652
                WHEN 'AED' THEN 0.272
                WHEN 'EUR' THEN 1.111
                WHEN 'QAR' THEN 0.275
                WHEN 'KWD' THEN 3.315
                ELSE 0 
              END as in_usd,
              SUM(amount) as sum_amount
          FROM 
          mytable
      WHERE 
          created_at >= current_date - '7 days'::INTERVAL 
      GROUP BY 
          currency) inner
      

      【讨论】:

      • 非常好,感谢您提供文档链接!另外,是否可以在 case/when 之外创建一个函数,以便我可以从多个查询中引用它?
      • 我从未在 amazon redshitf 上创建存储函数。但是,根据documentation,SQL 和 python 都可以。
      猜你喜欢
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多