我一直在以高效的方式从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