2016-02-27 79 views
1

我想查找匹配條件(此處爲data > 10)的連續記錄數(按時間順序,根據字段[when])。由於this answer我來到這個:GROUP 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); 

我還需要結果按時間順序排序,並且雖然它看起來像自動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 answerGROUP 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

從最終結果中刪除列,使用子查詢:

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; 
+0

謝謝。 1. SELECT是否保證以與發現它們相同的順序輸出結果?我擔心外層的SELECT會被允許改變內層的結果順序,在這種情況下,我將不得不確保外部查詢的順序。 2.使用SQL標準不支持的查詢是不謹慎的嗎?我已經在[SQL Fiddle](http://www.sqlfiddle.com/#!15/569ba/1)上嘗試了幾個RDBMS,它們似乎都接受它: 3.是否有可能沒有額外的子查詢?在這種簡單的情況下,開銷可能並不高,但我想。 – unagi

+1

如果您有疑問,可以將ORDER BY移動到外部查詢。沒有數據庫實際上符合標準的100%。如果可能的話,子查詢將被扁平化或作爲協同程序實施,因此不會有開銷。 –

+0

這足以解決我的問題,謝謝。但關於2 .:是否可以編寫這個查詢,以便它符合SQL標準?沒有RDMS符合100%標準的事實並不意味着不可能編寫所有/大多數RDMS兼容的SQL。至少Oracle和SQL服務器似乎拒絕在GROUP BY子句中使用別名。 – unagi