2010-05-05 74 views
9

這一直困擾着我 - 爲什麼SQL語句中的GROUP BY子句要求包含所有非聚合列?這些列應該默認包含 - 一種「GROUP BY *」 - 因爲我甚至無法運行查詢,除非它們全部包含在內。每一列都必須是聚合或在「GROUP BY」中指定,但似乎任何未彙總的內容都應該自動分組。爲什麼我需要顯式指定SQL「GROUP BY」子句中的所有列 - 爲什麼不是「GROUP BY *」?

也許這是ANSI-SQL標準的一部分,但即便如此,我不明白爲什麼。有人能幫助我理解這一慣例的必要性嗎?

+0

相關http://stackoverflow.com/questions/416625/why-does-sql-force-me-to-repeat-all-non-aggregated-fields-from-my-select-clause-i – 2010-05-05 23:04:14

+0

啊 - 它是重複的。我會解決這個問題。 – SqlRyan 2010-05-05 23:14:11

+1

其多元化:http://stackoverflow.com/questions/2311034/is-sql-group-by-a-design-flaw – cindi 2010-05-06 07:47:22

回答

19

很難確切知道SQL語言的設計者在編寫標準時想到什麼,但這裏是我的意見

SQL,作爲一般規則,需要你明確說明你的期望和你的意圖。該語言不會嘗試「猜你的意思」,並自動填入空格。 這是一件好事

當你寫一個查詢時,最重要的考慮因素是它產生正確的結果如果您犯了一個錯誤,那麼SQL解析器可能會告訴您更好,而不是猜測您的意圖並返回可能不正確的結果。 SQL的聲明性質(您聲明您想要檢索的內容而不是檢索步驟)已經很容易導致無意中犯錯誤。 將fuzziniess引入語言語法不會使這個更好

事實上,我所能想到的每種情況下語言允許在快捷方式都引起了問題。舉例來說,自然連接 - 您可以忽略要加入的列的名稱,並允許數據庫根據列名來推斷它們。一旦列名更改(如他們自然做的一段時間內)- 與他們現有查詢變化的語義。 這是壞的......很不好 - 你真的不希望這種魔術發生在你的數據庫代碼在幕後。這種設計選擇

一個後果,但是,是SQL是一個冗長的語言中,你必須明確地表達你的意圖。這可能導致必須編寫比您想要的更多的代碼,並且抱怨爲什麼某些構造如此冗長......但是在一天結束時 - 它就是這樣。

0

就像這樣簡單:你需要對from子句中的每一列求sql結果,這意味着from子句SQL中的每一列,sql引擎會在內部對結果集進行分組,您。所以這就解釋了爲什麼它會要求你提及所有列中的列,因爲它不可能將它部分分組。如果您提到了group by子句,那麼只有通過將所有列分組才能達到您的意圖。這是一個數學限制。

0

唯一合乎邏輯的理由,我能想到的,以保持GROUP BY條款,因爲它是可以包括未包含在您的分組選擇列字段。

例如。

Select column1, SUM(column2) AS sum 
FROM table1 
GROUP BY column1, column3 

儘管在查詢中其他位置沒有顯示第3列,但您仍然可以按結果對其值進行分組。 (當然,一旦你這樣做了,你不能從結果中看出爲什麼這些記錄是按原樣分組的。)

它看起來像是一個簡單的捷徑,用於絕大多數常見的場景彙總列)將是一個簡單而有效的工具,用於加速編碼。

也許"GROUP BY *"

因爲它已經是很常見的在SQL工具,允許結果列數列引用(即GROUP BY 1,2,3,等),這似乎是簡單的還是要能夠自動允許用戶在一個按鍵中包含所有非聚合字段。