我正在使用Oracle 10g,我想计算表tmp_ord
中包含的行的不同状态。它包含以下数据。
以下有一套标记状态的规则
我在下面写了一个查询来计算数据,但得到一个对应于ORDER_ID = 6的NULL值。
SELECT distinct ORDER_ID,CASE WHEN R1=0 THEN 'UNKNOWN'
WHEN R1=1 AND ORDER_STATUS='ABC' THEN 'ABC'
WHEN R1=1 AND ORDER_STATUS<>'ABC' THEN 'NON-ABC'
WHEN R1>1 THEN 'MD'
END STATUS
,CASE WHEN R2=0 THEN 'UNKNOWN'
WHEN R2=1 AND ORDER_STATUS_1='ABC' THEN 'ABC'
WHEN R2=1 AND ORDER_STATUS_1<>'ABC' THEN 'NON-ABC'
WHEN R2>1 THEN 'MD'
END STATUS_1
FROM
(
SELECT ORDER_ID,ORDER_STATUS,ORDER_STATUS_1,
COUNT(DISTINCT order_status) OVER (PARTITION BY ORDER_ID) R1
,COUNT(DISTINCT order_status_1) OVER (PARTITION BY ORDER_ID) R2
FROM TMP_ORD
ORDER BY ORDER_ID
);
我的输出低于输出值。请告诉我如何抑制与ORDER_ID = 6相关联的行,这将使STATUS = NULL ...它应该&#39; ABC&#39;因为它包含至少一个ABC&#39;并且没有使用&#39; NON-ABC&#39;
答案 0 :(得分:0)
我正在努力,但不知道背景,特别是“ABC”和“非ABC”真正代表它有点难以正确。
你说6应该返回“ABC” - 在你的具体情况下,将“NULL”视为非“非ABC”是否可以接受? 因此“NULL”=“ABC”?如果这对您没问题,请尝试使用NVL(状态,“ABC”)并且事情应该有效。
但是,对于数据的含义,这是一个非常大的假设。订单是否可能使其所有行的STATUS = NULL? 如果是,您的功能应该返回什么? ABC
或者,您可以尝试更严格地定义“NON-ABC”,尝试替换:
WHEN ... ORDER_STATUS<>'ABC' THEN 'NON-ABC'
带
WHEN ... (ORDER_STATUS<>'ABC'AND ORDER_STATUS IS NOT NULL) THEN 'NON-ABC'
看看你得到了什么
答案 1 :(得分:0)
第5点有点不清楚(对我而言),但这个查询应该做的工作:
with o0 as (
select order_id,
sum(decode (order_status, 'ABC', 1, 0)) s0_abc,
sum(decode (order_status, 'ABC', 0, null, 0, 1)) s0_xyz,
sum(decode (order_status, NULL, 1, 0)) s0_null,
sum(case when order_status is null and order_position is null
then 1 else 0 end) s0_null_op
from tmp_ord group by order_id),
o1 as (
select order_id,
sum(decode (order_status_1, 'ABC', 1, 0)) s1_abc,
sum(decode (order_status_1, 'ABC', 0, null, 0, 1)) s1_xyz,
sum(decode (order_status_1, NULL, 1, 0)) s1_null,
sum(case when order_status_1 is null and order_position is null
then 1 else 0 end) s1_null_op
from tmp_ord group by order_id)
select order_id,
case
when s0_abc > 0 and s0_xyz = 0 then 'ABC'
when s0_abc = 0 and s0_xyz > 0 then 'NON-ABC'
when s0_abc > 0 and s0_xyz > 0 then 'AMB'
when s0_null_op = s0_null then null
else 'UNKNOWN'
end status,
case
when s1_abc > 0 and s1_xyz = 0 then 'ABC'
when s1_abc = 0 and s1_xyz > 0 then 'NON-ABC'
when s1_abc > 0 and s1_xyz > 0 then 'AMB'
when s1_null_op = s1_null then null
else 'UNKNOWN'
end status_1
from o0 join o1 using (order_id)
order by order_id
结果:
ORDER_ID STATUS STATUS_1
---------- ------- --------
1 AMB ABC
2 AMB AMB
3 AMB AMB
4 NON-ABC NON-ABC
5 ABC ABC
6 ABC ABC
7 UNKNOWN UNKNOWN
7 rows selected
答案 2 :(得分:0)
抱歉误导了你们
如果你清楚地阅读了我的所有规则,它已经提到要对'ORDER_STATUS'和'ORDER_ID'计算'ORDER_POSITION'。
在我的查询(我在一个问题中发布)我对'ORDER_ID'计数了ORDER_STATUS。
请在下面找到解决方案。
SELECT ORDER_ID
,CASE
WHEN ABC_STATUS_CNT = 0 AND NON_ABC_STATUS_CNT=0 AND TOTAL_COUNT=1 THEN 'UNKNOWN'
WHEN ABC_STATUS_CNT >= 1 AND NON_ABC_STATUS_CNT=0 THEN 'ABC'
WHEN ABC_STATUS_CNT = 0 AND NON_ABC_STATUS_CNT>=1 THEN 'NON_ABC'
WHEN ABC_STATUS_CNT >= 1 AND NON_ABC_STATUS_CNT>=1 THEN 'AMB'
END STATUS
,CASE
WHEN ABC_STATUS_CNT_1 = 0 AND NON_ABC_STATUS_CNT_1=0 AND TOTAL_COUNT=1 THEN 'UNKNOWN'
WHEN ABC_STATUS_CNT_1 >= 1 AND NON_ABC_STATUS_CNT_1=0 THEN 'ABC'
WHEN ABC_STATUS_CNT_1 = 0 AND NON_ABC_STATUS_CNT_1>=1 THEN 'NON_ABC'
WHEN ABC_STATUS_CNT_1 >= 1 AND NON_ABC_STATUS_CNT_1>=1 THEN 'AMB'
END STATUS_1
FROM
(
SELECT ORDER_ID,COUNT(CASE WHEN ORDER_STATUS = 'ABC' THEN ORDER_POSITION ELSE NULL END) ABC_STATUS_CNT
,COUNT(CASE WHEN ORDER_STATUS <> 'ABC' THEN ORDER_POSITION ELSE NULL END) NON_ABC_STATUS_CNT
,COUNT(CASE WHEN ORDER_STATUS_1 = 'ABC' THEN ORDER_POSITION ELSE NULL END) ABC_STATUS_CNT_1
,COUNT(CASE WHEN ORDER_STATUS_1 <> 'ABC' THEN ORDER_POSITION ELSE NULL END) NON_ABC_STATUS_CNT_1
,COUNT(ORDER_POSITION) AS TOTAL_COUNT
FROM TMP_ORD_BNG2A
GROUP BY ORDER_ID
);