mysql内部选择中的随机选择

时间:2018-11-28 02:54:04

标签: mysql

问题Mysql Random Row Query on Inner Join与我的问题大致相同,但从未得到解答。

我有一个主表m和一个从表s。 S每m包含1到许多行。我想要一个查询,该查询选择连接到恰好一个随机选择的从属的每个主行。

如果表模式为:

M
---
id

S
---
id
mid

然后,用伪代码查询将是: select * from m inner join s on m.id = s.mid,其中s.id是从存在的值中随机选择的一个

可以将其转换为真实的SQL吗?

2 个答案:

答案 0 :(得分:1)

我认为以下查询可完成所需的工作,但使用子查询(而非内部联接):

SELECT *, (SELECT id FROM S WHERE S.mid = M.id ORDER BY RAND() LIMIT 1) AS S_id
FROM M

这里是link进行测试。 希望对您有所帮助。

答案 1 :(得分:0)

这可以使用Row_Number()概念来解决。我们需要在表mid的{​​{1}}分区中随机分配行号值。然后,使用sms表到mid的联接。每次都会选择一个随机行。

在低于8的MySQL版本中,我们可以使用User-defined Variables来仿真row_number = 1。要了解其工作原理,您可以查看以下答案以获取解释:https://stackoverflow.com/a/53465139/2469308

请注意,该技术在大型表上比使用子查询(在Row_Number()子句中)更为有效,因为它将对整个表进行一次排序。 strong>

View on DB Fiddle

SELECT

查询

create table m (id int, m_nm varchar(10));
create table s (id int, 
                mid int references m(mid), 
                s_nm varchar(10));

insert into m values(1, "a");
insert into m values(2, "b");
insert into m values(3, "c");

insert into s values(1, 1, "aa");
insert into s values(2, 1, "aa");
insert into s values(3, 2, "bb");
insert into s values(4, 2, "bbb");
insert into s values(5, 2, "bbbb");
insert into s values(6, 3, "cc");
insert into s values(7, 3, "ccc");

结果(运行#1)

SELECT 
  m.*, s_dt.id, s_dt.mid, s_dt.s_nm 
FROM 
  m 
JOIN 
(
SELECT
  @rn := IF(@m = dt.mid, @rn+1, 1) AS row_num,   
  @m := dt.mid AS mid, 
  dt.id, 
  dt.s_nm 
FROM 
( 
SELECT
   id, mid, s_nm, RAND() as rand_num
 FROM s
 ORDER BY mid, rand_num ) AS dt
CROSS JOIN (SELECT @rn:=0, @m:=0) AS user_vars 
) AS s_dt 
  ON s_dt.mid = m.id AND 
     s_dt.row_num = 1;

结果(运行#2)

| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 2   | 1   | aa   |
| 2   | b    | 5   | 2   | bbbb |
| 3   | c    | 7   | 3   | ccc  |

结果(运行#3)

| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 1   | 1   | aa   |
| 2   | b    | 4   | 2   | bbb  |
| 3   | c    | 6   | 3   | cc   |

MySQL 8.0.2+ / MariaDB 10.3 + 解决方案如下:

| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 1   | 1   | aa   |
| 2   | b    | 3   | 2   | bb   |
| 3   | c    | 7   | 3   | ccc  |

View on DB Fiddle