SQL Oracle 中的项目行的条件计数

conditional count of items row wise in SQL Oracle

我发布了类似的问题

这次数据集是行式的,但逻辑保持不变。这些项目将被逐一添加到列表 1、2、3..。我使用了项目添加到列表时的日期。

这是数据

CREATE TABLE lists ( column1, column2 , column3) AS
SELECT 'list1', '01-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list1', '02-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list2', '01-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list2', '02-01-2020' , 'toy'         FROM DUAL UNION ALL
SELECT 'list2', '03-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list3', '01-01-2020' , 'toy'         FROM DUAL UNION ALL
SELECT 'list3', '02-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list3', '03-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list4', '01-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list4', '02-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list4', '03-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list5', '01-01-2020' , 'toy'         FROM DUAL UNION ALL
SELECT 'list5', '02-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list5', '03-01-2020' , 'toy'         FROM DUAL UNION ALL
SELECT 'list5', '04-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list6', '01-01-2020' , 'car'         FROM DUAL UNION ALL
SELECT 'list6', '02-01-2020' , 'cards'       FROM DUAL UNION ALL
SELECT 'list6', '03-01-2020' , 'toy'         FROM DUAL UNION ALL
SELECT 'list6', '04-01-2020' , 'cards'       FROM DUAL;

table 看起来像这样

COLUMN1 COLUMN2 COLUMN3
list1   01-01-2020  car
list1   02-01-2020  car
list2   01-01-2020  car
list2   02-01-2020  toy
list2   03-01-2020  car
list3   01-01-2020  toy
list3   02-01-2020  cards
list3   03-01-2020  cards
list4   01-01-2020  car
list4   02-01-2020  cards
list4   03-01-2020  cards
list5   01-01-2020  toy
list5   02-01-2020  cards
list5   03-01-2020  toy
list5   04-01-2020  cards
list6   01-01-2020  car
list6   02-01-2020  cards
list6   03-01-2020  toy
list6   04-01-2020  cards

如果列表中只有 CAR,则计算汽车的数量。 如果有非汽车项目,那么你计算第一个添加到列表中的非汽车项目

例如

list1  car   2
list2  toy   1
list3  toy   1
list4  cards 2
list5  toy   2
list6  cards 2

您可以使用 window 函数获取有关列表的信息,然后将其用于过滤:

select l.column1, item_to_count,
       count(*)
from (select l.*,
             min(l.column2) keep (dense_rank first order by (case when l.column3 <> 'car' then 1 else 2 end), l.column2) over (partition by l.column1) as date_to_count,
             min(l.column3) keep (dense_rank first order by (case when l.column3 <> 'car' then 1 else 2 end), l.column2) over (partition by l.column1) as item_to_count
      from lists l
     ) l
where column3 = item_to_count and column2 >= date_to_count
group by l.column1, item_to_count
order by l.column1;

Here 是一个 db<>fiddle.