【问题标题】:How to group the table rows and add summary row above the group?如何对表格行进行分组并在组上方添加摘要行?
【发布时间】:2023-03-21 22:50:01
【问题描述】:

我有一个输出大量信息的 sql 查询。我需要做的是对输出表中的信息进行分组和汇总。这是我正在尝试做的一个示例:

name        val1    val2    val3    total   Run
some name    18       4       1       23    
 some name    5       4       1       23     2
 some name   13       8       2       23     1
other name    2       2       0        4     1
and name      2      42       1       45     1

来自数据库的名称可以出现不止一次。如果是这样,我将这些项目组合在一起并在上方添加摘要行,该行将具有相同的名称但也会计算总数:

  • Val1 必须加在一起
  • Val2、Val3 必须与 RUN 单元格中值最大的行相同
  • 总价值始终保持不变。

在输出表中会多次出现这种分组。 我试图用谷歌搜索我的问题,但最接近我正在寻找的问题是:How to add rows in middle of a table with jQuery? 这不是我真正在做什么。

我不确定是否有我可以使用的 sql 命令来执行此操作,或者是否可以在 php 中或使用 jquery 来完成。任何建议将不胜感激。

谢谢!

更新:

我曾尝试在 sql 中使用 GROUP BY,但它给了我语法错误:

SELECT name, val1, val2, val2, run
FROM tableName
WHERE ... ORDER BY name DESC GROUP BY name

(不要介意 WHERE ...我实际上在那里有陈述)。 当我在查询中有两个或三个结果并且所有三个都具有相同的名称时,它实际上对查询进行了分组。所以我虽然 GROUP BY 不是选项。

在 php 中,我将名称存储到变量中并检查名称是否相同。如果不一样,我将大师班添加到行中,如果不是,则该班级是孩子,这有助于我对其进行分组。但是我没有想出在上面添加摘要行的方法。

我在想每次名称更改时添加一个空白行并在页面加载后使用 jquery 填充它,但是,对于一次名称的出现,我不需要摘要。

至于,总结行中的 Val3 我在上面做了修改。 Val3 将与具有最大运行值的行中的 val3 相同。我想我被自己的例子弄糊涂了。

我希望这些信息对您有所帮助。

【问题讨论】:

  • 这一切都很好 - 但是除了谷歌之外,您还尝试过什么来解决您的问题?您是否有已经开始开发的 SQL、PHP 或 JQuery,但后来卡住了?向我们展示一些东西,它会更容易为您提供帮助。
  • 我能理解你对 val1 和 val2 的意思,但我不明白 val3。你要减去什么,又要减去什么?
  • 感谢您的cmets,我已经添加了上面的更改。
  • Andres,你是对的,我已经开始开发代码,但我被卡住了。我不确定解决问题的方法。
  • JJS,我已经在问题描述中进行了更新,希望对您有所帮助。谢谢!

标签: php jquery sql group-by


【解决方案1】:

每当我必须做这样的事情时,我都会使用多维关联数组,其中顶级键是我想要做的最高级别的分组。在您的情况下,这将是“名称”。

在该数组的每个元素中,还有另一个关联数组,其中包含我要跟踪的每个值的键。还有一个编号的子数组,它将包含属于该分组的每一行。

在完成所有行之后,我会遍历生成的关联数组并打印结果。

例如:

<?php

/** Simulate of the results of your SQL query **/
$sql_result = array(
    array("name"=>"some name ", "val1"=>5,  "val2"=>4,  "val3"=>1,  "run" =>2),
    array("name"=>"some name ", "val1"=>13, "val2"=>8,  "val3"=>2,  "run" =>1),
    array("name"=>"other name", "val1"=>2,  "val2"=>2,  "val3"=>0,  "run" =>1),
    array("name"=>"and name",   "val1"=>2,  "val2"=>42, "val3"=>1,  "run" =>1)
);

/** Add each result to your assoc array **/
$names = array();
foreach($sql_result as $row) {
    $name = $row["name"];

    // Create a new assoc array for each different name
    if( !$names[$name] ) {
        $names[ $name ] = array(
            "name"      => $row["name"],
            "max_run"   => $row["run"],
            "val1"      => $row["val1"],
            "val2"      => $row["val2"],
            "val3"      => $row["val3"],
            "runs"      => array( $row )
        );
        continue;
    }

    // Update the necessary values for the highest "run" number
    if ($row["run"] > $names[ $name ]["max_run"]) {
         $names[ $name ]["max_run"] = $row["run"];
         $names[ $name ]["val2"]    = $row["val2"];
         $names[ $name ]["val3"]    = $row["val3"];
    }

    // Update the reset of the values
    $names[ $name ]["val1"]     += $row["val1"];
    $names[ $name ]["total"]    = $names[ $name ]["val1"] + $names[ $name ]["val2"] + $names[ $name ]["val3"];
    $names[ $name ]["runs"][]   = $row;

}

/** Print your results **/
foreach ($names as $name) {
    // Print your totals here like $name["total"], $name["val1"]
    echo  $name["name"]." ";
    echo  $name["val1"]." ";
    echo  $name["val2"]." ";
    echo  $name["val3"]." ";
    echo  $name["total"]."<br>";
    if ( count($name["runs"]) > 1 ) {
        foreach( $name["runs"] as $run ) {
            echo print_r($run)."<br>";
        }
    }
    echo "<hr>";
}

?>

此代码已测试

【讨论】:

  • 谢谢 JJS,这是一个很棒的方法。我也在考虑将它存储到数组中,但不想用完额外的内存,因为通常我会从查询中得到至少 100 个结果。你认为有办法避免数组吗?如果没有,我会保留这个实现
  • 比我聪明的人可能会发布一些东西,但我能想到的唯一其他方法是在你的 SQL 中添加一些子查询。 assoc 数组方法是我经常使用的一种方法,即使结果超过 100 个,我也没有遇到任何问题。
  • 非常感谢您的帮助。对此,我真的非常感激!再次感谢!
  • 没问题。如果没有人发布更好的内容,您可以随时点击接受以感谢我的回答:)
猜你喜欢
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 2022-09-27
  • 2019-10-08
相关资源
最近更新 更多