oracle 一列缺少特定数据的SQL查询组

ioekq8ef  于 2023-01-20  发布在  Oracle
关注(0)|答案(3)|浏览(234)

我有一个Oracle SQL数据库,其中包含订单簿信息,例如
| 订单编号|时间戳|操作|订单状态|...|
| - ------|- ------|- ------|- ------|- ------|
| 1个|00时00分01秒|插入|新增|...|
| 1个|00时00分05秒|更新|部分填充|...|
| 第二章|00时00分07秒|更新|部分填充|...|
| 1个|00时00分08秒|取消|已填充|...|
| 三个|00时00分08秒|插入|新增|...|
现在,这个数据并不总是完全填充的,例如,有时候会有order_id缺少信息。
我试图识别的一个此类问题是缺少操作“INSERT”的订单(因此,具有相同order_ID的所有订单),例如,存在具有操作“UPDATE”或“CANCEL”但没有“INSERT”的order_id。在上面的示例表中,order_id 2(它具有“UPDATE”,但没有“INSERT”)就是这种情况
我能够通过下载整个数据集并使用Python分析数据来执行此分析,但如果可能,我希望能够使用直接SQL查询(更快)完成此操作。

goucqfw6

goucqfw61#

您可以使用条件聚合来检查某些状态是否与其他状态沿着存在。

select order_id
from sample
where operation in ('INSERT', 'UPDATE', 'CANCEL', 'OTHER_STATUS_TO_CHECK_TOGETHER_WITH_INSERT')
group by order_id
having count(case operation when 'INSERT' then 1 end) = 0

对于示例数据,它返回
| 订单编号|
| - ------|
| 第二章|
fiddle

vmdwslir

vmdwslir2#

看看以下内容是否有帮助:

Select Order_Id
from t
where Operation in ('UPDATE','CANCEL')
and not exists (
  select * from t t2
  where t2.Order_Id = t.Order_Id and t2.Operation = 'INSERT'
);
js4nwp54

js4nwp543#

在Oracle 12中,可以使用MATCH_RECOGNIZE执行逐行模式匹配,以确定UPDATECANCEL操作之前是否有INSERT操作:

SELECT order_id
FROM   order_book
MATCH_RECOGNIZE(
  PARTITION BY order_id
  ORDER     BY timestamp
  MEASURES
    COUNT(insert_op.operation) AS has_insert
  PATTERN ( insert_op? (update_op|cancel_op)+ )
  DEFINE
    insert_op AS operation = 'INSERT',
    update_op AS operation = 'UPDATE',
    cancel_op AS operation = 'CANCEL'
)
WHERE has_insert = 0;

其中,对于示例数据:

CREATE TABLE order_book (ORDER_ID, TIMESTAMP, OPERATION, ORDER_STATUS ) AS
SELECT 1, '00:00:01', 'INSERT', 'New'              FROM DUAL UNION ALL
SELECT 1, '00:00:05', 'UPDATE', 'Partially Filled' FROM DUAL UNION ALL
SELECT 2, '00:00:07', 'UPDATE', 'Partially Filled' FROM DUAL UNION ALL
SELECT 1, '00:00:08', 'CANCEL', 'Filled'           FROM DUAL UNION ALL
SELECT 3, '00:00:08', 'INSERT', 'NEW'              FROM DUAL;

输出:
| 订单编号|
| - ------|
| 第二章|
或者,如果您需要UPDATECANCEL操作位于组中第一个的组,则可以使用:

SELECT order_id
FROM   order_book
MATCH_RECOGNIZE(
  PARTITION BY order_id
  ORDER     BY timestamp
  PATTERN ( ^ (update_op|cancel_op) )
  DEFINE
    update_op AS operation = 'UPDATE',
    cancel_op AS operation = 'CANCEL'
);

其输出相同。
fiddle

相关问题