【问题标题】:MySQL: Select nth rows where at least one has a attribute set?MySQL:选择至少有一个属性集的第 n 行?
【发布时间】:2014-05-22 18:13:00
【问题描述】:

我在 MySQL 中有一个名为 words 的表。

一列称为word(实际单词),另一列称为special

我正在尝试执行一个查询,如果可能的话,应该这样做:

SELECT word FROM words WHERE special = 1 AT LEAST ONCE

这是一个类似伪查询的原因,但我想要的是从我的单词表中随机获取第 n 条记录,其中至少一个单词的属性 special 设置为 1。

这意味着如果是这种情况,则所有第 n 条记录都允许为 1,或者除了第 n 条记录之一之外的所有记录都可以具有 special = 0,但必须至少有一个具有特殊 = 1.

我尝试过类似的方法: SELECT * FROM words HAVING COUNT(isNum = 1) > 1 ORDER BY RAND() LIMIT 10 或类似的东西。它没有给我想要的结果,实际上它只返回一个结果。

这可以通过 SQL 来完成吗??

谢谢

【问题讨论】:

    标签: mysql sql select having


    【解决方案1】:

    这是一种应该相对有效的方法。它选择一个随机的“特殊”单词,然后选择 n + 1 个其他单词(可能包含第一个单词)。它对它们进行排序,以保证随机的第一个,然后选择其中的 n 个。

    select word
    from ((select word, 0 as ordering
           from words
           where special = 1
           order by rand()
           limit 1
          ) union all
          (select word, rand() as ordering
           from words
           limit n
          )
         ) t
    group by word
    order by min(ordering)
    limit n;
    

    【讨论】:

    • 嗨,戈登,感谢您的回答。它可以工作,有点,但它似乎总是只选择最多一个具有特殊 = 1 而不是 1> 记录的记录。但它和我自己一样接近,所以它会做:-)
    • @Mestika 。 . .没有理由不选择多个。将 n 增加到一个很大的数字,您可能会看到更多的数字。这完全取决于特殊的比例、总行数以及n 的值。
    • 是的,你完全正确。它完美地工作:-)
    【解决方案2】:
    SELECT *
    FROM words
    HAVING COUNT(special = 1) > 1
    ORDER BY RAND()
    LIMIT 10
    

    在此处使用 COUNT() 而不使用 GROUP 仅计算记录数并返回 1 行,然后将 HAVING 子句应用于该行,从而在结果集中产生一条记录。

    如果您将COUNT() 添加到SELECT 子句中,您会发现自己的错误:

    SELECT COUNT(special = 1), words.*
    FROM words
    HAVING COUNT(special = 1) > 1
    ORDER BY RAND()
    LIMIT 10
    

    计数后返回的记录不定。

    因此,您必须添加 GROUP BY 以获取多条记录(每个单词一条):

    SELECT *
    FROM words
    GROUP BY word
    HAVING COUNT(special = 1) > 1
    ORDER BY RAND()
    LIMIT 10
    

    现在,您会注意到它返回所有包含多个记录的单词,无论它是否有 special = 1

    这是因为special = 1 是一个返回01 的布尔表达式。 COUNT() 递增 COUNT(0)COUNT(1)。实际上,它会在除COUNT(NULL) 之外的任何地方递增。现在,你意识到你真的想要SUM()

    SELECT *
    FROM words
    GROUP BY word
    HAVING SUM(special = 1) > 1
    ORDER BY RAND()
    LIMIT 10
    

    或者,也许更直接:

    SELECT DISTINCT word
    FROM words
    WHERE special = 1
    ORDER BY RAND()
    LIMIT 10
    

    【讨论】:

    • 感谢您的回答 Marcus,感谢您在我自己的查询中为我提供了错误的演练。我怀疑这并不像我想象的那么容易。实际上对我有用的是您的第三个查询。最后一个查询只选择了 special = 1 的单词,我想在 special = 0 和 special = 1 之间进行选择。
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2017-08-02
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多