Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
内连接中的mysql随机选择_Mysql - Fatal编程技术网

内连接中的mysql随机选择

内连接中的mysql随机选择,mysql,Mysql,这个问题和我的差不多,但从来没有人回答过 我有一个主表m和从表s。对于每个m,S包含1到多行。我想要一个查询,选择每一个主行连接到一个随机选择的从属 如果表架构为: M --- id S --- id mid 然后,在伪代码中,查询将是: 在m.id=s.mid上从m内部连接s中选择*s,其中s.id是从现有值中随机选择的值 这可以转换成真正的SQL吗?这可以用概念来解决。我们需要在表s的mid分区内随机分配行号值。并且,使用mid和row_number=1从m表连接到s。这将每次随机选取一

这个问题和我的差不多,但从来没有人回答过

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

如果表架构为:

M
---
id

S
---
id
mid
然后,在伪代码中,查询将是: 在m.id=s.mid上从m内部连接s中选择*s,其中s.id是从现有值中随机选择的值

这可以转换成真正的SQL吗?

这可以用概念来解决。我们需要在表s的mid分区内随机分配行号值。并且,使用mid和row_number=1从m表连接到s。这将每次随机选取一行

在低于8的MySQL版本中,我们可以使用来模拟行数。要了解其工作原理,您可以查看以下答案以了解解释:

请注意,与在SELECT子句中使用子查询相比,这种技术在大型表上更有效,因为它只会对整个表进行一次排序

质疑

结果运行1

结果运行2

结果运行3

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

SELECT 
  m.*, s_dt.id, s_dt.mid, s_dt.s_nm 
FROM 
  m 
JOIN 
(
  SELECT
    s.*, 
    ROW_NUMBER() OVER w AS row_num
  FROM s
  WINDOW w AS (PARTITION BY mid 
               ORDER BY RAND())
) AS s_dt 
  ON s_dt.mid = m.id AND 
     s_dt.row_num = 1

我认为以下查询完成了所需的工作,但使用的是子查询而不是内部联接:

SELECT *, (SELECT id FROM S WHERE S.mid = M.id ORDER BY RAND() LIMIT 1) AS S_id
FROM M
这里有一个测试它的方法。
希望有帮助。

您的MySQL服务器版本是什么?是S.id,一个自动增量/INT值?是否可以假设它是均匀的,没有明显的差距,或者在随机选择中缺少平等的机会?实际上,我看到我的主机正在运行MariaDB。10.1.31-MariaDB-cll-lve Innodb_版本5.6.36-83.0s.id将自动递增,但很可能会因删除而产生间隙这对大型S表无效:是的,我刚刚创建了自己的。这里是:我猜是相同的结果。不,所有ID都是数字。检查链接,不用担心。玩得开心@TeeKea请检查更新的答案。之前的答案可能有错别字;因为新查询中的概念仍然保持不变。
| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 2   | 1   | aa   |
| 2   | b    | 5   | 2   | bbbb |
| 3   | c    | 7   | 3   | ccc  |
| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 1   | 1   | aa   |
| 2   | b    | 4   | 2   | bbb  |
| 3   | c    | 6   | 3   | cc   |
| id  | m_nm | id  | mid | s_nm |
| --- | ---- | --- | --- | ---- |
| 1   | a    | 1   | 1   | aa   |
| 2   | b    | 3   | 2   | bb   |
| 3   | c    | 7   | 3   | ccc  |
SELECT 
  m.*, s_dt.id, s_dt.mid, s_dt.s_nm 
FROM 
  m 
JOIN 
(
  SELECT
    s.*, 
    ROW_NUMBER() OVER w AS row_num
  FROM s
  WINDOW w AS (PARTITION BY mid 
               ORDER BY RAND())
) AS s_dt 
  ON s_dt.mid = m.id AND 
     s_dt.row_num = 1
SELECT *, (SELECT id FROM S WHERE S.mid = M.id ORDER BY RAND() LIMIT 1) AS S_id
FROM M