表格:
id | category (there is a index on id & category)
-----------
1 | 1
1 | 7
1 | 3
2 | 1
2 | 2
2 | 4
3 | 1
3 | 6
3 | 3
SELECT DISTINCT
category
FROM
many_to_many e1
WHERE id IN
(
SELECT DISTINCT
e1.id
FROM
many_to_many e1
INNER JOIN
many_to_many x1
ON e1.id=x1.id
WHERE
e1.category IN (3)
)
我喜欢退却:** 6,1,7 **(我上面的查询得到的结果)
在我看来,这个查询并没有很好地预成型,因为子查询搜索所有的ID,这个列表可能很大。
如果ID有关,也无关紧要 因此,对于性能,如果要为每个要填充的唯一类别进行100次id检查就足够了。
其次我使用其他查询(子查询)获取包含类别的所有id:
SELECT DISTINCT
e1.id
FROM
many_to_many e1
INNER JOIN
many_to_many x1
ON e1.id=x1.id
WHERE
e1.category IN (3)
returns: 3 & 1
查询我喜欢的结果的最有效方法是什么。是否有更高效(更好的预成型)解决方案? 我应该使用一个而不是两个查询吗?
答案 0 :(得分:2)
SELECT DISTINCT
x1.category
FROM
many_to_many e1
INNER JOIN
many_to_many x1
ON e1.id = x1.id
WHERE
e1.category = 3 --- IN (3)
AND
x1.category <> 3 --- NOT IN (3)
您应该使用EXPLAIN检查查询计划。 (category, id)
上的复合索引可能适用于此查询。
答案 1 :(得分:1)
也许这个?
SELECT DISTINCT e2.category
FROM many_to_many e1, many_to_many e2
WHERE
e1.category='3'
AND e1.id=e2.id
这将使用该表两次,使所有类别包含具有类别“3”的ID。这也会返回类别“3”,如果您愿意,可以将其排除。
答案 2 :(得分:1)
首先,您的第二个查询(包含类别3的所有ID)不需要加入x1
(请注意您根本不使用它):
SELECT DISTINCT
e1.id
FROM
many_to_many e1
WHERE
e1.category IN (3)
然后您的第一个查询可以简化:
SELECT DISTINCT
category
FROM
many_to_many e1
WHERE id IN
(
SELECT DISTINCT
e1.id
FROM
many_to_many e1
WHERE
e1.category IN (3)
)
然而而不是使用子查询,您只需加入,这通常比子查询更有效:
SELECT DISTINCT e2.category
FROM many_to_many e1
LEFT JOIN many_to_many e2 ON e1.id=e2.id
WHERE e1.category IN (3);
这会在many_to_many
上将id
加入自身,形成每个id
的所有类别组合。特别是,对于出现在同一(3,i)
中的所有其他类别i
,将有一行id
。
如果您不想包含3,请将LEFT JOIN
更改为:
LEFT JOIN many_to_may e2 ON e1.id=e2.id AND e1.category<>e2.category