提问者:小点点

随机派生表中的随机行


我有一组表,我想从其中一个随机的表中选择一个随机的行。

如果有5张桌子

Table1
Table2
Table3
Table4
Table5

每个都有相同的数据格式。

我已经尝试了下面,第一部分在选择一个随机表工作,但抓取信息从表返回0行。

 SELECT * FROM (SELECT `cat_table_name` from `category-defines` GROUP BY `cat_table_name` LIMIT 1) AS x ORDER BY RAND() LIMIT 3

共2个答案

匿名用户

不是每个任务都可以在一个SQL查询中完成。

在SQL中,所有表名(实际上,所有标识符)必须在解析查询时固定。 您不能编写一个基于查询期间求值的表达式来选择表(或列等)的SQL查询。

以此类推:这会像在任何其他代码中一样,尝试调用一个函数,其名称基于您想要调用的函数的返回值。

所以您不能在一个查询中执行您想要的操作。

您可以在一个查询中随机选择表名,然后在形成下一个查询时使用该结果。

SELECT `cat_table_name` from `category-defines` GROUP BY `cat_table_name` LIMIT 1

SELECT * FROM `$result_from_previous_query` ORDER BY RAND() LIMIT 3

这是最简单的解决方案。

一定要用勾号分隔表名,以防其中一个表名是from或其他保留的关键字。

(注意:上面的第一个查询不选择随机的表名,它总是选择第一个表)。

上面的注释建议将所有表合并。 这就是它的样子:

SELECT *
FROM 
(SELECT FLOOR(RAND()*5)+1 AS table_num) AS r
JOIN (
    (SELECT 1 AS table_num, * FROM my_table1 ORDER BY RAND() LIMIT 3)
    UNION
    (SELECT 2 AS table_num, * FROM my_table2 ORDER BY RAND() LIMIT 3)
    UNION
    (SELECT 3 AS table_num, * FROM my_table3 ORDER BY RAND() LIMIT 3)
    UNION
    (SELECT 4 AS table_num, * FROM my_table4 ORDER BY RAND() LIMIT 3)
    UNION
    (SELECT 5 AS table_num, * FROM my_table5 ORDER BY RAND() LIMIT 3)
) AS x USING (table_num) 

但这至少有两个问题:

  • 它承担了从每个表中挑选随机行的性能代价,只是为了扔掉其中的大部分。 浪费。
  • 您仍然必须事先知道表名,因此如果这些表名没有被修复,您将在此查询之前运行另一个查询以获取表名列表。

匿名用户

这是因为主查询将对派生表的结果(在本例中是表名)执行,而不是对实际的表名执行。

就我的MySQL知识而言,您必须将其分成两个查询,其中第一个查询检索表名,第二个查询使用第一个查询的结果。 在PHP中,它应该是这样的

//get a random table name
$stmt = $this->pdo->prepare('SELECT `cat_table_name` as table from `category-defines` GROUP BY `cat_table_name` LIMIT 1');
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);

//select 3 random rows with the table name
$stmt = $this->pdo->prepare('SELECT * FROM '.$row['table'].' ORDER BY RAND() LIMIT 3');

$stmt->execute();
$randomRows = $stmt->fetchAll(PDO::FETCH_ASSOC); //the three random rows