postgresql - 从三个不同的表中获取一个值会给出错误的结果 - postgresql

标签 postgresql join

目标是获得一项任务的剩余时间值。我知道我无法对两个连接表求和,但这个简单的查询让我感到困惑:

CREATE TABLE tsk
    (tskid int4, tskhr numeric(8,2));    
INSERT INTO tsk
    (tskid, tskhr)
VALUES
    (1,80.5),
    (2,120.7);

CREATE TABLE hr
    (hrid int4, hrtsk int4, hrqty numeric(8,2));    
INSERT INTO hr
    (hrid,hrtsk, hrqty)
VALUES
    (1,1,40.5),
    (2,2,40.7),
    (3,1,1);

CREATE TABLE inte
    (inteid int4, intetsk int4, inteqty numeric(8,2));    
INSERT INTO inte
    (inteid,intetsk, inteqty)
VALUES
    (1,1,10.5);

所需的输出是

+-------+------+
| tskid |  hr  | 
+-------+------+
|    1  | 28,5 |  (80,5-(40,5+1+10,5)
|    2  |   80 |  (120,7-40,7)
+-------+------+

我的第一次尝试很简单

SELECT    tskid, coalesce(tskhr-hrqty+inteqty,0) 
FROM      tsk
LEFT JOIN hr on hrtsk=tskid
LEFT JOIN inte on intetsk=tskid

输出

+-------+----------+
| tskid | coalesce |
+-------+----------+
|     1 |     50.5 |
|     1 |       90 |
|     2 |        0 |
+-------+----------+

第二次尝试

SELECT    tskid, coalesce(tskhr-(hrqty+inteqty),0)
FROM      tsk
LEFT JOIN (SELECT hrtsk, sum(hrqty)hrqty FROM hr GROUP BY 1) h ON tskid =h.hrtsk
LEFT JOIN (SELECT intetsk, sum(inteqty)inteqty FROM inte GROUP BY 1) i ON tskid =i.intetsk;

给出了这个结果:

+-------+----------+
| tskid | coalesce |
+-------+----------+
|     1 |     28.5 |
|     2 |        0 |
+-------+----------+

第三次尝试在外部求和也不正确:

WITH list AS(
SELECT    tskid, tskhr, hrqty, inteqty 
FROM      tsk
LEFT JOIN hr on hrtsk=tskid
LEFT JOIN inte on intetsk=tskid)
SELECT    tskid, coalesce(sum(tskhr-hrqty+inteqty),0) 
FROM      list
GROUP BY  1

结果:

+-------+----------+
| tskid | coalesce |
+-------+----------+
|     1 |    140.5 |
|     2 |        0 |
+-------+----------+

我一定错过了一些明显的东西,但我不知道是什么。

fiddle :http://sqlfiddle.com/#!15/f11f75/28

子查询也没有运气。

TIA,

最佳答案

我将为 hrinte 表使用单独的子查询:

SELECT
    t1.tskid,
    t1.tskhr - COALESCE(t2.hrqty, 0) - COALESCE(t3.inteqty, 0) AS hr
FROM tsk t1
LEFT JOIN
(
    SELECT hrtsk, SUM(hrqty) AS hrqty
    FROM hr
    GROUP BY hrtsk
) t2
    ON t1.tskid = t2.hrtsk
LEFT JOIN
(
    SELECT intetsk, SUM(inteqty) AS inteqty
    FROM inte
    GROUP BY intetsk
) t3
    ON t1.tskid = t3.intetsk;

SQLFiddle

这种方法有效的原因是子查询避免了连接所固有的记录相乘问题。在本例中,我们只想对 tsk 表中的值进行一次计数,但我们需要按其他两个表中的任务 ID 进行聚合。

关于postgresql - 从三个不同的表中获取一个值会给出错误的结果 - postgresql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48238523/

相关文章:

mysql - 使用变量为 mysql 中的分组制作标签

mysql - 内连接 : add up amounts with same id

php - 从具有多个连接的 SQL 查询中提取和计算唯一列

mysql - {mysql} 使用交叉连接选择

postgresql - 有 (type_id, element_id) 对,例如 (1,1)、(1,2)、.. (5,3)。如果我需要获取没有 element_id 1 的类型 id,如何从结果中排除 type_id?

postgresql - 如何从 PGAdmin4 连接到 docker Postgres 服务器

使用 Postgres 处理 Django 时区

mysql - 在 JOIN 中使用具有 'AS' 的字段的指定名称

windows - 用于将 psql 查询输出存储到变量中的批处理文件

postgresql - USING 部分在 EXECUTE 中被忽略...在 PL/pgSQL 中使用