mysql 从具有不同后缀的表中提取数据

evrscar2  于 2023-11-16  发布在  Mysql
关注(0)|答案(2)|浏览(151)

我有多个结构完全相同的表(字段:date、id、revenue)。让我们假设我有3个表,每个表有3行,以使其更简单。
每个表之间唯一的变化是后缀,例如:
Myserver.Mytable_name.05112021(我们称之为表1)
Myserver.Mytable_name.06112021(我们称之为表2)
Myserver.Mytable_name.07112021(我们称之为表3)
我想要的是拉这些表中的一些字段,这样我就不必指定后缀
我期望的结果应该如下所示:
| ID|日期|收入|
| --|--|--|
| id_1|日期_1|收入_1|
| id_2|日期_1|收入_1|
| id_3|日期_1|收入_1|
| id_1|日期_2|收入_2|
| id_2|日期_2|收入_2|
| id_3|日期_2|收入_2|
| id_1|日期_3|收入_3|
| id_2|日期_3|收入_3|
| id_3|日期_3|收入_3|
我怎样才能得到上面的结果,而不使用union或union all?
这很重要,因为我的表是每天创建的,我不想为了获取数据而在CTE中手动添加它们。
谢谢你的帮助!
在这种情况下使用union或unionall是很麻烦的

hpxqektj

hpxqektj1#

你需要UNION/UNION ALL来完成这个操作,但是有一种方法可以让你只写一次查询,然后在需要的地方进行编辑,你可以使用PREPARED STATEMENT。
下面是一个例子:

  1. SET @generatedQuery := NULL;
  2. SELECT GROUP_CONCAT( CONCAT('SELECT * FROM ',table_name) SEPARATOR ' UNION ALL ')
  3. INTO @generatedQuery
  4. FROM information_schema.tables
  5. WHERE
  6. table_schema='Myserver' AND
  7. table_name LIKE 'mytable_%';
  8. /*Check the generated query*/
  9. SELECT @generatedQuery;
  10. PREPARE statement FROM @generatedQuery;
  11. EXECUTE statement;
  12. DEALLOCATE PREPARE statement;

字符串
在上面的例子中,你只需要关注查询来生成实际的查询。假设你只想获取特定的日期范围,那么你可以这样做:

  1. SELECT GROUP_CONCAT(CONCAT('SELECT * FROM ',table_name,' WHERE date="2023-11-11"'))
  2. SEPARATOR ' UNION ALL ')
  3. INTO @generatedQuery
  4. FROM information_schema.tables
  5. WHERE
  6. table_schema='Myserver' AND
  7. table_name LIKE 'mytable_%';


或者可能数据库/服务器(table_schema)已经改变,或者table_name前缀现在不同了,那么:

  1. SELECT GROUP_CONCAT( CONCAT('SELECT * FROM ',table_name) SEPARATOR ' UNION ALL ')
  2. INTO @generatedQuery
  3. FROM information_schema.tables
  4. WHERE
  5. table_schema='newserver' AND
  6. table_name LIKE 'myNewtableName_%';


Demo fiddle

展开查看全部
lbsnaicq

lbsnaicq2#

这很重要,因为我的表是每天创建的,我不想为了获取数据而在CTE中手动添加它们
然后你需要动态地生成SQL。
避免这种情况的另一种方法是创建一些标准视图,这些视图从表中返回数据,但让创建表的进程重新创建视图,这样就可以有一个不需要更改的查询。

  • 无论哪种方式,某些进程都需要更改视图或更改查询以引用新表。动态SQL是数据库内部的常见解决方案,但否则您可以在应用程序层生成查询,这将是相同的主体。

在我看来,Union是完美的:
从手动查询开始:
https://sqlfiddle.com/#!9/afd29a/2
请注意,这里我使用表名的后缀构造了一个日期列

  1. SELECT STR_TO_DATE(RIGHT('Mytable_name.05112021',8),'%d%m%Y') as "date"
  2. , `id`
  3. , `revenue`
  4. FROM `Mytable_name.05112021`
  5. UNION ALL
  6. SELECT STR_TO_DATE(RIGHT('Mytable_name.06112021',8),'%d%m%Y') as "date"
  7. , `id`
  8. , `revenue`
  9. FROM `Mytable_name.06112021`
  10. UNION ALL
  11. SELECT STR_TO_DATE(RIGHT('Mytable_name.07112021',8),'%d%m%Y') as "date"
  12. , `id`
  13. , `revenue`
  14. FROM `Mytable_name.07112021`;

