2013-06-03 105 views
2

讓我們有兩張表,一張持有用戶信息和一張持有用戶記錄的某種類型的收據。用戶和收據之間有一對多的關係。使用SQL JOIN和COUNT

什麼是檢索用戶的最佳SQL方法,按最大數量的收據排序?

我能想到的最好方法是使用連接和計數(?)來返回用戶數組及其相關收據數。

有沒有一種方法可以在這種情況下使用計數功能?

select * from `users` inner join `receipts` on `users`.`id` = `receipts`.`uId` 

回答

2

由Dave和meewoK提供的兩個答案將完成你所需要的。我提供了一個替代方案,應該提供更好的性能,並允許您顯示更多的用戶信息,因爲在Dave的答案中,您只能選擇由聚合函數或組合子句使用的列。

SELECT users.id, users.name, r.numReceipts 
FROM users u 
INNER JOIN (
    SELECT uId, count(receipts) as numReceipts 
    FROM receipts 
    GROUP BY receipts.id 
) as r ON r.uId = u.id 
ORDER BY r.numReceipts DESC 

這創建了一個內聯視圖。只返回每個用戶的收據計數,然後加入該用戶ID的內嵌視圖。

如果我錯了,有人糾正我,但我已經被告知,當您在SELECT子句中執行標量子查詢時,規劃器效率不高。這樣最好加入臨時桌子。有多種方法來編寫這個查詢,這一切都取決於你想如何使用這些信息!乾杯!

+1

tbh我不知道哪一個更快,我懷疑我做這個的方式比較慢(當然在更大的桌子上),因爲你正在做一個完整的表b掃描並計算表a中的每個uid。我的答案也取決於他不想從收據表中得到任何數據,正如你的給他的那樣:)雖然tbh中的一個子選擇可能不是做這件事的最好方法。如果我想要一個計數器並檢索兩個表的細節,我會試圖做一個左外連接。或者也許是一個工會,只是選擇整個地段:) – Dave

+0

是的,我絕對同意一個左連接是處理這個任務的最有效的方式。 – enigmasck

+0

我必須測試這些方法,然後看看哪個更快...... –

5

如果OP希望從users表包括附加信息(附加聚合等)利用數據:

SELECT `users`.`id`, 
     count(`receipts`.`uId`) 
FROM `users` 
INNER JOIN `receipts` ON `users`.`id` = `receipts`.`uId` 
GROUP BY `users`.`id` 
ORDER BY count(`receipts`.`uId`) DESC 

否則,只需要receipts表...

SELECT `users`.`id`, 
     count(`receipts`.`uId`) 
FROM `receipts` 
GROUP BY `receipts`.`uId` 
ORDER BY count(`receipts`.`uId`) DESC 
+0

。 。如果您打算將返回限制爲僅ID,則不需要連接。 –

+0

。 。這個查詢仍然是錯誤的,除非它們恰好是'receiptts'表中名爲'receipts'的列。 –

3

試試這個

SELECT a.`id`, count(b.`recipts`) as total_receipts 
FROM `users` a 
INNER JOIN `receipts` b 
ON a.`id` = b.`uId` 
GROUP BY a.`id` 
ORDER BY count(b.`receipts`) desc 
2

SELECT users.*, (SELECT COUNT(*) FROM tblreceipts WHERE tblreciepts.uId=users.id) as counter FROM用戶ORDER BY counter DESC

像這樣的東西可能工作(不知道在速度,雖然如果大表)

2

如果您要包括所有的用戶,甚至包括那些沒有收據,然後一個好辦法是一個left outer join

SELECT u.*, count(r.uid) as NumReceipts 
FROM `users` u left outer join 
    `receipts` r 
    ON u.id = r.`uId 
GROUP BY `u.id 
ORDER BY NumReceipts DESC; 

如果你只是想爲有收入的用戶的ID,那麼連接甚至沒有必要:

SELECT r.uid, count(*) as NumReceipts 
FROM receipts r 
GROUP BY r.uid 
ORDER BY NumReceipts