2008-12-12 125 views
1

我有三個表。這個查詢將寫下正確的答案(用適當btv.cas的X線btv.id_user和race.id_zavod問題與表JOIN MySQL和聚合

SELECT `btv.id_user`, `btv.id_zavod`,`btv.cas` 
FROM `btv` 
JOIN `btu` ON `btv.id_user` = `btu.id_user` 
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod` 
WHERE `race.type` = '8' AND `btv.id_user` = '607' 

結果:

| 607 | 512 | 03:15:58 | 
| 607 | 730 | 03:01:18 | 
| 607 | 164 | 03:07:26 | 
| 607 | 767 | 02:58:31 | 
| 607 | 1147 | 03:06:47 | 
| 607 | 1149 | 03:09:41 | 
| 607 | 1178 | 03:24:20 | 

但是,當我嘗試將其彙總到一個由id_user排它返回正確分鐘btv.cas但錯誤的連接錯誤race.id_zavod

SELECT `btv.id_user`, `btv.id_zavod`, MIN(`btv.cas`) 
FROM `btv` 
JOIN `btu` ON `btv.id_user` = `btu.id_user` 
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod` 
WHERE `race.type` = '8' AND `btv.id_user` = '607' 
GROUP BY `btv.id_user` 

結果:

| 607 | 512 | 02:58:31 | 

回答

0

當您使用GROUP BY,在選擇列表中的列必須滿足下列之一:

  • 列在GROUP BY(名爲例如btv.id_user在你的例子)
  • 列在一個聚合函數內(例如MIN(btv.cas)
  • 列是一個功能依賴您在GROUP BY中命名的列的編號爲

這是您的查詢中的錯誤:btv.id_zavod對於每個值btv.id_user都有很多值。這不符合功能依賴性。對於id_user的每個值,在id_zavod中必須只有一個值,因爲它是函數依賴項。

在某些數據庫品牌中,該查詢實際上會給您一個錯誤。 MySQL更加靈活,相信您只需在選擇列表中命名列中的列,這些列是您在GROUP BY中命名的列的功能依賴關係。

這裏有一個查詢,返回你想要什麼,的btv.casid_user最小值,請與btv.id_zavod相應的值:

SELECT b1.id_user, b1.id_zavod, b1.cas 
FROM btv AS b1 
JOIN btu ON (b1.id_user = btu.id_user) 
JOIN race ON (b1.id_zavod = race.id_zavod) 
LEFT OUTER JOIN btv AS b2 ON (b1.id_user = bt2.id_user AND 
    (b1.cas > b2.cas OR (b1.cas = b2.cas AND b1.primarykey > b2.primarykey)) 
WHERE race.type = '8' AND b1.id_user = '607' 
AND b2.id_user IS NULL; 

換句話說,你需要做你的加入和以前一樣,但隨後再次加入到btv,看看是否有另一行id_user的值和cas中的較小值。使用OUTER JOIN,因爲你正在尋找沒有匹配的情況。您可以使用b2.id_user IS NULL進行測試,因爲當沒有匹配時,OUTER JOIN使所有列爲NULL。

請注意,可能存在關係,因此我們使用主鍵作爲tiebreaker添加額外項。

您不需要在此查詢中使用GROUP BY。這被隱式處理,因爲只有一行滿足OUTER JOIN條件。

1

你寫的查詢:

SELECT `btv.id_user`, `btv.id_zavod`, MIN(`btv.cas`) 
FROM `btv` 
JOIN `btu` ON `btv.id_user` = `btu.id_user` 
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod` 
WHERE `race.type` = '8' AND `btv.id_user` = '607' 
GROUP BY `btv.id_user`

將無法​​運行。你需要id_zavod或其他組合。你能告訴我們你真的在運行什麼查詢嗎?你期望的結果是什麼?

+0

你會感到驚訝,但它的工作(但錯誤) – beny 2008-12-12 23:25:37

0

嘗試:

SELECT `btv.id_user`, `btv.id_zavod`, MIN(`btv.cas`) 
FROM `btv` 
Inner JOIN `btu` ON `btv.id_user` = `btu.id_user` 
Inner JOIN `race` ON 'btv.id_zavod' = `race.id_zavod` 
WHERE `btv.id_user` = '607' 
GROUP BY `btv.id_user` having `race.type` = '8' 
0

你只是試圖獲取最低btv.cas值和其他相應的列?如果是這樣,你可以只通過btv.cas和限制1次命中順序:

SELECT `btv.id_user`, `btv.id_zavod`,`btv.cas` 
FROM `btv` 
JOIN `btu` ON `btv.id_user` = `btu.id_user` 
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod` 
WHERE `race.type` = '8' AND `btv.id_user` = '607' 
ORDER BY `btv.cas` LIMIT 1
+0

這是正確的,這會爲這個SELECT工作,但後來我想爲所有用戶使用此選擇(爲所有用戶查找最小的cas和相應的id_zavod) – beny 2008-12-13 10:31:54