2012-02-15 79 views
2

如果我有一個數據表編號:SQL GROUP BY與集合

+------+------+------+------+ 
| colA | colB | colC | colD | 
+------+------+------+------+ 
| 1 | 2 | 3 | 4 | 
| 1 | 2 | 9 | 5 | 
+------+------+------+------+ 

做:

select colA, colB, colC, MAX(colD) FROM Numbers GROUP BY colA, colB; 

我認爲,它應該由colA, colB返回行2.羣體,並挑選最大的一個在colD

不幸的是,這不起作用,因爲您還必須由colC進行分組才能返回。

爲什麼?有沒有另一種方法來做我想做的事情?

我想要colAcolB中相同的行,但是最大的一個在colD

回答

5

有幾種方法可以解決這個問題。也許最簡單的是JOIN針對一個子查詢,該子查詢執行colA, colB組,並從中找到完整對應的行。

SELECT 
    tbl.colA, 
    tbl.colB, 
    tbl.colC, 
    tbl.colD 
FROM tbl JOIN (
    SELECT 
    colA, 
    colB, 
    MAX(colD) AS maxD 
    FROM tbl 
    GROUP BY colA, colB 
) g ON tbl.colA = g.colA AND tbl.colB = g.colB AND tbl.colD = g.maxD 
+0

這對於NATURAL JOIN來說是一個很好的用例。 – Benoit 2012-02-15 13:59:05

+0

謝謝,並且非常感謝Benoit對這個問題進行了重構:)如果兩個列名都相同,那麼是否真的必須命名所有「on」:s? – momomo 2012-02-15 14:11:55

+0

@Hamidam是的,只要其中一個不是主鍵,你確實需要所有列在'ON'子句中的。例如,如果'colA'是一個唯一的鍵值,那麼你可以'ON tbl.colA = g.colA',但由於你的屬性並不唯一,所以你需要組合必要的列數來創建一個唯一的值colA ,colB,MAX(colD)' – 2012-02-15 14:19:37

0

您的查詢的問題之一是,您想要顯示codC的值,但它不在組中。要顯示沒有聚合函數的值,它必須位於組中。因此,要解決您的查詢,你可以做這樣的事情:

select n1.* from Number n1 
inner join (select colA, colB, max(colD) as colD from Number GROUP BY colA, colB) n2 on n1.colA = n2.colA and n1.colB = n2.colB and n1.colD = n2.colD 

會以選擇的最大(冷)每個可樂COLB所有行。

+2

如果您沒有將'max(colD)'別名作爲colD,將無法使用! – Benoit 2012-02-15 13:33:28

+0

@Benoit謝謝:) – 2012-02-15 13:35:47

3

你可以這樣做:

SELECT N1.colA, N1.colB, N1.colC, N1.colD 
    FROM Numbers N1 
    LEFT JOIN Numbers N2 ON N2.colA = N1.colA 
         AND N2.colB = N1.colB 
         AND N2.colD > N1.colD 
    WHERE N2.colA IS NULL; 

的LEFT JOIN將查找在與同列A和B,以及更大的列D.同一表中的行如果發現任何行,那麼你已經在在列最大值D.

這在技術上是一樣的:

SELECT * 
    FROM Numbers N 
WHERE NOT EXISTS 
    (SELECT NULL /* or whatever you want, doesn't matter */ 
     FROM Numbers 
     WHERE colA = N.colA 
      AND colB = N.colB 
      AND colD > N.colD 
    ) 

請注意,您可能要添加一個DISTINCT如果返回欺騙行。