DB - Oracle
省略所有约束。
create table customer (cid number(10), cname varchar(50));
create table exercise (eid number(10), ecode varchar(2));
-- mapping table
create table customer_exercise (cid number(10), eid number(10), cnt number(10))
数据
Customer table
100 e1
200 e2
300 e3
400 e4
Exercise table
1 c1
2 c2
3 c3
4 c4
Customer_Exercise
cid eid count
100 1 20
200 2 50
100 2 30
300 4 10
SQL:
SELECT c.cid
,e.eid
,COALESCE(SUM(ce.cnt), 0) AS total_cnt
FROM customer c
CROSS JOIN exercise e
LEFT JOIN customer_exercise ce
ON ce.cid = c.cid
AND ce.eid = e.eid
WHERE c.cid IN (100, 200, 300)
AND e.eid IN (1, 2)
GROUP BY c.cid, e.eid
结果:
cid eid total_cnt
100 1 20
100 2 30
200 1 0
200 2 50
300 1 0
300 2 0
有没有办法过滤掉in子句中没有任何运动ID条目的客户?
例如客户300没有运动ID 1或2的任何行。该客户不应该在结果中。客户200没有练习1的行,但有练习2的数据,所以他应该在练习1中显示为0。
如何获得如下的结果集?
预期结果:
cid eid total_cnt
100 1 20
100 2 30
200 1 0
200 2 50
答案 0 :(得分:0)
您可以使用inner join
代替外部联接,但删除eid
上的联接条件,将其移动到CASE WHEN
子句中的select
表达式中。这样你就不得不重复in (1, 2)
条件:
SELECT c.cid
, e.eid
, COALESCE(SUM(CASE e.eid WHEN ce.eid THEN ce.cnt ELSE 0 END), 0) AS total_cnt
FROM (
SELECT DISTINCT eid
FROM exercise
WHERE eid IN (1, 2)) e
CROSS JOIN customer c
INNER JOIN customer_exercise ce
ON ce.cid = c.cid
AND ce.eid IN (1, 2)
WHERE c.cid IN (100, 200, 300)
GROUP BY c.cid
, e.eid
ORDER BY 1, 2
在rextester.com上看到它。
输出:
cid | eid | total_cnt
----+------+----------
100 | 1 | 20
100 | 2 | 30
200 | 1 | 0
200 | 2 | 50
替代:
SELECT c.cid
, e.eid
, COALESCE(SUM(CASE e.eid WHEN ce.eid THEN ce.cnt ELSE 0 END), 0) AS total_cnt
FROM exercise e
CROSS JOIN customer c
INNER JOIN customer_exercise ce
ON ce.cid = c.cid
AND ce.eid IN (1, 2)
WHERE c.cid IN (100, 200, 300)
AND e.eid IN (1, 2)
GROUP BY c.cid
, e.eid
ORDER BY 1, 2
答案 1 :(得分:0)
正确的方法:
with t as (
SELECT c.cid
,e.eid
,COALESCE(SUM(ce.cnt), 0) AS total_cnt
,count(max(ce.cnt))over(partition by c.cid) ce_cnt
FROM customer c
CROSS JOIN exercise e
LEFT JOIN customer_exercise ce
ON ce.cid = c.cid
AND ce.eid = e.eid
WHERE c.cid IN (100, 200, 300)
AND e.eid IN (1, 2)
GROUP BY c.cid, e.eid
)
select t.cid,t.eid,t.total_cnt from t where t.ce_cnt >0
对不起,我有一点点错误,(没有max()代码给ORA-00979:不是GROUP BY表达式)