字符串
我不知道在MySQL中有什么函数可以用来返回给定列引用的表名,但是如果我们要使用动态或 * 准备好的语句 *,那就没关系了。
首先,我们可以使用这个查询生成上面的SQL:

  1. SELECT GROUP_CONCAT(CONCAT("SELECT STR_TO_DATE(RIGHT('", table_name, "',8),'%d%m%Y') as \"date\", `id`, `revenue` FROM `", table_name ,"`") SEPARATOR ' UNION ALL ') as Query
  2. FROM information_schema.tables
  3. WHERE table_name like 'MyTable_name.%';


它返回以下内容:

  1. SELECT STR_TO_DATE(RIGHT('mytable_name.05112021',8),'%d%m%Y') as "date", `id`, `revenue` FROM `mytable_name.05112021` UNION ALL SELECT STR_TO_DATE(RIGHT('mytable_name.06112021',8),'%d%m%Y') as "date", `id`, `revenue` FROM `mytable_name.06112021` UNION ALL SELECT STR_TO_DATE(RIGHT('mytable_name.07112021',8),'%d%m%Y') as "date", `id`, `revenue` FROM `mytable_name.07112021`


因此,我们可以将所有这些功能整合到一个SP中,下面是一个完整的示例,您可以按照该示例进行操作
https://www.db-fiddle.com/f/4Xiv7XtbhP7d2N5EdqsYg4/0

  1. CREATE PROCEDURE dynamicQuery()
  2. BEGIN
  3. SET @query = (SELECT GROUP_CONCAT(CONCAT("SELECT STR_TO_DATE(RIGHT('", table_name, "',8),'%d%m%Y') as \"date\", `id`, `revenue` FROM `", table_name ,"`") SEPARATOR ' UNION ALL ') as Query
  4. FROM information_schema.tables
  5. WHERE table_name like 'MyTable_name.%');
  6. PREPARE stmt FROM @query;
  7. EXECUTE stmt;
  8. DEALLOCATE PREPARE stmt;
  9. END

Schema(MySQL v5.7)

  1. DELIMITER //
  2. CREATE TABLE `Mytable_name.05112021` (
  3. `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  4. `revenue` decimal(10,2)
  5. )//
  6. CREATE TABLE `Mytable_name.06112021` (
  7. `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  8. `revenue` decimal(10,2)
  9. )//
  10. CREATE TABLE `Mytable_name.07112021` (
  11. `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  12. `revenue` decimal(10,2)
  13. )//
  14. INSERT INTO `Mytable_name.05112021` (`revenue`) VALUES
  15. ( 50.10 ),
  16. (135.10),
  17. (35.75 )//
  18. INSERT INTO `Mytable_name.06112021` (`revenue`) VALUES
  19. ( 60.10 ),
  20. (136.10),
  21. (36.75 )//
  22. INSERT INTO `Mytable_name.07112021` (`revenue`) VALUES
  23. ( 70.10 ),
  24. (137.10),
  25. (37.75 )//
  26. CREATE PROCEDURE dynamicQuery()
  27. BEGIN
  28. SET @query = (SELECT GROUP_CONCAT(CONCAT("SELECT STR_TO_DATE(RIGHT('", table_name, "',8),'%d%m%Y') as \"date\", `id`, `revenue` FROM `", table_name ,"`") SEPARATOR ' UNION ALL ') as Query
  29. FROM information_schema.tables
  30. WHERE table_name like 'MyTable_name.%');
  31. PREPARE stmt FROM @query;
  32. EXECUTE stmt;
  33. DEALLOCATE PREPARE stmt;
  34. END
  35. //
  1. CALL dynamicQuery;

| 日期|ID|收入|
| --|--|--|
| 2021-11-05| 1 |50.10|
| 2021-11-05| 2 |135.10|
| 2021-11-05| 3 |三十五点七五|
| 2021-11-06 2021-11-06 2021-11-06| 1 |60.10|
| 2021-11-06 2021-11-06 2021-11-06| 2 |136.10|
| 2021-11-06 2021-11-06 2021-11-06| 3 |三十六点七五|
| 2021-11-07 2021-11-07| 1 |70.10|
| 2021-11-07 2021-11-07| 2 |137.10|
| 2021-11-07 2021-11-07| 3 |三十七点七五|
View on DB Fiddle

展开查看全部

相关问题