我从考恩读此不同,与诺亚同意...
找到所有的水果,其中: - 用户 - 没有评分 - ATLEAST一个其他用户没有评分
然而,根据我的经验,使用NOT IN可能会很慢。所以,我通常更喜欢用与Cowan相同的方式使用LEFT JOIN进行过滤。这里有几个不同的选择,虽然我还没有来得及测试的大型数据集的性能...
SELECT
[f].id,
[f].name
FROM
fruit AS [f]
INNER JOIN
fruit_rating AS [fr]
ON [fr].fruit_id = [f].id
GROUP BY
[f].id,
[f].name
HAVING
SUM(CASE WHEN [fr_exclude].user_id = 10 THEN 1 ELSE 0 END) = 0
SELECT
[f].id,
[f].name
FROM
fruit AS [f]
INNER JOIN
fruit_rating AS [fr]
ON [fr].fruit_id = [f].id
LEFT JOIN
fruit_rating AS [fr_exclude]
ON [fr_exclude].fruit_id = [fr].fruit_id
AND [fr_exclude].user_id = 10
GROUP BY
[f].id,
[f].name
HAVING
MAX([fr_exclude].user_id) IS NULL
由于这仅适用于一个用户,我会还考虑把表“用户排除”并就代替LEFT JOIN ...
SELECT
[f].id,
[f].name
FROM
fruit AS [f]
INNER JOIN
fruit_rating AS [fr]
ON [fr].fruit_id = [f].id
LEFT JOIN
excluded_users AS [ex]
AND [ex].user_id = [fr].user_id
GROUP BY
[f].id,
[f].name
HAVING
MAX([ex].user_id) IS NULL
还有一些更长的啰嗦,但我怀疑是在具有适当索引的较大数据集上最快的...
SELECT
[f].id,
[f].name
FROM
fruit [f]
INNER JOIN
(
SELECT
fruit_id
FROM
fruit_rating
GROUP BY
fruit_id
)
AS [rated]
ON [rated].fruit_id = [f].id
LEFT JOIN
(
SELECT
[fr].fruit_id
FROM
fruit_rating AS [fr]
INNER JOIN
excluded_users AS [ex]
ON [ex].user_id = [fr].user_id
GROUP BY
[fr].fruit_id
)
AS [excluded]
ON [rated].fruit_id = [excluded].fruit_id
WHERE
[excluded].fruit_id IS NULL
GROUP BY
[f].id,
[f].name
你打我吧! – Noah 2009-01-08 21:59:20
是的,这里的速度问题:)。但是你写了整个查询,所以我猜它也很有用。 – Rockcoder 2009-01-08 22:06:34