Where 子句不适用于没有 Clickhouse 分组的聚合

问题描述 投票:0回答:1

我正在尝试使用三种不同的条件来计算总和和计数而不进行分组,并添加书面标志以将它们彼此区分开。然后我试图获取唯一带有特定标志的记录。但来自 cte 的结果查询并没有按照我的预期进行过滤。它的工作原理与我将 flag_purchase 过滤器添加到 cte 中的 where 子句相同。

DDL 和表插入:

    CREATE TABLE t15
    (
        `winner_price_wo_vat` Nullable(Decimal(38, 2)),
        `prc_lot` Nullable(String),
        `business_code` String,
        `business_unit` Nullable(String),
        `is_finished` Nullable(String),
    )
    ENGINE = MergeTree
    ORDER BY business_code
    SETTINGS index_granularity = 8192;
    INSERT INTO t15 (winner_price_wo_vat,prc_lot,business_code,business_unit,is_finished) VALUES
         (100.00,'1','1','1','1'),
         (100.00,'2','1','2','1'),
         (200.00,'3','2','1','1'),
         (250.00,'4','2','1','1'),
         (300.00,'5','3','1','1');

我的询问:

    with cte as (
    select 
        'competitive' as flag_purchase
        , SUM(winner_price_wo_vat) as sum_wo
        , COUNT(prc_lot) as cnt
    from t15
    where 
        1=1
        and business_code = '1'
        and is_finished = '1'
    union all 
    select 
        'open' as flag_purchase
        , SUM(winner_price_wo_vat) as sum_wo
        , COUNT(prc_lot) as cnt
    from t15
    where 
        1=1
        and business_code = '2' and business_unit = '2'
        and is_finished = '1'
    union all 
    select 
        'closed' as flag_purchase
        , SUM(winner_price_wo_vat) as sum_wo
        , COUNT(prc_lot) as cn
    from t15
    where 
        1=1
        and business_code = '3' and business_unit = '1'
        and is_finished = '1'
    )
    select 
        flag_purchase
        , sum_wo
        , cnt
    from cte 
    where 
        1=1
        and flag_purchase = 'closed'

输出:

    flag_purchase|sum_wo|cnt|
    -------------+------+---+
    competitive  |      |  0|
    open         |      |  0|
    closed       |300.00|  1|

如果我在 cte 中添加 group by,那么它会按预期工作 - 输出仅包含一条记录,其中

flag_purchase = 'closed'

为什么Clickhouse会这样工作,我只能通过group by解决这个问题吗?

group-by where-clause clickhouse
1个回答
0
投票

作为替代方案,请考虑使用此查询:

SELECT
    multiIf((business_code = '1') AND (business_unit IS NULL), 'competitive',
            (business_code = '2') AND (business_unit = '2'), 'open',
            (business_code = '3') AND (business_unit = '1'), 'closed', '?') AS flag_purchase,
    business_code,
    business_unit,
    SUM(winner_price_wo_vat) AS sum_wo,
    COUNT(prc_lot) AS cnt
FROM t15
PREWHERE (business_code IN ('1', '2', '3')) AND (is_finished IN ('1'))
GROUP BY
    GROUPING SETS (
        (business_code),
        (business_code, business_unit))
HAVING flag_purchase = 'closed'

/*
   ┌─flag_purchase─┬─business_code─┬─business_unit─┬─sum_wo─┬─cnt─┐
1. │ closed        │ 3             │ 1             │    300 │   1 │
   └───────────────┴───────────────┴───────────────┴────────┴─────┘
*/

一些建议:

© www.soinside.com 2019 - 2024. All rights reserved.