【问题标题】:TSQL query with aggregated data具有聚合数据的 TSQL 查询
【发布时间】:2019-02-08 00:37:48
【问题描述】:

我有一个查询,它返回两种不同产品的最小值、最大值、平均值和总计。然而,客户想要两种产品的最小值、最大值、平均值和总数。但是,当我尝试对这两个产品求和并尝试聚合日期时,我返回了一个不想要的结果。

以下 SQL 查询返回两种产品的单独数据:

SELECT 
   CONVERT(date, DateTimeNow) AS Date,
   MIN(FT1) AS Minimum1 , 
   MAX(FT1) AS Maximum1, 
   AVG(FT1) AS Average1, 
   MAX(FQ1) AS Total1,
   MIN(FT2) AS Minimum2, 
   MAX(FT2) AS Maximum2, 
   AVG(FT2) AS Average2, 
   MAX(FQ2) AS Total2
FROM Data
GROUP BY CONVERT(date, DateTimeNow)
ORDER BY CONVERT(date, DateTimeNow);

然后我将查询修改为以下内容:

SELECT 
    CONVERT(date, DateTimeNow) AS Date,
    MIN(FT1+FT2) AS Minimum , 
    MAX(FT1+FT2) AS Maximum, 
    AVG(FT1+FT2) AS Average, 
    MAX(FQ1+FT2) AS Total
FROM Data
GROUP BY CONVERT(date, DateTimeNow)
ORDER BY CONVERT(date, DateTimeNow);

但是,当我运行第二个查询时,结果并没有加起来。例如,Minimum 不等于第一个查询 Minimum1 + Minimum2

【问题讨论】:

  • 需要一些样本数据和预期输出。

标签: sql sql-server tsql


【解决方案1】:

我强烈建议:

SELECT CONVERT(date, DateTimeNow) AS Date,
       MIN(v.FT) AS Minimum , 
       MAX(v.FT) AS Maximum, 
       AVG(v.FT) AS Average, 
       MAX(v.FQ1) AS Total
FROM Data CROSS APPLY
     (VALUES (FT1, FQ1), (FT2, FQ2)) as v(FT, FQ)
GROUP BY CONVERT(date, DateTimeNow)
ORDER BY CONVERT(date, DateTimeNow);

特别是,这应该正确处理NULL 值。两个值的平均值不一定是两个值的平均值。

【讨论】:

    【解决方案2】:

    我了解到您将每个产品存储在同一张表的不同列中。计算组合最小值、平均值和最大值的逻辑可能如下:

    SELECT 
        CONVERT(date, DateTimeNow) AS Date,
        CASE WHEN MIN(FT1) < MIN(FT2) THEN MIN(FT1) ELSE MIN(FT2) END AS Minimum, 
        CASE WHEN MAX(FT1) > MAX(FT2) THEN MAX(FT1) ELSE MAX(FT2) END AS Maximum, 
        ( AVG(FT1) + AVG(FT2) ) / 2 AS Average,
        SUM(FT1) + SUM(FT2) AS Total
    FROM Data
    GROUP BY CONVERT(date, DateTimeNow)
    ORDER BY CONVERT(date, DateTimeNow);
    

    意思:

    • 最小值是产品 1 的最小值和产品 2 的最小值之间的最小值
    • 最大值是产品1的最大值和产品2的最大值之间的最大值
    • 平均值是产品1的平均值和产品2的平均值的平均值
    • total 是两个查询的总和

    您可以根据您的要求(您没有完全指定)根据需要调整这些规则。

    【讨论】:

    • 谢谢你,虽然不完全是我所追求的,但这有助于引导我朝着正确的方向前进。
    【解决方案3】:

    感谢大家的意见。以下是我所追求的正确查询:

    SELECT 
        CONVERT(date, DateTimeNow) AS Date, MIN(FT1) + MIN(FT2) AS Minimum, 
        MAX(FT1) + MAX(FT2) AS Maximum,
        AVG(FT1) + AVG(FT2) / 2 AS Average,
        MAX(FQ1) + MAX(FQ2) AS Total1
    FROM #rawData
    GROUP BY CONVERT(date, DateTimeNow)
    ORDER BY CONVERT(date, DateTimeNow);
    

    【讨论】:

    • 您在平均计算周围缺少括号:AVG(FT1) + AVG(FT2) / 2 AS Average 应该是 (AVG(FT1) + AVG(FT2)) / 2 AS Average
    【解决方案4】:

    “FROM”子句通过包含您要对其执行操作的两条记录来进行添加。您的日期逻辑没有做任何事情 - 它正在抓取所有日期的所有记录,然后“错误地”始终输入今天的日期。

    SELECT CONVERT(date, DateTimeNow) AS Date, MIN(FT) AS Minimum , MAX(FT) AS Maximum, AVG(FT) AS Average, SUM(FT) AS Total, COUNT(FT) as NumOfRecs
    FROM Data
    WHERE ProductName IN ('FTName1','FTName2')
    GROUP BY CONVERT(date, DateTimeNow)
    ORDER BY CONVERT(date, DateTimeNow);
    

    【讨论】:

      猜你喜欢
      • 2020-06-17
      • 2017-10-27
      • 2010-11-23
      • 2020-11-03
      • 2010-09-14
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多