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 查询

在Doctrine 2中执行WHERE .. IN子查询

优化包含 WHERE 和 ORDER BY 的 MySQL UPDATE 查询?

在 Doctrine 2 中执行 WHERE .. IN 子查询

MySql学习 —— where / having / group by / order by / limit 简单查询

Python学习之旅—Mysql数据库之表操作(where+group by+having+order by)