英文:
Oracle Counts of partitions based on conditions
问题
我需要统计跳过特定状态的订单。这是一个状态历史表,状态按降序排列。
我尝试过下面的Oracle SQL逻辑,但它给我返回了所有单独记录的计数,而不是单独的订单。
我需要将这部分作为选择语句的一部分,而不是作为WHERE子句、公共表达式或子查询的一部分,因为我将在OBIEE Answers中复制这个逻辑。
select
count(CASE WHEN STATUS NOT LIKE '%Approved%' THEN 1 END) NOT_APPROVED,
count(CASE WHEN STATUS NOT LIKE '%Dispatched%' THEN 1 END) NOT_DISPATCHED
From Orders
英文:
I need to count the orders which skipped a particular status. This is a status history table where statuses are arranged in descending order.
I have tried below Oracle SQL Logic but it's giving me count of all individual records and not the individual orders
I need this to be part of select statement only and not in whare clause or CTE or subquery as I'd be replicating this in OBIEE Answers.
select
count(CASE WHEN STATUS NOT LIKE '%Approved%' THEN 1 END) NOT_APPROVED,
count(CASE WHEN STATUS NOT LIKE '%Dispatched%' THEN 1 END) NOT_DISPATCHED
From Orders
答案1
得分: 1
我建议稍微改变方法:
- 对于每个订单,按行的创建日期排序,汇总所有状态
- 在列表中查找缺失的状态
SELECT count(
CASE
WHEN INSTR(status_array, 'Approved') > 0 THEN 0
ELSE 1) as '未批准',
... 每个状态都要重复
FROM (
SELECT order_id, LISTAGG(status, ',') WITHIN GROUP (ORDER BY created_at) AS status_array
FROM Orders
GROUP BY order_id
) t;
请注意,这只是一般的想法,我没有您的数据,所以无法为您执行查询。
英文:
I would suggest changing the approach a bit:
- For each order, aggregate all the statuses, sorted by the creation date of the row
- Look for the missing status in the list
SELECT count(
CASE
WHEN INSTR(status_array, 'Approved') > 0 THEN 0
ELSE 1) as 'Not approved',
... Repeat for each status
FROM (
SELECT order_id, LISTAGG(status, ',') WITHIN GROUP (ORDER BY created_at) AS status_array
FROM Orders
GROUP BY order_id
) t;
Please note that that's just the general idea, I don't have your data, so I can't execute the query for you.
答案2
得分: 1
你需要包括一个 GROUP BY
子句,并可以使用条件聚合:
SELECT order#,
MAX(CASE status WHEN 'Fulfilled' THEN 1 ELSE 0 END) AS is_fulfilled,
MAX(CASE status WHEN 'Dispatched' THEN 1 ELSE 0 END) AS is_dispatched,
MAX(CASE status WHEN 'Approved' THEN 1 ELSE 0 END) AS is_approved,
MAX(CASE status WHEN 'Cancelled' THEN 1 ELSE 0 END) AS is_cancelled,
MAX(CASE status WHEN 'Initiated' THEN 1 ELSE 0 END) AS is_initiated
FROM orders
GROUP BY order#
对于示例数据:
CREATE TABLE orders (order#, status) AS
SELECT 'A123', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'A123', 'Dispatched' FROM DUAL UNION ALL
SELECT 'A123', 'Approved' FROM DUAL UNION ALL
SELECT 'A123', 'Initiated' FROM DUAL UNION ALL
SELECT 'A456', 'Cancelled' FROM DUAL UNION ALL
SELECT 'A456', 'Initiated' FROM DUAL UNION ALL
SELECT 'B123', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'B123', 'Dispatched' FROM DUAL UNION ALL
SELECT 'B123', 'Initiated' FROM DUAL UNION ALL
SELECT 'B456', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'B456', 'Approved' FROM DUAL UNION ALL
SELECT 'B456', 'Initiated' FROM DUAL;
输出:
ORDER# | IS_FULFILLED | IS_DISPATCHED | IS_APPROVED | IS_CANCELLED | IS_INITIATED |
---|---|---|---|---|---|
A123 | 1 | 1 | 1 | 0 | 1 |
A456 | 0 | 0 | 0 | 1 | 1 |
B123 | 1 | 1 | 0 | 0 | 1 |
B456 | 1 | 0 | 1 | 0 | 1 |
英文:
You need to include a GROUP BY
clause and can use conditional aggregation:
SELECT order#,
MAX(CASE status WHEN 'Fulfilled' THEN 1 ELSE 0 END) AS is_fulfilled,
MAX(CASE status WHEN 'Dispatched' THEN 1 ELSE 0 END) AS is_dispatched,
MAX(CASE status WHEN 'Approved' THEN 1 ELSE 0 END) AS is_approved,
MAX(CASE status WHEN 'Cancelled' THEN 1 ELSE 0 END) AS is_cancelled,
MAX(CASE status WHEN 'Initiated' THEN 1 ELSE 0 END) AS is_initiated
FROM orders
GROUP BY order#
Which, for the sample data:
CREATE TABLE orders (order#, status) AS
SELECT 'A123', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'A123', 'Dispatched' FROM DUAL UNION ALL
SELECT 'A123', 'Approved' FROM DUAL UNION ALL
SELECT 'A123', 'Initiated' FROM DUAL UNION ALL
SELECT 'A456', 'Cancelled' FROM DUAL UNION ALL
SELECT 'A456', 'Initiated' FROM DUAL UNION ALL
SELECT 'B123', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'B123', 'Dispatched' FROM DUAL UNION ALL
SELECT 'B123', 'Initiated' FROM DUAL UNION ALL
SELECT 'B456', 'Fulfilled' FROM DUAL UNION ALL
SELECT 'B456', 'Approved' FROM DUAL UNION ALL
SELECT 'B456', 'Initiated' FROM DUAL;
Outputs:
ORDER# | IS_FULFILLED | IS_DISPATCHED | IS_APPROVED | IS_CANCELLED | IS_INITIATED |
---|---|---|---|---|---|
A123 | 1 | 1 | 1 | 0 | 1 |
A456 | 0 | 0 | 0 | 1 | 1 |
B123 | 1 | 1 | 0 | 0 | 1 |
B456 | 1 | 0 | 1 | 0 | 1 |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论