GROUP BY子句

时间:2016-02-27 08:16:58

标签: sql sqlite

我想找到符合条件的连续记录的数量(按时间顺序,根据字段[when])(此处为data > 10)。感谢this answer我到达了这里:

SELECT tt.i, COUNT(*) AS count
FROM  t tt WHERE data > 10
GROUP BY i, (SELECT COUNT(*) FROM t WHERE [when] < tt.[when] AND NOT data > 10 AND i=tt.i );

我还需要按时间顺序对结果进行排序,虽然看起来GROUP BY会自动对它们进行排序,但似乎无法保证,所以我需要添加ORDER BY子句:

SELECT tt.i, COUNT(*) AS count
FROM  t tt WHERE data > 10
GROUP BY i, (SELECT COUNT(*) FROM t WHERE [when] < tt.[when] AND NOT data > 10 AND i=tt.i )
ORDER BY i, (SELECT COUNT(*) FROM t WHERE [when] < tt.[when] AND NOT data > 10 AND i=tt.i );

这可行,但由于子查询重复而不好。所以我想使用别名:

SELECT tt.i, COUNT(*) AS count, (SELECT COUNT(*) FROM t WHERE [when] < tt.[when] AND NOT data > 10 AND i=tt.i ) AS xid
FROM  t tt WHERE data > 10
GROUP BY i, xid
ORDER BY i, xid;

这也有效,但我不希望xid出现在我的结果中;我把它放在SELECT只是为了别名。 此外,我不明白为什么会这样,因为this answer GROUP BY根据SELECT执行,因此无法访问别名xid

这是我的测试表,以防有人想尝试查询:

CREATE TABLE t(i INT , [when] DATETIME, data INT);
INSERT INTO t(i, [when], data) VALUES (1, '20130813', 1);
INSERT INTO t(i, [when], data) VALUES (2, '20130812', 121);
INSERT INTO t(i, [when], data) VALUES (1, '20130811', 132);
INSERT INTO t(i, [when], data) VALUES (2, '20130810', 15);
INSERT INTO t(i, [when], data) VALUES (1, '20130809', 9);
INSERT INTO t(i, [when], data) VALUES (2, '20130808', 1435);
INSERT INTO t(i, [when], data) VALUES (1, '20130807', 143);
INSERT INTO t(i, [when], data) VALUES (2, '20130806', 18);
INSERT INTO t(i, [when], data) VALUES (1, '20130805', 19);
INSERT INTO t(i, [when], data) VALUES (2, '20130804', 1);
INSERT INTO t(i, [when], data) VALUES (1, '20130803', 1234);
INSERT INTO t(i, [when], data) VALUES (2, '20130802', 124);
INSERT INTO t(i, [when], data) VALUES (1, '20130801', 6);
  1. 如何才能使我的查询正确(确保正确的顺序),避免重复子查询并在结果中输出xid
  2. 为什么我的上一个查询尽管有子句执行顺序?

1 个答案:

答案 0 :(得分:1)

要从最终结果中删除列,请使用子查询:

SELECT only, what, I, want
FROM (SELECT ...);

SQL标准指定SELECT子句中的别名在GROUP BY子句中不可用,以允许该特定执行顺序。 但是,SQLite不会强制执行标准中的所有限制,如果它实际上找到xid的定义,它只会使用它。但是当符合标准的解释和其他一些解释时,SQLite倾向于选择前者;考虑此查询的结果:

SELECT a AS b
FROM (SELECT 1 AS a, 'x' AS b UNION ALL
      SELECT 2,      'y'      UNION ALL
      SELECT 3,      'x')
GROUP BY b;