随机选择满足条件的字段

时间:2014-07-29 11:39:55

标签: php mysql sql postgresql ms-access

这是表格 -

+----+---------+--------+
| id | letters | status |
+----+---------+--------+
|  1 | A       |      0 |
|  2 | B       |      1 |
|  3 | C       |      0 |
|  4 | D       |      0 |
|  5 | E       |      1 |
|  6 | F       |      1 |
|  7 | G       |      0 |
|  8 | H       |      0 |
+----+---------+--------+

需要查找具有以下条件的记录 -

  1. 选择LIMIT 3
  2. 的字母
  3. ORDERRAND()
  4. status true or false 都需要呈现,但至少需要呈现 包含status TRUE但不超过2
  5. 的字母

    欲望结果可能是 -

    +---------+--------+
    | letters | status |
    +---------+--------+
    | B       |      1 |
    | E       |      1 |
    | H       |      0 |
    +---------+--------+
    
    +---------+--------+
    | letters | status |
    +---------+--------+
    | C       |      0 |
    | E       |      1 |
    | H       |      0 |
    +---------+--------+
    

    但不是 -

    +---------+--------+
    | letters | status |
    +---------+--------+
    | C       |      0 |
    | G       |      0 |
    | H       |      0 |
    +---------+--------+
    
    +---------+--------+
    | letters | status |
    +---------+--------+
    | B       |      1 |
    | E       |      1 |
    | F       |      1 |
    +---------+--------+
    

    任何人都请帮忙。

1 个答案:

答案 0 :(得分:1)

以下是评论中要求的 Postgres 解决方案。

假设statusNOT NULL 假设至少有一行status FALSEstatus TRUE一直存在。

WITH cte AS (
   (
   SELECT id, letters, status
   FROM   tbl
   WHERE  status       -- 1 row with status true
   ORDER  BY random()
   LIMIT  1
   )
   UNION ALL
   (
   SELECT id, letters, status
   FROM   tbl
   WHERE  NOT status   -- 1 row with status false
   ORDER  BY random()
   LIMIT  1
   )
   )
SELECT * FROM cte
UNION ALL              -- add another random row
(
SELECT id, letters, status
FROM   tbl
LEFT   JOIN cte c USING (id)
WHERE  c.id IS NULL    -- don't select row twice
ORDER  BY random()
LIMIT  1
)
ORDER BY random();     -- order 3 rows randomly

MySQL确实支持CTEs 所有括号都是必要的。详细说明:

这对于大表来说效率不高。为了获得更好的性能,请考虑以下相关答案:

如果状态TRUEFALSE不是非常不平衡,我会写一个plpgsql函数循环遍历随机排序的表(或选择like in the the linked answer),直到我有三行at每个状态中至少有一个。会快得多。