Oracle根据条件计算分区的数量。

huangapple go评论60阅读模式
英文:

Oracle Counts of partitions based on conditions

问题

我有以下数据Oracle根据条件计算分区的数量。

我需要统计跳过特定状态的订单。这是一个状态历史表,状态按降序排列。

我尝试过下面的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 have following data Oracle根据条件计算分区的数量。

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

我建议稍微改变方法:

  1. 对于每个订单,按行的创建日期排序,汇总所有状态
  2. 在列表中查找缺失的状态
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:

  1. For each order, aggregate all the statuses, sorted by the creation date of the row
  2. 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

fiddle

英文:

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

fiddle

huangapple
  • 本文由 发表于 2023年7月6日 18:12:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76627751.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定