MySQL将子查询加入group by

时间:2014-06-09 19:42:24

标签: mysql group-by left-join

我有一个要求,我需要将组数据分成相等数量的ob行。由于mysql没有rownum(),我正在模拟这种行为:

SET @row:=6; 
SELECT MAX(agg.timestamp) AS timestamp, MAX(agg.value) AS value, COUNT(agg.value) AS count 
FROM 
    (
        SELECT timestamp, value, @row:=@row+1 AS row 
        FROM data 
        WHERE channel_id=52 AND timestamp >= 0 ORDER BY timestamp
    ) AS agg 
GROUP BY row div 8
ORDER BY timestamp ASC;

注意:根据Can grouped expressions be used with variable assignments?,此查询可能不是100%正确,但 可以正常工作。

另一个要求是计算分组集之间的行差异。我已经找到了一个解决方案,使用子查询连接同一个表:

SET @row:=6; 
SELECT MAX(agg.timestamp) AS timestamp, MAX(agg.value) AS value, COUNT(agg.value) AS count 
FROM 
    (
        SELECT timestamp, value, @row:=@row+1 AS row 
        FROM data 
        WHERE channel_id=52 AND timestamp >= 0 ORDER BY timestamp
    ) AS agg 
LEFT JOIN data AS prev
    ON prev.channel_id = agg.channel_id
    AND prev.timestamp = (
        SELECT MAX(timestamp) 
        FROM data
        WHERE data.channel_id = agg.channel_id
            AND data.timestamp < MIN(agg.timestamp)
    )
GROUP BY row div 8
ORDER BY timestamp ASC;

不幸的是错误:

Error Code: 1054. Unknown column 'agg.channel_id' in 'on clause'

知道如何编写此查询吗?

2 个答案:

答案 0 :(得分:2)

您从未从您的sbuquery中选择channel_id,因此它不会返回到父查询,因此不可见。尝试

SELECT MAX(agg.timestamp) AS timestamp, MAX(agg.value) AS value, COUNT(agg.value) AS count 
FROM 
    (
        SELECT timestamp, value, @row:=@row+1 AS row, channel_id
                                                    ^^^^^^^^^^^^-- need this
        FROM data 

由于MySQL只能看到并使用您从该子查询中明确返回的字段,因此不会深入挖掘&#34;在查询底层的表中,您需要选择/返回您将使用父查询的所有字段。

答案 1 :(得分:0)

这个版本怎么样:

SELECT MAX(agg.timestamp) AS timestamp, MAX(agg.value) AS value, COUNT(agg.value) AS count, COALESCE(prev.timestamp, 0) AS prev_timestamp
FROM (SELECT d.*, @row:=@row+1 AS row 
      FROM data d CROSS JOIN
           (select @row := 6) vars
      WHERE channel_id = 52 AND timestamp >= 0 ORDER BY timestamp
     )  agg LEFT JOIN
    data prev
    ON prev.channel_id = agg.channel_id AND
       prev.timestamp = (SELECT MAX(timestamp) 
                         FROM data
                         WHERE data.channel_id = agg.channel_id AND
                               data.timestamp < agg.timestamp
                        )
GROUP BY row div 8
ORDER BY timestamp ASC;

这包括子查询中的所有列。它将变量初始化放在同一个查询中。