目标是在任务上获得剩余时间的一个值。我知道我不能将两个连接表相加,但这个简单的查询让我感到困惑:
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 |
+-------+----------+
我必须错过一些明显的东西,但我无法弄清楚是什么。
小提琴:http://sqlfiddle.com/#!15/f11f75/28
子查询也没有运气。
TIA,
答案 0 :(得分:2)
我会为hr
和inte
表使用单独的子查询:
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;
这种方法的工作原理是子查询避免了连接所固有的记录倍增问题。在这种情况下,我们只想计算tsk
表中的值一次,但我们需要在其他两个表中按任务ID进行聚合。
答案 1 :(得分:0)
试试这个:
SELECT tskid, tskhr-((select sum(hrqty) ty from hr where hrid = tsk.tskid group by hrid)+ CASE WHEN (SELECT COUNT(*) FROM inte WHERE inteid=tsk.tskid) = 0 THEN 0 ELSE (SELECT intetsk+inteqty FROM inte WHERE inteid=tsk.tskid group by inteid) END) AS hr FROM tsk group by tskid;