MySQL WHERE IN 查询 - ORDER BY 匹配
Posted
技术标签:
【中文标题】MySQL WHERE IN 查询 - ORDER BY 匹配【英文标题】:MySQL WHERE IN Query - ORDER BY Match 【发布时间】:2012-04-05 18:11:33 【问题描述】:我正试图重新表述我的问题,因为我的最后一个问题并不清楚。
这是我的测试台
+----------+---------+-------+
| rel_id | genre | movie |
+----------+---------+-------+
| 1 | 1 | 3 |
| 2 | 8 | 3 |
| 3 | 3 | 3 |
| 4 | 2 | 5 |
| 5 | 8 | 5 |
| 6 | 3 | 5 |
| 7 | 1 | 8 |
| 8 | 8 | 8 |
| 9 | 3 | 8 |
| 10 | 5 | 9 |
| 11 | 7 | 9 |
| 12 | 9 | 9 |
| 13 | 4 | 9 |
| 14 | 12 | 9 |
| 15 | 1 | 10 |
| 16 | 8 | 10 |
| 17 | 3 | 10 |
| 18 | 5 | 10 |
| 19 | 1 | 11 |
| 20 | 2 | 11 |
| 21 | 8 | 11 |
| 22 | 5 | 11 |
| 23 | 3 | 11 |
+----------+---------+-------+
如果我查找类型为 1、8、3 的电影,结果应按以下顺序排列:电影编号。 3、8、10、5、11(9 出)。
如果不可能,那么我只想要完全匹配“1、8、3”的所有内容,在这种情况下,我只会得到电影编号。 3 和 8。
【问题讨论】:
您的查询无效吗?它首先查找具有一种类型的所有电影,然后按电影分组。 它似乎按预期工作,电影 5 有类型 8 和 3,但没有类型 1。你的意思是你想要获得所有这些类型的电影吗? @flo 是的,这是正确的,因为在我得到完全匹配的顺序后,我需要输出电影。我只需要这部电影,而不是3倍。希望你理解:D @Matthew Riches 我想得到第一部电影 3 和 8,因为他们得到了类型 1、8、3 的正确类型匹配,最后的结果应该是电影编号。 5 因为这里只是第一个流派不一样,但是第二个和第三个得到了正确的匹配。理解? :) 好的,我已经在pastebin 上发布了另一个示例,请记住,我使用 3 种流派作为示例。查询可能在 WHERE 子句中有 5 个流派 【参考方案1】:如果我理解正确,您希望按匹配数降序对结果进行排序。为此,您可以尝试:
SELECT movie
FROM genre_rel
WHERE genre IN (1, 8, 3)
GROUP BY movie
order by count(movie) desc
如果您想要符合所有条件的电影,您可以使用:
SELECT movie
FROM genre_rel
WHERE genre IN (1, 8, 3)
GROUP BY movie
HAVING count(movie) = 3
更新:
这是我在 mysql 中能做的最好的事情。您不能使用 IN,因为您无法提取有关过滤器顺序的信息。如果您添加派生表作为过滤方式,您可以附加此信息并使用它按位置匹配显示结果。请注意,您没有在genre_rel 表中提供任何排序信息,因此您并不真正了解每部电影流派的重要性。此查询将按条件中类型重要性的降序为您提供匹配的电影:
SELECT movie
FROM genre_rel
INNER join
(
select 1 genre, 1000 weight
union all
select 8, 100
union all
select 3, 10
) weights
on genre_rel.genre = weights.genre
GROUP BY movie
order by sum(weight) desc
请注意,除了 5 部之外的所有电影都属于所有 3 种类型。如果您向genre_rel 添加一个表示重要性顺序的列,您可能会设计一些数学方法(权重-重要性或类似的东西)。
【讨论】:
首先感谢您的帮助:) 这个查询几乎给了我想要的结果。但它也会以 1、8、4、3 的顺序返回类型为 1、8、4、3 的电影 - 但这些电影应该作为最后的结果返回 我不明白。你有 3 部电影和 3 个流派,这四个数字是从哪里来的?此查询准确返回 3、8、5 - 我在发布为答案之前对其进行了测试。 我想你理解我 :) 因为你发布的第二个查询正是我想要的! :) 非常感谢你 嗯,第一个结果还可以,但以下不是。我在pastebin 上发布了另一个示例,请记住,我使用 3 种流派作为示例。查询可能在 WHERE 子句中有 5 个流派 啊,你想要电影按照它们在 IN () 中列出的顺序!恐怕不会,但我不精通 MySql,所以你可以试试新的、措辞更好的问题。【参考方案2】:您可以通过以下方式做到这一点:
SELECT distinct movie FROM genre_rel WHERE genre IN (1, 8, 3);
【讨论】:
【参考方案3】:您在流派列中给出了标准。如果您的电影 5 还包含流派 8 和 3。由于这个原因,你也得到了电影 5。
【讨论】:
是的,我想要电影号码。 5,但电影的顺序应该是 3、8、5 而不是 3、5、8【参考方案4】:怎么样:
SELECT movie, SUM(gentre) AS count
FROM genre_rel
WHERE genre IN (1, 8, 3)
GROUP BY movie
ORDER BY count DESC
【讨论】:
SUM 在这里没有意义,因为流派只是 id。你应该使用 COUNT()。 感谢您的帮助 Tomasz。这个查询几乎给了我想要的结果。但它也会以 1、8、4、3 的顺序返回类型为 1、8、4、3 的电影 - 但这些电影应该作为最后的结果返回 你说得对,这里当然应该用 COUNT 而不是 SUM!【参考方案5】:试试这个查询 -
SELECT movie FROM genre_rel
GROUP BY movie
ORDER BY
IF(COUNT(IF(genre IN (1, 8, 3), 1, NULL)) = 3, genre, genre + 1000)
其中 1000 是不匹配电影的订单偏移量,如果需要,请增加此值。
另外,你可以试试这个 ORDER BY -
ORDER BY IF(COUNT(IF(genre IN (1, 8, 3), 1, NULL)) = 3, genre, MAX(genre))
【讨论】:
以上是关于MySQL WHERE IN 查询 - ORDER BY 匹配的主要内容,如果未能解决你的问题,请参考以下文章
使用“WHERE [tinyint] ORDER BY ID”的慢 MySQL 查询
优化包含 WHERE 和 ORDER BY 的 MySQL UPDATE 查询?
在 Doctrine 2 中执行 WHERE .. IN 子查询
MySql学习 —— where / having / group by / order by / limit 简单查询