我一直在以高效的方式從MySQL數據庫中檢索數據。MySQL:在HAVING子句之前限制結果集的問題
我有一個很多項目的表。每個項目可以具有狀態1,2或3.我想選擇具有特定狀態的項目,具體取決於其他表格中這些記錄的鏈接。
例子:
- 的表
items
與字段:ID,名稱,狀態,... - 的表
bought
與字段:的itemId,用戶id - 的表
rented
與字段:的itemId,用戶id
說,我想這對於用戶id 123
:
- 所購買的全部記錄,具有都是租的狀態1
- 所有的記錄,具有狀態1或2
- 未購買或租借的所有記錄,其狀態3
我的選擇查詢現在看起來是這樣的:
SELECT
i.id,
i.name,
i.status,
// bought by this user?
SUM(IF(b.userId = 123, 1, 0)) AS bought,
// rented by this user?
SUM(IF(r.userId = 123, 1, 0)) AS rented,
FROM items i
LEFT JOIN bought b
ON b.itemId = i.id
LEFT JOIN rented r
ON r.itemId = r.id
GROUP BY i.id
HAVING
// bought and status 1
(bought > 0 AND status = 1)
// rented and status 1 or 2
OR (rented > 0 AND status IN (1, 2)
// not bought or rented and status 3
OR (bougth = 0 AND rented = 0 AND status = 3)
ORDER BY i.name ASC
問題1
SELECT子句中的SUM部分是確定是否有鏈接到某個項目的其他表中的條目的好方法?假設每個用戶只有一個條目,總和將爲1或0,爲我提供所需的信息。但它似乎......不知何故怪異。
問題2
儘管這個作品,有一個很大的問題:它基本上檢索所有項目,然後使用HAVING
條款過濾它們。由於有很多條目,查詢速度太慢了。我試圖找出如何解決這個問題。
我第一次嘗試WHERE
條款..但如何?
...
WHERE
// only items with status 1 if bought or rented
(t.status = 1 AND (bought > 0 OR rented > 0))
// only items with status 2 if rented
OR (t.status = 2 AND rented > 0)
// only items with status 3 if not bought or rented
OR (t.status = 3 AND bought = 0 AND rented = 0)
...
但是,您不能使用SELECT
子句中的變量。並且由於項目表中沒有列rented
或bought
,所以這將不起作用。
我也嘗試使用用戶定義的變量,但這並沒有工作,要麼:
SELECT
...
@bought := SUM(IF(b.userId = 123, 1, 0)) AS bought,
...
WHERE @bought = ... // does not work
然後我試圖一個子查詢,但我不能得到它使用的主要的查詢項目ID :
...
WHERE
...
// only items with status 2 if rented
OR (
t.status = 2
AND (
SELECT COUNT(r2.userId)
FROM rented r2
WHERE r2.userId = 123
AND r2.itemId = i.itemId // it doesn't recognize i.itemId
) > 0
)
...
任何想法?我還想將所有內容都保存在一個查詢中。這只是一個簡單的例子,但實際的一個比較大。我敢肯定,我可以將所有事情分開,並使用各種查詢分別收集所有內容,但這隻會增加很多的代碼,並且不會使維護更容易。
是最終的結果集輸出'bought'和'rented'列必要的,或者是他們那裏只是爲了利用列別名? – 2010-11-11 02:55:43
他們也有必要以後區分項目。 – Alec 2010-11-11 03:44:52