如何在某些条件下获取MAX值(SQL)

时间:2017-09-09 14:40:47

标签: oracle postgresql

请帮我构建一个查询。

需要获得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

2 个答案:

答案 0 :(得分:1)

使用FILTER clausecoalesce()的聚合函数为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