【问题标题】:How to get MAX value with some conditions (SQL)如何在某些条件下获得 MAX 值(SQL)
【发布时间】:2017-09-09 23:05:35
【问题描述】:

请帮我建立一个查询。

需要得到 MAX(LVALUE) & SUM(BVALUE)。 这是一个非常简单的要求,但我应该考虑以下三个条件。

一个。如果 BVALUE 为零,则该行不应参与构建 MAX(LVALUE)。

b.每个 NAME 至少应打印一行。

c。如果所有 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

@想要的结果

NAME       MAX(LVALUE) SUM(BVALUE)
---------- ----------- -----------
SECOND       0       0
FIRST       12      32

【问题讨论】:

    标签: oracle postgresql


    【解决方案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;
    

    【讨论】:

    • 美丽。这就是我想尝试的.. CASE WHEN。非常感谢!
    【解决方案2】:

    由于您不考虑在 BVALUE=0 时计算最大值,因此您可以在 BVALUE = 0 时排除所有行。在所有情况下,它都不会影响 SUM(BVALUE),因为它是 0

    select max(lvalue), sum(bvalue)
    from p_test
    where bvalue != 0
    group by name
    

    由于您需要为每个名称显示一条记录,因此上面不会显示“SECOND”的记录。为了解决这个问题,你可以加入到自己,或者使用子查询

    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
    

    【讨论】:

    • 你完全明白我想要什么。它运作良好。非常感谢。
    猜你喜欢
    • 2020-06-13
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 2017-09-09
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    相关资源
    最近更新 更多