我试图一起使用CASE和GROUP BY来有条件地过滤结果,只要它们符合CASE标准,如果它们不相同,则返回结果,好像没有指定GROUP BY标准。
这是我所拥有的简单模型:
es.id | es.acct_num | p.id | p.name
1001 | 4306-0 | 1569 | The High School
1002 | 4306-0 | 1569 | The High School
665 | 5906-7 | 981 | Rec Center
783 | 5906-7 | 1221 | The Gym
以及我希望看到的内容:
es.id | es.acct_num | p.id | p.name
1001 | 4306-0 | 1569 | The High School
1002 | 4306-0 | 1569 | The High School
0 | 5906-7 | 0 | MULTI-SITE
由于es.acct_num 5906-7 有超过1个不同的关联p.id,我希望它按es.acct_num分组为1行项,然后有es.id,p .id由' 0'表示,并且p.name由字符串' MULTI-SITE'表示。
但是,由于es.acct_num 4306-0 只有1个不同的关联p.id,我希望这些都作为单独的行项返回,就像没有应用分组条件一样。
解决方案逃脱了我。我怎么能做到这一点?
答案 0 :(得分:3)
您可以使用条件聚合执行此操作:
SELECT (case when count(*) > 1 then 0 else max(es.id) end) as esid,
es.acct_num,
(case when count(*) > 1 then 0 else max(p.id) end) as pid,
(case when count(*) > 1 then 'MULTI-SITE' else p.name end) as name,
COUNT(*) AS cnt
FROM es join
p
on . . .
GROUP BY es.acct_num;
不要被max()
表达式所迷惑。 case
的那一部分只有一行,因此这些行只返回该行中的值。
编辑:
我认为您需要使用相关子查询,连接/聚合或使用变量计算值来执行此操作。使用窗口函数,几乎任何其他数据库都会更容易。这是一个想法,在没有看到完整查询的情况下,有点难以详细表达:
SELECT (case when esp.cnt > 1 then 0 else max(es.id) end) as esid,
es.acct_num,
(case when esp.cnt > 1 then 0 else max(p.id) end) as pid,
(case when esp.cnt > 1 then 'MULTI-SITE' else p.name end) as name
FROM es join
p
on . . . join
(select es.acct_num, count(distinct p.id) as cnt
from . . .
group by es.acct_num
) esp
on esp.acct_num = es.acct_num
GROUP BY es.acct_num, (case when cnt = 0 then es.id end);
答案 1 :(得分:3)
很抱歉这个延误了。
我确定的解决方案似乎是两个想法的混合体。 2个查询之间的UNION,其中嵌套了一个子查询,该查询首先充当过滤器以排除“MULTI-SITE”结果,在第二种情况下仅包括这些结果:
SELECT col1,col2,etc... from table WHERE acct_num NOT IN (
SELECT MULTISITE.es_acct_num FROM (
SELECT acct_num as es_acct_num,
COUNT(DISTINCT p.id) as `cnt`
FROM blah, blah, blah
GROUP BY es.acct_num HAVING `cnt` > 1) as MULTISITE)
UNION
SELECT col1,col2,etc... from table WHERE acct_num IN (
SELECT MULTISITE.es_acct_num FROM (
SELECT acct_num as es_acct_num,
COUNT(DISTINCT p.id) as `cnt`
FROM blah, blah, blah
GROUP BY es.acct_num HAVING `cnt` > 1) as MULTISITE)
GROUP BY es.acct_num -- notice this final group by clause sitting outside the "filter" rolls the multi-site results up into their respective groupings by acct_num
这两个回复都包含了很好的想法,但我提出的解决方案是两个想法的组合,所以我觉得最好将我正在使用的解决方案标记为正确答案。但是,由于我发现它们都非常有用,我上面的答案仍然是+1。
答案 2 :(得分:2)
您可以将其分为两个单独的查询,并使用UNION
加入所有内容:
SELECT es.id, es.acct_num, p.id, p.name, COUNT(p.id) AS count
FROM ... es JOIN ... p
GROUP BY es.acct_num
HAVING count > 1
UNION
SELECT 0 AS es.id, es.acct_num, 0 AS p.id, 'MULTI-SITE' AS p.name, COUNT(p.id) AS count
FROM ... es JOIN ... p
GROUP BY es.acct_num
HAVING count = 0