【问题标题】:SQL Group By with CaseSQL 分组方式(带大小写)
【发布时间】:2017-03-04 03:06:40
【问题描述】:

我需要创建一个简化的报告,在其中列出我的所有销售来源,并仅针对杂项进行细分。

我之所以说 simplified 是因为我试图将一些东西组合在一起,这意味着所有动物销售都应该被标记为 Boarding Charges

这是我目前的查询:

SELECT
    CASE
        WHEN aoi.is_animal = 'N' THEN TO_CHAR(aot.name)
        ELSE 'Boarding Charges'
    END AS display_name,
    aoi.is_animal,
    CASE
        WHEN aot.name = 'Misc.' THEN 'Y'
        ELSE 'N'
    END AS show_details,
    SUM(aoi.quantity * aoi.unit_price) as total
FROM ANIMAL_ORDER ao
LEFT JOIN ANIMAL_ORDER_ITEM aoi ON aoi.order_id = ao.id
LEFT JOIN ANIMAL_ORDER_TYPE aot ON aot.id = aoi.order_type_id
WHERE ao.order_stage != 'CANCELLED'
GROUP BY
    aot.name,
    CASE
        WHEN aoi.is_animal = 'N' THEN 0
        ELSE 1
    END, aoi.is_animal

我现在正在尝试让这件事变得简单,所以我不担心 Misc. 的东西 - 我只是暂时添加了一个列让它说 YN

上面的查询结果如下:

# Resulting table

DISPLAY_NAME            IS_ANIMAL   SHOW_DETAILS       TOTALS
-------------------------------------------------------------
Boarding Charges        Y           N                 8039.53
Truck Delivery Fee      N           N                 1005.21
Misc.                   N           Y                  237.16
Cancellation Fee        N           N                   45.00
Late Fee                N           N                  410.25
Courier Fee             N           N                 1338.40
Boarding Charges        Y           N                  311.27
Boarding Charges        Y           N                 7341.19

如您所见,登机费没有组合在一起,我明白原因是什么 - 我在GROUP BY 子句中有aot.name。它存在的唯一原因是因为当我尝试删除它时,我在TO_CHAR(aot.name) 上收到一个错误,说它不是GROUP BY 表达式。

我只想将所有寄宿费归为一组并汇总它们的总数。

附加信息

我正在尝试使用this question 中提到的方法。

【问题讨论】:

    标签: sql oracle group-by case


    【解决方案1】:

    如果你想按 display_name 分组,你应该在 group by 中重复相同的条件

      SELECT
        CASE
            WHEN aoi.is_animal = 'N' THEN TO_CHAR(aot.name)
            ELSE 'Boarding Charges'
        END AS display_name,
        aoi.is_animal,
        CASE
            WHEN aot.name = 'Misc.' THEN 'Y'
            ELSE 'N'
        END AS show_details,
        SUM(aoi.quantity * aoi.unit_price) as total
    FROM ANIMAL_ORDER ao
    LEFT JOIN ANIMAL_ORDER_ITEM aoi ON aoi.order_id = ao.id
    LEFT JOIN ANIMAL_ORDER_TYPE aot ON aot.id = aoi.order_type_id
    WHERE ao.order_stage != 'CANCELLED'
    GROUP BY
        CASE
            WHEN aoi.is_animal = 'N' THEN TO_CHAR(aot.name)
            ELSE 'Boarding Charges'
        END ,
        aoi.is_animal,
        CASE
            WHEN aot.name = 'Misc.' THEN 'Y'
            ELSE 'N'
        END 
    

    【讨论】:

    • 似乎只要我删除 GROUP BY 子句上的别名就可以工作。
    • 在 oracle 中,查询也应该使用列别名 .. 我使用平面代码仅用于示例 ..因为 aot.name 不等同于 display_name 的情况 ..无论如何我有更新asnwer 也用于别名...让我知道
    • 不,它不起作用。我收到一条错误消息,提示 ORA-00904: "show_details": invalid identifier
    • @scaisEdge - OP 所说的是最后的“AS show_details”不起作用 - 显然它不起作用(我假设任何风格的 SQL)。当然,在整个 CASE 表达式中,其他别名确实有效;但您不能在 GROUP BY 中为 CASE 表达式的结果设置别名。
    • @mathguy 。回答更新删除别名组
    【解决方案2】:

    我认为这会做你想要的:

    SELECT (CASE WHEN aoi.is_animal = 'N' THEN TO_CHAR(aot.name)
                 ELSE 'Boarding Charges'
            END) AS display_name,
           (CASE WHEN aoi.is_animal = 'N' THEN aoi.is_animal END) as is_animal,
           (CASE WHEN aoi.is_animal <> 'N' THEN NULL
                 WHEN aot.name = 'Misc.' THEN 'Y'
                 ELSE 'N'
            END) AS show_details,
           SUM(aoi.quantity * aoi.unit_price) as total
    FROM . . .
    

    这个想法是将其他两个键设置为 NULL 用于“登机费”行。 GROUP BY 应该更改以匹配 SELECT 列。

    【讨论】:

    • 这确实解决了无法对所有 登机费 进行分组的问题,但我不明白在其他 2 列上添加 null 的目的是什么.我想我更喜欢@scaisEdge 的答案。 - 仍然赞成。
    • @PatrickGregorio 。 . .好吧,其他列似乎有可能对“登机费”行有不同的值。然后将结果分散到多行。此版本保证“登机费”仅在一行上,而与其他列的值无关。因此,这是对这个问题的一个更有弹性的答案。
    猜你喜欢
    • 2017-03-07
    • 2022-01-24
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    相关资源
    最近更新 更多