如何自动从多个表中选择一列
How to automate selection of a column from multiple tables
我有几个至少 26 个表...我正在尝试 select 所有表中的一列并将它们显示为一个
我试过这个:
(SELECT col1,col2,col3,col4
FROM table1
ORDER BY col1 DESC LIMIT 1)
UNION
(SELECT col1,col2,col3,col4
FROM table2
ORDER BY col1 DESC LIMIT 1)
这行得通,但我必须复制和粘贴很多次,具体取决于我拥有的表格数量,这不是很有效。请帮忙——我刚开始学习 mysql,但我一直在尝试解决这个问题。
您可以通过在存储过程中使用游标来实现,如下所示:
CREATE DEFINER=`homestead`@`%` PROCEDURE `union_tables`()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE tablename VARCHAR(100);
DECLARE tableschema VARCHAR(100);
DECLARE sql_union_tables TEXT;
DECLARE tables_cursor CURSOR FOR SELECT TABLE_NAME, TABLE_SCHEMA FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = 'DbInscripciones' AND TABLE_NAME LIKE 'TblFaltasA%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN tables_cursor;
SET sql_union_tables = '';
read_loop: LOOP
FETCH tables_cursor INTO tablename, tableschema;
IF done THEN
LEAVE read_loop;
END IF;
IF sql_union_tables = '' THEN
SET sql_union_tables = CONCAT('(SELECT numcontrol FROM ', tableschema, '.', tablename, ' LIMIT 1)');
ELSE
SET sql_union_tables = CONCAT(sql_union_tables, ' UNION ALL (SELECT numcontrol FROM ', tableschema, '.', tablename, ' LIMIT 1)');
END IF;
END LOOP;
CLOSE tables_cursor;
SET sql_union_tables = CONCAT(sql_union_tables, ';');
PREPARE stmt FROM sql_union_tables;
EXECUTE stmt;
SELECT sql_union_tables;
END
让我们分部分解释一下。您可以通过查询 information_schema
数据库获得所需 table 名称的列表,并且 tables_cursor
游标将允许您遍历该 table 列表。
在迭代部分,您使用从游标查询中获得的 table 构造一个查询并将其保存在 sql_union_tables
.
中
构建完查询后,您可以使用 PREPARE
和 EXECUTE
语句以及 return 结果查询(最后一行)来执行它。
此存储过程假设您的 table 中有相同的列。如果您的列因每个 table 而异,您将必须实施一些逻辑来处理它。
在此之后,您可以像这样调用存储过程:
CALL union_tables
我有几个至少 26 个表...我正在尝试 select 所有表中的一列并将它们显示为一个
我试过这个:
(SELECT col1,col2,col3,col4
FROM table1
ORDER BY col1 DESC LIMIT 1)
UNION
(SELECT col1,col2,col3,col4
FROM table2
ORDER BY col1 DESC LIMIT 1)
这行得通,但我必须复制和粘贴很多次,具体取决于我拥有的表格数量,这不是很有效。请帮忙——我刚开始学习 mysql,但我一直在尝试解决这个问题。
您可以通过在存储过程中使用游标来实现,如下所示:
CREATE DEFINER=`homestead`@`%` PROCEDURE `union_tables`()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE tablename VARCHAR(100);
DECLARE tableschema VARCHAR(100);
DECLARE sql_union_tables TEXT;
DECLARE tables_cursor CURSOR FOR SELECT TABLE_NAME, TABLE_SCHEMA FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = 'DbInscripciones' AND TABLE_NAME LIKE 'TblFaltasA%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN tables_cursor;
SET sql_union_tables = '';
read_loop: LOOP
FETCH tables_cursor INTO tablename, tableschema;
IF done THEN
LEAVE read_loop;
END IF;
IF sql_union_tables = '' THEN
SET sql_union_tables = CONCAT('(SELECT numcontrol FROM ', tableschema, '.', tablename, ' LIMIT 1)');
ELSE
SET sql_union_tables = CONCAT(sql_union_tables, ' UNION ALL (SELECT numcontrol FROM ', tableschema, '.', tablename, ' LIMIT 1)');
END IF;
END LOOP;
CLOSE tables_cursor;
SET sql_union_tables = CONCAT(sql_union_tables, ';');
PREPARE stmt FROM sql_union_tables;
EXECUTE stmt;
SELECT sql_union_tables;
END
让我们分部分解释一下。您可以通过查询 information_schema
数据库获得所需 table 名称的列表,并且 tables_cursor
游标将允许您遍历该 table 列表。
在迭代部分,您使用从游标查询中获得的 table 构造一个查询并将其保存在 sql_union_tables
.
构建完查询后,您可以使用 PREPARE
和 EXECUTE
语句以及 return 结果查询(最后一行)来执行它。
此存储过程假设您的 table 中有相同的列。如果您的列因每个 table 而异,您将必须实施一些逻辑来处理它。
在此之后,您可以像这样调用存储过程:
CALL union_tables