请帮我构建一个查询。
需要获得MAX(LVALUE)& SUM(BVALUE)。 这是非常简单的要求,但我应该考虑以下3个条件。
一个。如果BVALUE为零,则该行不应涉及构建MAX(LVALUE)。
湾每个NAME至少应打印一行。
℃。如果所有BVALUE都为零,则MAX(LVALUE)应为零。
CREATE TABLE P_TEST
(
NAME VARCHAR2(10),
LVALUE NUMBER,
BVALUE NUMBER
)
/
INSERT INTO P_TEST VALUES('FIRST',929292,0);
INSERT INTO P_TEST VALUES('FIRST',12,32);
INSERT INTO P_TEST VALUES('FIRST',-34,0);
INSERT INTO P_TEST VALUES('FIRST',21,0);
INSERT INTO P_TEST VALUES('SECOND',79292,0);
COMMIT;
以下查询只是起作用,但MAX(LVALUE)929292是从BVALUE的零值驱动的,所以它超出了规则。
SELECT NAME,MAX(LVALUE),SUM(BVALUE)
FROM P_TEST
GROUP BY NAME
/
@错误的结果
NAME MAX(LVALUE) SUM(BVALUE)
---------- ----------- -----------
SECOND 79292 0
FIRST 929292 32
@ Desired result
NAME MAX(LVALUE) SUM(BVALUE)
---------- ----------- -----------
SECOND 0 0
FIRST 12 32
答案 0 :(得分:1)
使用FILTER clause和coalesce()的聚合函数为NULL结果获取零:
select
name,
coalesce(max(lvalue) filter (where bvalue <> 0), 0) as max_lvalue,
coalesce(sum(bvalue) filter (where bvalue <> 0), 0) as sum_bvalue
from p_test
group by name;
name | max_lvalue | sum_bvalue
--------+------------+------------
SECOND | 0 | 0
FIRST | 12 | 32
(2 rows)
如果RDBMS中未知最后一个,则可以使用CASE表达式而不是FILTER:
select
name,
coalesce(max(case when bvalue <> 0 then lvalue end), 0) as max_lvalue,
coalesce(sum(case when bvalue <> 0 then bvalue end), 0) as sum_bvalue
from p_test
group by name;
答案 1 :(得分:1)
由于当BVALUE = 0时你没有考虑计算最大值,你可以在BVALUE = 0时排除所有行。在所有情况下,它都不会对SUM(BVALUE)有贡献,因为它是0
select max(lvalue), sum(bvalue)
from p_test
where bvalue != 0
group by name
由于您需要显示每个名称的记录,因此上述内容不会显示“SECOND”的记录。要解决此问题,您可以加入self,或使用子查询
select nvl(max(b.lvalue), 0), nvl(sum(b.bvalue), 0)
from p_test a, p_test b
where a.name = b.name (+)
and b.bvalue != 0
或(以下允许您更多地控制每个摘要包含的内容)
select distinct name,
nvl((select max(b.lvalue) from p_test b where b.name = a.name and b.bvalue != 0), 0),
nvl((select sum(c.lvalue) from p_test c where c.name = a.name), 0)
from p_test a