如何篩選僅符合某些標準的組與其他組相比較的組的結果集?例如,只有那些組織記錄數量最多的組織?比較SQL組和海誓山盟
我原本以爲子查詢如下應該做的伎倆:
SELECT * FROM (
SELECT *, COUNT(*) AS Records
FROM T
GROUP BY X
) t HAVING Records = MAX(Records);
然而,除了在一個空的記錄最終HAVING
條款的結果......這是怎麼回事?
如何篩選僅符合某些標準的組與其他組相比較的組的結果集?例如,只有那些組織記錄數量最多的組織?比較SQL組和海誓山盟
我原本以爲子查詢如下應該做的伎倆:
SELECT * FROM (
SELECT *, COUNT(*) AS Records
FROM T
GROUP BY X
) t HAVING Records = MAX(Records);
然而,除了在一個空的記錄最終HAVING
條款的結果......這是怎麼回事?
對於你給出的確切問題,一種看待它的方法是你想要一組記錄,其中沒有其他組具有更多記錄。所以,如果你說
SELECT taxid, COUNT(*) as howMany
GROUP by taxid
你得到所有縣及其計數
然後你就可以把這個表達式,通過使其子查詢表,並給它一個別名。在下面,我將查詢的兩個「副本」分配給名稱X和Y,並要求在一張表中沒有更多的taxids。如果有兩個相同的號碼,我會得到兩個或更多。不同的數據庫具有專有語法,特別是TOP和LIMIT,這使得這種查詢變得更簡單,更易於理解。
SELECT taxid FROM
(select taxid, count(*) as HowMany from flats
GROUP by taxid) as X
WHERE NOT EXISTS
(
SELECT * from
(
SELECT taxid, count(*) as HowMany FROM
flats
GROUP by taxid
) AS Y
WHERE Y.howmany > X.howmany
)
我知道,通過在'WHERE'子句中重複子查詢,我可以提取最大行數(只需使用'max()'就可以正常工作),但是調用相同子查詢倍;有沒有什麼辦法可以引用WHERE子句中'FROM'子句中子查詢產生的臨時表? – eggyal 2012-03-27 14:00:57
試試這個:
SELECT * FROM (
SELECT *, MAX(Records) as max_records FROM (
SELECT *, COUNT(*) AS Records
FROM T
GROUP BY X
) t
) WHERE Records = max_records
我很抱歉,我現在不能測試此查詢的有效性。
第二級查詢中的「SELECT MAX(記錄)」會將記錄集截斷爲只有一個記錄,其中「記錄」和「max_records」字段不一定相同(因此總體結果將只包含零或一個記錄);也許這是我的原始查詢所暗示的,因此沒有結果? – eggyal 2012-03-27 13:43:21
在MySQL(我假設你正在使用,因爲你已經張貼SELECT *, COUNT(*) FROM T GROUP BY X
這將在我所知道的所有RDBMS失敗)。您可以使用:
SELECT T.*
FROM T
INNER JOIN
( SELECT X, COUNT(*) AS Records
FROM T
GROUP BY X
ORDER BY Records DESC
LIMIT 1
) T2
ON T2.X = T.X
這在MySQL進行了測試,並刪除隱式分組/聚集。
如果你可以使用窗口功能,並與領帶或公用表表達式TOP/LIMIT的一個變得更短:
窗口函數+ CTE:(MS SQL-服務器& PostgreSQL的測試)
WITH CTE AS
( SELECT *, COUNT(*) OVER(PARTITION BY X) AS Records
FROM T
)
SELECT *
FROM CTE
WHERE Records = (SELECT MAX(Records) FROM CTE)
窗口函數與TOP(測試MS SQL服務器)
SELECT TOP 1 WITH TIES *
FROM ( SELECT *, COUNT(*) OVER(PARTITION BY X) [Records]
FROM T
)
ORDER BY Records DESC
最後,我從來沒有使用甲骨文所以apolgies沒有添加一個解決方案,在oracle上工作...
編輯
我的解決方案對於MySQL並沒有考慮到的關係,和我的一個解決這種對腳趾的步驟建議你所說的你想避免(副本子查詢),所以我不知道我能幫助畢竟,但是隻是在情況下,優選這裏是你的提琴要求,將工作的一個版本:
SELECT T.*
FROM T
INNER JOIN
( SELECT X
FROM T
GROUP BY X
HAVING COUNT(*) =
( SELECT COUNT(*) AS Records
FROM T
GROUP BY X
ORDER BY Records DESC
LIMIT 1
)
) T2
ON T2.X = T.X
第一個(mysql)的確會失去聯繫;這可能是eggyal想要的,如果不是的話,我認爲你必須將它改寫成與count相匹配。後兩者不會失去聯繫。 – 2012-03-27 14:27:09
@LevinMagruder是的,幾分鐘前注意到了這一點,添加了一個編輯,但現在我也不認爲這是OP所要的,因爲它重複了子查詢,但據我所知,這是不可避免的。 – GarethD 2012-03-27 14:30:29
+1比我的「不存在」邏輯更直接。 – 2012-03-27 14:31:36
如果的Juho的回答不會給你你需要什麼,請輸入您的數據庫類型使用(oracle,mysql,sql server等)(通過使用標籤,你把sql放在哪裏。如果你只需要通用的SQL解決方案,請在消息正文中提及)。如果您已花時間在您的文章和sqlfiddle.com中添加一些示例數據和表格結構,您可以更輕鬆地讓人們更深入地查看您的問題。 – 2012-03-27 13:41:20
@LevinMagruder:MySQL 5.1;示例數據http://sqlfiddle.com/#!3/b4306/4 – eggyal 2012-03-27 13:49:08
好吧,我不使用mysql,但有人會告訴你一個比我在下面顯示的更簡單的查詢,將他們的答案標記爲答案,但是如果我的回答很有幫助,而且你想向我發射upvote,謝謝。如果你有很多像這樣的問題,也許還會閱讀標籤爲「每個組最多的問題」的問題,那麼有很多有趣的方法。 – 2012-03-27 14:00:00