如何将列数据附加到SQL中的MAX Aggregate函数?

时间:2016-01-15 20:01:21

标签: sql

列名: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

所需输出:(当发生最大读数读数时,每个不同名称的最大读数为TIME)

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

4 个答案:

答案 0 :(得分:1)

但是在单个查询中没有,因为在time子句中添加GROUP BY会导致查询失效。

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

答案 1 :(得分:1)

在不知道DATACHANNEL如何发挥作用的情况下,您可以使用类似的内容来查找每个NAME MAX(READING)所需的数据:< / p>

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参数中包含这些行。

答案 2 :(得分:0)

选择需要一些fiddeling。也许有点像这样:

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

答案 3 :(得分:0)

您不需要执行GROUP BY子句,只需使用WHERE子句中的子查询获取MAX(读取)值:

  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);

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