【问题标题】:SUM values of specific column from all tables LIKE table_%所有表中特定列的 SUM 值 LIKE table_%
【发布时间】:2018-03-27 19:07:45
【问题描述】:

我需要帮助来创建一个 SQL 查询,以便对所有表 LIKE table_% 中的特定列的值求和,因为表会随着时间的推移而增长,这必须满足基于以下格式的新表名


方案名称: database_01

表名: tb_data_'YEAR'_'MONTH'


  • YEARMONTH 都是从 2011 年到 2018 年的所有 12 个月和年份的值。

每个表都包含一个名为 TOTAL_VALUE 的列。我有一个触发 SQL 查询以从数据库中提取数据的 php 脚本。

我想对每个表 TOTAL_VALUE 列的总数求和,并保存下面我的脚本的值以推送数组。

$sql = "SELECT TOTAL_VALUES FROM tb_data_2017_october";   
$result = mysqli_query($conn, $sql);

$data = array(); while($enr = mysqli_fetch_assoc($result)){
    $a =  array($enr['TOTAL_VALUES']);
    foreach ($a as $as){
        echo "'".$as."', ";}
    array_push($data, $as); }

我一直在尝试使用以下选项更改 SQL:

SELECT id FROM table1
    UNION
    SELECT id FROM table2
    UNION
    SELECT id FROM table3
    UNION
    SELECT id FROM table4

但是我需要满足检查所有类似于 tb_data_% 的表的能力

【问题讨论】:

  • 这是一个糟糕的数据库设计。如果可以,请重新考虑。
  • 同意你的观点,但目前数据是这样的。必须迁移到具有指定数据的列的单个数据库。但是,我将不胜感激有关当前可能的解决方案的任何反馈。不过感谢您的回复。
  • 然后从schema 中选择所有您需要的名称并创建一个大联合查询。
  • 你使用的是什么数据库服务器?
  • 提示:使用循环

标签: php mysql sql


【解决方案1】:

有关获取表列表的信息,请参阅此问题:Get table names using SELECT statement in MySQL

您可以在一个查询结果中获取表的列表,然后查询每个表。我会稍微修改你的代码来举个例子:

// Get the tables
$tables_sql = "SELECT table_name 
                FROM information_schema.tables 
                WHERE table_schema='<your DB>' 
                AND table_name LIKE 'tb_data%'";  

$tables = mysqli_query($conn, $sql);

// Iterate over the tables
while($table = mysqli_fetch_assoc($tables)){
{
    /*
    * Your code
    */

    // This query assumes that you can trust your table names not to to an SQL injection
    $sql = "SELECT TOTAL_VALUES FROM " . $table['table_name']; 
    $result = mysqli_query($conn, $sql);

    $data = array(); while($enr = mysqli_fetch_assoc($result)){
        $a =  array($enr['TOTAL_VALUES']);
        foreach ($a as $as){
            echo "'".$as."', ";
        array_push($data, $as); }
}

获得表格列表后,您可以做任何您需要的事情。您可以构建一个大的联合查询(这比单独查询每个表更有效),或者将表提供给MERGE 引擎,如barmar's answer

【讨论】:

  • 以下代码完全错误,与文件突然结束有关。不幸的是,没有 Echo 产生,这可能是基于表没有通过 TOTAL_VALUE 列吗?
  • @user9560017 看起来是因为我从您的问题中复制的代码中有一个额外的}。在我的示例中,我刚刚编辑了问题以删除回显行 (echo "'".$as."', ";) 末尾的 }
【解决方案2】:

使用MERGE存储引擎创建一个虚拟表,将所有的月表组合在一起。

CREATE TABLE tb_all_data (
    ...
) ENGINE=MERGE UNION=(tb_data_2017_october, tb_data_2017_november, ...);

列出UNION= 列表中的所有表,并在创建新表时对其进行更新。

然后你可以从tb_all_data查询。

【讨论】:

  • 感谢您的分享,由于每个表大约有 250,000 行,因此我应该注意哪些限制。月份和年份的表格中也没有参考,这只是在表格名称中。
  • @user9560017 在 250k 行时,您绝对应该选择 sum(TOTAL_VALUES),而不是每一行。
  • @user9560017 来自文档:MERGE 表中的最大行数为 2^64 (~1.844E+19)。如果每个表包含大约 250K 行,则只能合并 72 万亿张表。
  • 阅读我链接到的文档以了解更多注意事项。
  • 这样组合多个表可能会出现性能问题,但如果编写UNION 查询也会出现同样的情况。
【解决方案3】:

试试这个 - 它会循环使用您想要的模式的所有表格并为您创建总和:

declare @table table (rowid int identity, name varchar(max))
        insert @table
        select name from sys.tables where name like '%yourname%'

        declare @holding table (name varchar(max), sumvalue int)

        declare @iterator int = 1
        declare @tablename varchar(max)
        while @iterator<=(select max(rowid) from @table)
        begin
        select @tablename=name from @table where rowid=@iterator

        insert @holding
        exec('select '+@tablename+' sum(TOTAL_VALUE)TOTAL_VALUE from '+@tablename+' group by +'+@tablename+'')

        set @iterator=@iterator+1
        end 

    select * from @holding

【讨论】:

    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2015-07-29
    • 2023-03-21
    相关资源
    最近更新 更多