【问题标题】:How to append a column data to a MAX Aggregate function in SQL?如何将列数据附加到 SQL 中的 MAX 聚合函数?
【发布时间】:2016-01-15 20:01:21
【问题描述】:

列名:namereadingchanneltime

我目前正在尝试查找每个不同 name 的最大值。每个name 都有许多值,因为它以每小时一次的时间间隔读取。目标是找出每个不同name 的最大值并记录它发生的时间间隔。

到目前为止,我已经得到了这个代码:

 SELECT name, max(reading) AS "max_reading", data, channel, time 
 FROM interval_data 
 GROUP BY name, data, channel

但是,这给了我一个错误,说 time 必须被聚合或分组。有没有什么简单的方法可以将最大值出现的时间附加到输出中,而不必对列执行分组/聚合函数?


样本数据:

NAME    READING     DATA    CHANNEL     TIME
1       1           1       1           1/15/2015 09:00
1       3           1       1           1/15/2015 10:00
1       2           1       1           1/15/2015 11:00
1       5           1       1           1/15/2015 12:00
2       2           1       1           1/15/2015 09:00
2       4           1       1           1/15/2015 10:00
2       6           1       1           1/15/2015 11:00
2       5           1       1           1/15/2015 12:00
3       7           1       1           1/15/2015 09:00
3       3           1       1           1/15/2015 10:00
3       5           1       1           1/15/2015 11:00
3       2           1       1           1/15/2015 12:00

期望的输出:(每个不同名称的最大读数和最大读数发生时的时间)

NAME    READING     DATA    CHANNEL     TIME
1       5           1       1           1/15/2015 12:00
2       6           1       1           1/15/2015 11:00
3       7           1       1           1/15/2015 09:00

【问题讨论】:

  • 你在用什么rdbms
  • 时间列不在您的group by 子句中。
  • 如果您能提供示例数据和所需的输出,将会很有帮助。不确定是否仅将 TIME 列添加到 group by 子句会解决您的问题
  • @RichardHamilton 它将解决错误,但会产生 OP 所需的输出。这是我的担心。
  • 我没有解决这个问题,因为“时间”可能是一个时间戳,他将获得与不使用 MAX 时相同数量的行

标签: sql


【解决方案1】:

在不知道DATACHANNEL 是如何发挥作用的情况下,您可以使用类似的方法来查找每个NAMEMAX(READING) 所需的数据:

SELECT
    id.NAME, id.READING, id.DATA, id.CHANNEL, id.TYPE
FROM 
    INTERVAL_DATA id
JOIN (
    SELECT 
        NAME, MAX(READING) AS READING
    FROM 
        INTERVAL_DATA
    GROUP BY
        NAME
    ) id_agg
    ON 
    id.NAME = id_agg.NAME 
    AND 
    id.READING = id_agg.READING    

如果您需要CHANNELTYPE 来区分唯一行,请将它们包含在内连接子查询和连接的ON 参数中。

【讨论】:

  • 子查询中缺少分组方式
  • @Nimesh:谢谢,已修复。
【解决方案2】:

有,但不是在单个查询中,因为将 time 添加到 GROUP BY 子句会使您的查询无用。

因此,在子查询中获取合理分组所需的所有字段。加入此子查询并获取所有分组字段、您的 max_reading 以及最终来自 interval_data 的时间。

【讨论】:

  • 这是一个恰当的解决方案
【解决方案3】:

选择需要一些技巧。可能是这样的:

Select B.NAME, A."Max_READING", B.DATA, B.CHANNEL, B.TIME
    From INTERVAL_DATA B INNER JOIN 
        ( Select NAME, Max(READING) As "Max_READING", DATA, CHANNEL
        From INTERVAL_DATA Group By NAME, DATA, CHANNEL) A ON B.NAME = A.NAME AND B.DATA = A.DATA AND B.CHANNEL = A.CHANNEL

这里有类似的问题:SQL Select only rows with Max Value on a Column

【讨论】:

    【解决方案4】:

    您实际上不需要执行 GROUP BY 子句,您可以使用 WHERE 子句中的子查询获取 MAX(Reading) 值:

      IF OBJECT_ID('tempdb.dbo.#T','U') IS NOT NULL
        DROP TABLE #T
    
    CREATE TABLE #T
        (NAME VARCHAR(50) NOT NULL,
        CHANNEL VARCHAR(50) NOT NULL,
        DATA VARCHAR(50) NOT NULL,
        READING INT NOT NULL,
        [TIME] DATETIME NOT NULL)
    
    INSERT INTO #T
        (NAME, CHANNEL, DATA, READING, [TIME])
    VALUES
        ('Oscar','NBC', 'green', 1, '2015-01-01'),
        ('Oscar','NBC', 'green', 200, '2015-01-02'),
        ('Oscar','NBC', 'green', 3, '2015-01-03'),
        ('Oscar','NBC', 'red', 4, '2015-01-01'),
        ('Oscar','NBC', 'red', 5, '2015-01-02'),
        ('Oscar','NBC', 'red', 62, '2015-01-03'),
        ('Oscar','CNN', 'red', 7, '2015-01-01'),
        ('Oscar','CNN', 'red', 8, '2015-01-02'),
        ('Oscar','CNN', 'red', 9, '2015-01-03'),
        ('Luke','NBC', 'green', 1, '2015-01-01'),
        ('Luke','NBC', 'green', 2, '2015-01-02'),
        ('Luke','NBC', 'green', 3, '2015-01-03'),
        ('Luke','NBC', 'red', 4, '2015-01-01'),
        ('Luke','NBC', 'red', 5, '2015-01-02'),
        ('Luke','NBC', 'red', 6, '2015-01-03'),
        ('Luke','CNN', 'red', 7, '2015-01-01'),
        ('Luke','CNN', 'red', 88, '2015-01-12'),
        ('Luke','CNN', 'red', 9, '2015-01-22'),
        ('George','NBC', 'green', 1, '2015-01-01'),
        ('George','NBC', 'green', 2, '2015-01-02'),
        ('George','NBC', 'green', 3, '2015-01-09'),
        ('George','NBC', 'red', 4, '2015-01-01'),
        ('George','NBC', 'red', 5, '2015-01-02'),
        ('George','NBC', 'red', 6, '2015-01-03'),
        ('George','CNN', 'red', 7, '2015-01-01'),
        ('George','CNN', 'red', 8, '2015-01-02'),
        ('George','CNN', 'red', 11, '2015-01-15')
    
    --Provides the Max Reading for each Name
    SELECT t.NAME, t.CHANNEL, t.DATA, t.READING, t.[TIME]
    FROM #t AS t
    WHERE
        t.reading = (SELECT MAX(sub.reading)
                    FROM #t AS sub
                    WHERE
                        sub.NAME = t.NAME)
    --Provides the Max Reading for each name, channel, and data grouping
    SELECT t.NAME, t.CHANNEL, t.DATA, t.READING, t.[TIME]
    FROM #t AS t
    WHERE
        t.reading = (SELECT MAX(sub.reading)
                    FROM #t AS sub
                    WHERE
                        sub.NAME = t.NAME
                        AND
                        sub.CHANNEL = t.CHANNEL
                        AND
                        sub.DATA = t.DATA);
    

    第一个查询为您提供每个不同名称的最大读数和时间,而第二个查询提供每个不同名称、通道和数据的最大读数和时间。

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-31
      • 2015-05-19
      • 1970-01-01
      • 2021-11-14
      • 2020-12-10
      相关资源
      最近更新 更多