带有相反表达式的Oracle case语句

enyaitl3  于 2023-08-04  发布在  Oracle
关注(0)|答案(2)|浏览(134)

我有下面的表进行分析(见图)。
我需要订单的排名1是履行,并已通过该订单(项目或单位)审批状态(显然有些订单可以跳过审批)。
另外,需要在单个select语句中创建此。
你能帮我建立一个Oracle SQL吗?我尝试使用Case语句的各种组合,但无法使用相反的条件提取标志。谢谢你,谢谢
| 订单号|订单状态|秩| rank |
| --|--|--| ------------ |
| 一二三四|履行|一个| 1 |
| 一二三四|装船的|二个| 2 |
| 一二三四|已批准-单位级别|三个| 3 |
| 一二三四|已排队-设备级别|四个| 4 |
| 一二三四|已批准-项目级|五个| 5 |
| 一二三四|已排队-项目级别|六个| 6 |
| 一二三四|已提交|七个| 7 |
已尝试SQL:

SELECT ORDER_REGION, 
CASE WHEN RANK=1 AND ORDER_STATUS = 'Fulfilled' then
 case when rank>1 and order_status not like '%Queued - Project level%' then 'N' else 'Y' end end  is_it_approved_at_project
FROM orders
GROUP BY order_Region;

字符串
预期输出:
| 项目是否批准|项目是否批准| Is It approved at Project |
| --|--| ------------ |
| Y轴|Y轴| Y |
| 不适用|Y轴| Y |
| Y轴|不适用| N |

y3bcpkx1

y3bcpkx11#

您可以使用条件聚合和CASE表达式:

SELECT   order_number,
         CASE
         WHEN COUNT(CASE WHEN order_status = 'Approved - Unit Level' THEN 1 END) = 0
         THEN 'N' ELSE 'Y' END AS is_approved_unit,
         CASE
         WHEN COUNT(CASE WHEN order_status = 'Approved - Project Level' THEN 1 END) = 0
         THEN 'N' ELSE 'Y' END AS is_approved_project
FROM     orders
GROUP BY order_number
HAVING   COUNT(CASE WHEN rank = 1 AND order_status = 'Fulfilled' THEN 1 END) > 0

字符串
其中,对于样本数据:

CREATE TABLE orders ( order_region, order_number, order_status, rank ) AS
SELECT 'New York',  1234,   'Fulfilled',    1 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'shippped', 2 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'Approved - Unit Level',    3 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'Queued - Unit Level',  4 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'Approved - Project Level', 5 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'Queued - Project Level',   6 FROM DUAL UNION ALL
SELECT 'New York',  1234,   'Submitted',    7 FROM DUAL;


输出:
| IS_APPROVED_UNIT|已批准项目| IS_APPROVED_PROJECT |
| --|--| ------------ |
| Y轴|Y轴| Y |
fiddle

cwxwcias

cwxwcias2#

听起来使用exists可以帮助解决这个问题:

select order_region
from orders as ordersFulfilled
where ordersFulfilled.rank = 1
and ordersFulfilled.order_status = 'Fulfilled'
and exists (
    select 1
    from orders as ordersQueued
    where ordersFulfilled.order_number = ordersQueued.order_number
    and ordersFulfilled.rank > 1
    and ordersFulfilled.order_status not like 'Queued - Project level%'
);

字符串
请注意,此查询将只返回满足条件的行。如果您需要的订单不满足条件,您可以使用not exists而不是exists
你也应该意识到在查询中比较字符串是相当“昂贵”的,尤其是在使用通配符的时候。这就是为什么我删除了数组开头的通配符,因为这更像是“starts with”而不是“contains”。但是,这仅在索引列order_status时有效。更好的方法是使用数字而不是字符串作为状态列(当然还要在此列上添加索引)。

相关问题