讓我們有兩張表,一張持有用戶信息和一張持有用戶記錄的某種類型的收據。用戶和收據之間有一對多的關係。使用SQL JOIN和COUNT
什麼是檢索用戶的最佳SQL方法,按最大數量的收據排序?
我能想到的最好方法是使用連接和計數(?)來返回用戶數組及其相關收據數。
有沒有一種方法可以在這種情況下使用計數功能?
select * from `users` inner join `receipts` on `users`.`id` = `receipts`.`uId`
讓我們有兩張表,一張持有用戶信息和一張持有用戶記錄的某種類型的收據。用戶和收據之間有一對多的關係。使用SQL JOIN和COUNT
什麼是檢索用戶的最佳SQL方法,按最大數量的收據排序?
我能想到的最好方法是使用連接和計數(?)來返回用戶數組及其相關收據數。
有沒有一種方法可以在這種情況下使用計數功能?
select * from `users` inner join `receipts` on `users`.`id` = `receipts`.`uId`
由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子句中執行標量子查詢時,規劃器效率不高。這樣最好加入臨時桌子。有多種方法來編寫這個查詢,這一切都取決於你想如何使用這些信息!乾杯!
如果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
。 。如果您打算將返回限制爲僅ID,則不需要連接。 –
。 。這個查詢仍然是錯誤的,除非它們恰好是'receiptts'表中名爲'receipts'的列。 –
試試這個
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
SELECT users.*, (SELECT COUNT(*) FROM tblreceipts WHERE tblreciepts.uId=users.id) as counter FROM
用戶ORDER BY counter DESC
像這樣的東西可能工作(不知道在速度,雖然如果大表)
如果您要包括所有的用戶,甚至包括那些沒有收據,然後一個好辦法是一個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
tbh我不知道哪一個更快,我懷疑我做這個的方式比較慢(當然在更大的桌子上),因爲你正在做一個完整的表b掃描並計算表a中的每個uid。我的答案也取決於他不想從收據表中得到任何數據,正如你的給他的那樣:)雖然tbh中的一個子選擇可能不是做這件事的最好方法。如果我想要一個計數器並檢索兩個表的細節,我會試圖做一個左外連接。或者也許是一個工會,只是選擇整個地段:) – Dave
是的,我絕對同意一個左連接是處理這個任務的最有效的方式。 – enigmasck
我必須測試這些方法,然後看看哪個更快...... –