随机选择满足少数条件的字段

Posted

技术标签:

【中文标题】随机选择满足少数条件的字段【英文标题】:Randomly select fields where few condition met 【发布时间】:2014-07-29 11:39:54 【问题描述】:

这是桌子-

+----+---------+--------+
| 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 |
+----+---------+--------+

它需要查找满足以下条件的记录-

    选择带有LIMIT 3的字母 ORDERRAND() status true or false 都需要呈现,但至少要呈现 带有status TRUE 的字母,但不超过2

希望的结果可能是-

+---------+--------+
| 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 |
+---------+--------+

请大家帮忙。

【问题讨论】:

请编辑您的问题。你的条件3不清楚。听起来您需要从状态为 TRUE 的行中选择三个随机选择的行。对吗? 至少是一封信的礼物是什么意思?这在英语中没有意义。 我编辑了我的问题.. 请任何人检查.. 我目前正在使用 php 执行此操作,但正在寻找一个简单的 mysql 解决方案,可以节省一些查询.. MySQL?那为什么这被标记为 PostgreSQL 和 MS-Access? @ErwinBrandstetter 我认为这是一个与数据库相关的问题.. PostgreSQL 有什么解决方案吗? 【参考方案1】:

根据 cmets 的要求,这是 Postgres 中的解决方案。

假设statusNOT NULL。 假设始终存在至少一行 status FALSE 和一行 status 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。 所有括号都是必需的。详情:

PostgreSQL combine multiple select statements

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

Best way to select random rows PostgreSQL

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

【讨论】:

感谢您的回复.. 投赞成票.. 我读到一篇文章告诉 MySQL 不支持 CTE,但替代方法是使用 TEMPORARY tables,这对我来说效率非常低。我在 MySQL 上尝试了 (SELECT * FROM test order by rand() limit 2) union (select * from test where status=1 order by rand() limit 1) 但有时会返回 2 个结果。希望有人引导我一个适当的解决方案..

以上是关于随机选择满足少数条件的字段的主要内容,如果未能解决你的问题,请参考以下文章

如何生成满足某些条件的三个随机整数? [关闭]

生成2个随机数

对生成随机输出的代码进行单元测试的最佳方法是啥?

随机信号分析学习—多维随机变量与条件随机变量

Scratch 3.x编程技巧:条件语句与随机数

R重复功能直到满足条件