Mysql ORDER BY RAND()

时间:2015-09-17 08:37:50

标签: mysql sql

我有一个存储所用主题使用次数的表,因为每个后续请求都会增加使用次数。我添加了一个查询来返回最少使用的主题。

      SELECT b.body, n.nid
      FROM node n
      LEFT JOIN body b ON n.nid = b.entity_id
      LEFT JOIN topic_usage u ON n.nid = u.entity_id
      LEFT JOIN reference r ON n.nid = r.entity_id
        AND (
          r.entity_type =  'node'
        AND
          r.deleted =  '0'
        )
      WHERE n.type = :type
      AND n.status = 1
      AND r.target_id= :id
      ORDER BY u.field_topic_usage_value ASC LIMIT 0,1

示例表

nid | Usage Count
-----------------
 1  | 0
 2  | 0
 3  | 0
 4  | 1

上述查询可以正常返回最低使用主题。但要求是在最低使用率上应用RAND()

根据上面的示例表,查询应该使用rand(),其中使用次数为0.

我可以编写2个查询,第一个查询得到最低计数,第二个查询对该计数执行rand()但是可以合并为1吗?

谢谢。

解决方案1 ​​@fancypants

      SELECT b.body, node.nid
      FROM node 
      LEFT JOIN body ON n.nid = body.entity_id 
      LEFT JOIN topic_usage ON n.nid = u.entity_id 
      LEFT JOIN field_data_field_issue_reference r ON node.nid = f.entity_id , 
        ( select @min := ( 
            SELECT min(f.usage_value) from node n 
            LEFT JOIN field_data_field_topic_usage ON n.nid = f.entity_id 
           )
        ) var_init_subquery 
      AND node.status = 1 
      AND f.field_issue_reference_target_id = 708 
      order by f.usage_value, if(f.usage_value=@min, rand(), node.nid) 
      LIMIT 0,1

解决方案2 @Hitesh

    SELECT b.body, node.nid
    FROM node
    LEFT JOIN body ON node.nid = b.entity_id
    LEFT JOIN topic_usage ON node.nid = f.entity_id
    LEFT JOIN issue_reference f ON node.nid = f.entity_id
      AND (
        f.entity_type =  'node'
      AND
        f.deleted =  '0'
      )
    WHERE node.type = 'issue_paragraphs'
    AND node.status = 1
    AND f.field_issue_reference_target_id  = 708
    GROUP BY node.nid having f.usage_value=min(f.usage_value)
    ORDER BY rand() LIMIT 0,1

3 个答案:

答案 0 :(得分:2)

示例数据:

CREATE TABLE t
    (`a` int, `b` int)
;

INSERT INTO t
    (`a`, `b`)
VALUES
    (1, 1),
    (2, 1),
    (3, 0),
    (4, 0),
    (5, 1),
    (6, 0)
;

<强>查询:

select
*
from
t
order by b, if(b=0, rand(), a)

每次执行时,a列都会随机排序,其中b0并按a排序b不是0 1}}。

要让它达到最低限度,您只需使用variables

select
a, b
from
t
, (select @min := (select min(b) from t)) var_init_subquery
order by b, if(b=@min, rand(), a)

答案 1 :(得分:1)

我认为你需要使用Group by和having子句进行选择,然后使用rand()命令。例如,我写的查询如下。根据列选择,我的查询可能有误,但我要专注于approch。

 SELECT b.body, n.nid
      FROM node n
      LEFT JOIN body b ON n.nid = b.entity_id
      LEFT JOIN topic_usage u ON n.nid = u.entity_id
      LEFT JOIN reference r ON n.nid = r.entity_id
        AND (
          r.entity_type =  'node'
        AND
          r.deleted =  '0'
        )
      WHERE n.type = :type
      AND n.status = 1
      AND r.target_id= :id
      GROUP BY n.nid having u.field_topic_usage_value=min(u.field_topic_usage_value)
      ORDER BY rand()

答案 2 :(得分:0)

据我所知,如果您只想对0使用次数的主题应用RAND()排序,则无法使用一个查询。可能的解决方法是更改​​ORDER BY子句,如下所示:

ORDER BY u.field_topic_usage_value ASC, RAND()

这将对所有具有相同使用计数的主题应用随机排序作为可能的解决方法,同时按使用计数本身维护排序。