【问题标题】:MySQL WHERE IN Query - ORDER BY MatchMySQL WHERE IN 查询 - ORDER BY 匹配
【发布时间】: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 个流派

标签: mysql sql sql-order-by where-in


【解决方案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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-16
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      相关资源
      最近更新 更多