使用PHP/PDO对不同SQL表中的多个列求和并求平均值


Sum and average multiple columns from different SQL tables with PHP/PDO

为了简单明了,我有以下两种SQL表结构:

tbl1: col1, col2, col3
tbl2: col1, col2, col3

两个表的列数相同,并且两个表中的列ID相同。此外,对于两个表,col1中的所有值都是相同的。两个表都有大约2000个条目,所有条目都是整数,并且两个表通常都有相同数量的条目。

现在,我有了第三个表,它的结构与前两个表相同,我正试图用前两个表格中每列中每个值的总和填充它,如下所示:

tbl3: col1, (tbl1.col2+tbl2.col2), (tbl1.col3+tbl2.col3)

最后,我还有一个第四个表,它将具有前两个表中每个值的平均值,如下所示:

tbl3: col1, (tbl1.col2+tbl2.col2)/2, (tbl1.col3+tbl2.col3)/2

我一直在研究如何使用子查询和联合操作(如@Jonysuise在这里描述的)来实现这一点,但当我这样做时,我看到tbl3中插入了不正确的值,根本没有值,或者PDO语法错误。

此外,由于这些数据需要如何在上游处理,我正在通过PDO执行这项工作,由于我对这种结构不太熟悉,我开始怀疑是否存在一些我没有得到的不同的推荐方法。

最后一个没有抛出错误的版本是:

$db->exec("INSERT INTO tbl3 (col1, col2, col3) select col1, sum(col2), sum(col3) as total
from
(
    select col1,col2,col3
    from tbl1
    union all
    select col1,col2,col3
    from tbl2
) t
group by col1");

我正试图找到一种更有效的方法来做到这一点,尤其是一种可以适应其他数学运算(如平均值)的方法。

编辑:只是澄清一下,当我运行上面的脚本时,如果没有错误,我通常会在tb3中得到一个大于预期的值。

布局时,不需要聚合、并集或派生表查询。只需将追加查询的选择部分中的两个表连接起来,即可运行单元级操作。

下面的结果与上面的查询相同,并避免了联合子查询和聚合。此外,您仍然可以在单位级别实现其他聚合:

# SUM
$db->exec("INSERT INTO tbl3 (col1, col2, col3) 
           SELECT tbl1.col1, tbl1.col2 + tbl2.col2, tbl1.col3 + tbl2.col3
           FROM tbl1 
           INNER JOIN tbl2 
           ON tbl1.col1 = tbl2.col1;");
# AVERAGE (ΣXi)/N ; MEDIAN 
$db->exec("INSERT INTO tbl4 (col1, col2, col3) 
           SELECT tbl1.col1, (tbl1.col2 + t2.col2)/2, (tbl1.col3 + t2.col3)/2
           FROM tbl1 
           INNER JOIN tbl2 
           ON tbl1.col1 = tbl2.col1;");
# MAX; MIN
$db->exec("INSERT INTO tbl5 (col1, col2, col3, col4, col5) 
           SELECT tbl1.col1,
                  CASE WHEN tbl1.col2 > t2.col2 THEN tbl1.col2
                       ELSE tbl2.col2 END As MaxCol2, 
                  CASE WHEN tbl1.col3 > t2.col3 THEN tbl1.col3
                       ELSE tbl2.col3 END As MaxCol3, 
                  CASE WHEN tbl1.col2 < t2.col2 THEN tbl1.col2
                       ELSE tbl2.col2 END As MinCol2, 
                  CASE WHEN tbl1.col3 < t2.col3 THEN tbl1.col3
                       ELSE tbl2.col3 END As MinCol3, 
           FROM tbl1 
           INNER JOIN tbl2 
           ON tbl1.col1 = tbl2.col1;");
# POPULATION VARIANCE: σ^2 = Σ(Xi-μ)^2/N 
$db->exec("INSERT INTO tbl6 (col1, col2, col3) 
           SELECT tbl1.col1,
                  POWER(((t1.col2 - ((t1.col2 + t2.col2)/2)) +
                         (t2.col2 - ((t1.col2 + t2.col2)/2))),2) / 2,
                  POWER(((t1.col3 - ((t1.col3 + t2.col3)/2)) +
                         (t2.col3 - ((t1.col3 + t2.col3)/2))),2) / 2
           FROM tbl1 
           INNER JOIN tbl2 
           ON tbl1.col1 = tbl2.col1;");
# POPULATION STANDARD DEVIATION: σ = sqrt[Σ(Xi-μ)^2/N]
$db->exec("INSERT INTO tbl7 (col1, col2, col3) 
           SELECT tbl1.col1,
             POWER(
                   POWER(((t1.col2 - ((t1.col2 + t2.col2)/2)) +
                          (t2.col2 - ((t1.col2 + t2.col2)/2))),2) / 2
                   ,(1/2)),
             POWER(
                   POWER(((t1.col3 - ((t1.col3 + t2.col3)/2)) +
                          (t2.col3 - ((t1.col3 + t2.col3)/2))),2) / 2
                   ,(1/2))
           FROM tbl1 
           INNER JOIN tbl2 
           ON tbl1.col1 = tbl2.col1;");

您提到的查询运行良好。查看SQL fiddlehttp://sqlfiddle.com/#!9/96f90/6

选择查询如下,

select col1, sum(col2) as total2, sum(col3) as total3
from
(
    select col1,col2,col3
    from tbl1
    union all
    select col1,col2,col3
    from tbl2
) t
group by col1;
select col1, avg(col2) as avg2, avg(col3) as avg3
from
(
    select col1,col2,col3
    from tbl1
    union all
    select col1,col2,col3
    from tbl2
) t
group by col1;

尝试从这些查询中插入,它将工作

INSERT INTO tbl3 (col1, col2, col3) ...

请检查错误日志以识别错误