使用PHP / PDO对来自不同SQL表的多个列求和

时间:2016-01-03 00:43:41

标签: php sql database 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 here描述的那些操作),但是当我这样做时,我看到插入到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中获得一个大于预期的值。

2 个答案:

答案 0 :(得分:1)

如您所述,您不需要聚合,联合或派生表查询。只需在追加查询的选择部分中加入两个表,然后运行单元级操作即可。

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

# 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;");

答案 1 :(得分:0)

您提到的查询工作正常。请参阅SQL小提琴http://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) ...

请检查错误日志以确定错误