2016-06-07 75 views
1

假設我有下面的SQL查詢(Notice the JOIN):如何使用GROUP BY的查詢與JOIN

SELECT 
    bpq.Id, 
    b.BatchCode, 
    bpq.PartId, 
    bpq.Hkid 
FROM 
    BoxPartsQuantity bpq 
JOIN 
    Batch b 
ON 
    bpq.BatchId = b.Id 
WHERE 
    PartId = 1 

,並傳回的結果是:

Id  BatchCode PartId Hkid 
137 2016-03-31 1  34361 
138 2016-03-31 1  34361 
139 2016-03-31 1  34361 
140 2016-03-31 1  34361 
141 2016-03-31 1  34361 
1123 2016/04/19 1  34361 
1976 2016/04/29 1  34361 

我如何刪除在BatchCodeHkid中重複,假設我想得到如下結果:

Id  BatchCode PartId Hkid 
137 2016-03-31 1  34361 
1123 2016/04/19 1  34361 

我試過下面的代碼:

SELECT 
    bpq.Id, 
    b.BatchCode, 
    bpq.PartId, 
    bpq.Hkid 
FROM 
    BoxPartsQuantity bpq 
JOIN 
    Batch b 
ON 
    bpq.BatchId = b.Id 
WHERE 
    PartId = 1 

GROUP BY 
    b.BatchCode, 
    bpq.Hkid 

但它返回我這個錯誤:

[SQL]SELECT 
    bpq.Id, 
    b.BatchCode, 
    bpq.PartId, 
    bpq.Hkid 
FROM 
    BoxPartsQuantity bpq 
JOIN 
    Batch b 
ON 
    bpq.BatchId = b.Id 
WHERE 
    PartId = 1 

GROUP BY 
    b.BatchCode, 
    bpq.Hkid 

[Err] 42000 - [SQL Server]Column 'BoxPartsQuantity.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

我對我應該和必須做非常困惑,因爲我沒有那麼多熟悉SQL編碼和所有。謝謝

回答

2

你必須使用一個聚合函數不參加的GROUP BY子句中的記錄:

SELECT 
    MIN(bpq.Id), 
    b.BatchCode, 
    bpq.PartId, 
    bpq.Hkid 
FROM 
    BoxPartsQuantity bpq 
JOIN 
    Batch b 
ON 
    bpq.BatchId = b.Id 
WHERE 
    PartId = 1  
GROUP BY 
    b.BatchCode, 
    bpq.Hkid, 
    bpq.PartId 

上面的查詢地也於GROUP BY現場bpq.PartId。這對分組沒有任何影響,因爲返回的所有記錄都是PartId=1。對於字段bpq.Id使用MIN,查詢返回每個記錄組的最小值,如OP中引用的預期結果。

+0

@TheQuestioner在這種情況下,你必須從'GROUP BY'條款刪除'bpq.Hkid',並添加像'MIN(bpq.Hkid )'在'SELECT'中。 –

2

由於bpq.id不是唯一的,因此每個組都有多個值,因此您必須選擇您想要的哪一個(不是所有的DBMS都可以,MySQL允許它,它會隨機選擇一個值) 。

你的榜樣,我想你想的第一ID,所以MIN()是要走的路:

SELECT 
    min(bpq.Id), 
    b.BatchCode, 
    bpq.PartId, 
    bpq.Hkid 
FROM 
    BoxPartsQuantity bpq 
JOIN 
    Batch b 
ON 
    bpq.BatchId = b.Id 
WHERE 
    PartId = 1 
GROUP BY 
    b.BatchCode, 
    bpq.Hkid, 
    bpq.PartId 
0

,你所面臨的這個錯誤告訴的是,這並不包括在選擇列的列表中的每個列在聚合函數中也應該放在Group By中。

覆蓋@Giorgos Betsos答案旁您的要求,您還可以使用ROW_NUMBER不需要使用組通過任何更多的跟隨太:

SELECT Id , 
    BatchCode , 
    PartId , 
    Hkid 
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY b.BatchCode ORDER BY bpq.Id) AS Rn , 
       bpq.Id , 
       b.BatchCode , 
       bpq.PartId , 
       bpq.Hkid 
     FROM  BoxPartsQuantity bpq 
       JOIN Batch b ON bpq.BatchId = b.Id 
     WHERE  PartId = 1 
    ) AS K 
WHERE Rn = 1; 

在上面的查詢和子查詢中我們首先爲每個記錄分配行號。此行號針對每個不同的BatchCode進行重設,並且此行號將根據Id列進行排序。在分配行號後,我們在外部查詢中過濾行號等於1。我們使用子查詢分配行號並在外部查詢中對其進行過濾的原因是,Row_number不能放置在查詢的Where部分內。

1

下面的查詢將提供所需的結果: -

SELECT 
distinct min(bpq.Id) over(partition by b.BatchCode,bpq.Hkid), 
b.BatchCode, 
bpq.PartId, 
bpq.Hkid 

FROM 
BoxPartsQuantity bpq 
JOIN 
Batch b 
ON 
bpq.BatchId = b.Id 
WHERE bpq.PartId = 1