【问题标题】:How do you filter mathematically calculated data in SQL?如何在 SQL 中过滤数学计算的数据?
【发布时间】:2013-07-30 23:53:51
【问题描述】:

这可能比我想象的要容易,但我很难过。我写了下面的查询,它总结了客户在特定商店的所有购买,以及同一客户在同一商店的退货总额,最后,存储从总退货中减去总退货的结果在名为 TOTAL_SPENT 的计算列中购买。这是我的查询:

SELECT Account_Id,
  SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) AS TOTAL_PURCHASED,
  SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END) AS TOTAL_RETURNED,
  (TOTAL_PURCHASED - TOTAL_RETURNED) AS TOTAL_SPENT
FROM Transactions_Table
WHERE Store = 'Store XYZ'
GROUP BY Account_Id
ORDER BY TOTAL_SPENT DESC

我的问题是这个查询返回了数十万条记录,但我只关心大约 10% 的返回数据。因此,假设您只想查看 TOTAL_SPENT >= 500.00 的返回数据。但是对于我的生活,我无法弄清楚如何做到这一点! 羞愧地垂下头

【问题讨论】:

    标签: sql logic arithmetic-expressions


    【解决方案1】:

    在 SQL 中,WHERE 子句在SELECT 子句之前处理。因此,当 SQL 开始过滤表中与查询相关的行时,它还不知道列 TOTAL_SPENT。

    有几种方法可以解决这个问题。

    1) 在WHERE 子句中重复表达式,而不是在SELECT 子句中引用列名:

    SELECT Account_Id,
      SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) AS TOTAL_PURCHASED,
      SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END) AS TOTAL_RETURNED,
      (TOTAL_PURCHASED - TOTAL_RETURNED) AS TOTAL_SPENT
    FROM Transactions_Table
    WHERE Store = 'Store XYZ'
    GROUP BY Account_Id
    ORDER BY 
      (SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) - SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END)) DESC
    

    注意:如果您要查找 TOTAL_SPENT 高于 500 的 组,请使用 HAVING 子句而不是 WHERE。

    2) 使用视图。删除您的 WHERE 子句并使用您的查询创建一个 VIEW。然后,从该视图中选择并添加您的WHERE 子句。

    CREATE VIEW Whatever AS
       SELECT Account_Id,
          SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) AS    TOTAL_PURCHASED,
          SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END) AS TOTAL_RETURNED,
          (TOTAL_PURCHASED - TOTAL_RETURNED) AS TOTAL_SPENT
       FROM Transactions_Table
       GROUP BY Account_Id;
    
    SELECT * From Whatever WHERE TOTAL_SPENT >= 500
    

    3) 使用嵌套的 SELECT:

    select * from (
      SELECT
        Account_Id,
        SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) AS TOTAL_PURCHASED,
        SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END) AS TOTAL_RETURNED,
        (TOTAL_PURCHASED - TOTAL_RETURNED) AS TOTAL_SPENT
      FROM Transactions_Table
      WHERE Store = 'Store XYZ'
      GROUP BY Account_Id
    ) where TOTAL_SPENT > 500 ORDER BY TOTAL_SPENT DESC;
    

    4) 如果您的数据库支持,请使用 CTE:

    WITH MyQuery AS (
      SELECT
        Account_Id,
        SUM(CASE WHEN Transaction_Code = 'Purchase' THEN Transaction_Amount ELSE 0 END) AS TOTAL_PURCHASED,
        SUM(CASE WHEN Transaction_Code = 'Return' THEN Transaction_Amount ELSE 0 END) AS TOTAL_RETURNED,
        (TOTAL_PURCHASED - TOTAL_RETURNED) AS TOTAL_SPENT
      FROM Transactions_Table
      WHERE Store = 'Store XYZ'
      GROUP BY Account_Id
    )
    SELECT * FROM MyQuery WHERE TOTAL_SPENT > 500 ORDER BY TOTAL_SPENT DESC;
    

    【讨论】:

    • 谢谢您,先生!我尝试按照您的建议创建视图,但不幸的是,我没有获得足够高的访问级别来创建视图。我接下来尝试了嵌套选择,它给了我正在寻找的确切结果。
    猜你喜欢
    • 2022-07-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    相关资源
    最近更新 更多