【问题标题】:Select random row with other criteria选择具有其他条件的随机行
【发布时间】:2013-05-29 14:13:03
【问题描述】:

我已经看到this great answer 了解如何从表中选择随机行,它在我的表上效果很好。修改我最终得到的查询:

SELECT r1.clID, clUserName, clCompanyName, clBio 
FROM customerlogin AS r1 JOIN 
(
    SELECT 
    (
        RAND() * 
        (
            SELECT MAX(clID) 
            FROM customerlogin)) 
    AS clID) 
AS r2 
WHERE r1.clID >= r2.clID 
ORDER BY r1.clID ASC LIMIT 1

但是,我需要更进一步,将可能的答案限制在符合特定条件的答案。

我认为最好的方法是构建一个临时表,仅从原始表中选择有效行,然后从临时表中选择一个随机行,但是我不确定如何去做这样做。我尝试在谷歌上搜索从随机表中创建和选择的各种组合,但到目前为止没有任何乐趣。我假设我只是不知道问我在追求什么的正确方法。

任何人都可以向我指出如何实现这一点的指南或一些示例代码吗?或者,如果有更好的解决方案我忽略了,那么我愿意接受建议。

【问题讨论】:

    标签: mysql sql select random


    【解决方案1】:

    只要您的标准保持不变,您就可以创建一个视图。

    视图是这样的:

    CREATE VIEW customerloginVIEW 
    AS  SELECT clID,  clUserName, clCompanyName, clBio 
    FROM customerlogin
    WHERE something = somethingelse
    GROUP by clID
    ORDER BY clID DESC

    和查询

    SELECT r1.clID, clUserName, clCompanyName, clBio 
    FROM customerloginVIEW AS r1 JOIN 
    (
        SELECT 
        (
            RAND() * 
            (
                SELECT MAX(clID) 
                FROM customerloginVIEW)) 
        AS clID) 
    AS r2 
    WHERE r1.clID >= r2.clID 
    ORDER BY r1.clID ASC LIMIT 1
    

    【讨论】:

      【解决方案2】:

      这个想法是创建一个具有自动递增主键的临时表。 “自动递增”,因此它从 1 开始并且是连续的。 “主键”,因此您可以使用它来非常快速地获取行。

      然后使用您想要的数据子集(或数据 ID)加载表。然后使用ROW_COUNT()获取表中的行数,使用rand()获取随机行。

      以下代码是一个(未经测试的)示例:

      create temporary table temp (
          id int auto_increment primary key,
          clid int
      );
      
      insert into temp(clid)
          select clid
          from customerLogin
          where <what you want>;
      
      select @numrows := ROW_COUNT();
      
      select @therow := (@numrows - 1) * rand();
      
      select cl.*
      from (select temp.*
            from temp
            where id = @therow
           ) temp join
           CustomerLogin cl
           on cl.clid = temp.clid;
      

      【讨论】:

      • 嗯...看来我的主机不允许这样做。很奇怪。一旦我尝试运行它,我就会拒绝用户访问。不过,感谢您花时间向我展示这个。
      【解决方案3】:

      我会得到一个可能的选择列表,随机选择一个,然后获取它。如下所示:

      /* Get list of possible choices */
      SELECT clID
      FROM customerlogin
      WHERE ("match criteria here")
      

      // 使用服务器端语言从这个列表中选择一个随机数?

      /* Reissue query to fetch the chosen random id */
      SELECT *
      FROM customerlogin
      WHERE clID = ("chosenRandomID")
      

      或者,您似乎可以简单地修改随机发生器从中选择的 select 语句:

      SELECT r1.clID, clUserName, clCompanyName, clBio 
      FROM customerlogin AS r1 JOIN 
      (
          SELECT 
          (
              RAND() * 
              (
                  SELECT MAX(clID)
                  FROM customerlogin
                  WHERE ("match criteria here"))) 
          AS clID) 
      AS r2 
      WHERE r1.clID >= r2.clID 
      ORDER BY r1.clID ASC LIMIT 1
      

      【讨论】:

      • 修改语句不起作用。这只是限制了最大 ID。如果不符合条件的 ID 低于符合条件的最高 ID,您仍然会得到不正确的结果。
      猜你喜欢
      • 2021-07-03
      • 1970-01-01
      • 2013-11-18
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 2016-03-21
      相关资源
      最近更新 更多