SQL Oracle 中字符串列表中的条件计数

conditional count in a list of strings in SQL Oracle

我有几个项目的清单

column1 column2                 desired col3  desired col4 
items1  car                     car           1
items2  car,car                 car           2
items3  car,toy,car             toy           1
items4  car,toy,toy             toy           2
items5  car,toy,cards           toy           1
items6  toy,cards,cards         toy           1
items7  toy,cards,toy           toy           2
items8  car,cards,toy,cards     cards         2
items9  car,cards,cards         cards         2
itrmd10 toy,cards,car           toy           1

规则是,如果有汽车项目,那么在 col3 中应该出现 car 并且 count of cars 在 col4 中 如果列表中没有汽车项目或其他项目,那么它应该始终显示第一个与汽车项目不同的项目 + 该项目的数量。

例如

items3 列表中还有一个项目是汽车,在本例中是第一个玩具,因此将显示计数为 1 的玩具

items6 没有汽车所以玩具显示为第一个

items8 还有其他物品作为汽车礼物,所以这次第一个是卡片,将以 2 的数量显示

items10 car 不必是列表中的第一个项目,但规则是相同的,列表中的另一个项目作为 car 然后计算第一个 = toy,计数为 1

谢谢

the rule is, if there is a car item then in col3 should come car and count of cars in col4 If there is no car item or another item is present in the list then it should always display the first one that differs form car item + the count of this item.

您可以使用:

SELECT t.*,
       REGEXP_COUNT(
         ',' || REPLACE( column2, ',', ',,' ) || ',',
         ',' || column3 || ','
       ) AS column4
FROM   (
  SELECT column1,
         column2,
         CASE
         WHEN ',' || column2 || ',' LIKE '%,car,%'
         THEN 'car'
         ELSE REGEXP_SUBSTR( column2, '[^,]+' )
         END AS column3
  FROM   table_name
) t

其中,对于您的示例数据:

CREATE TABLE table_name ( column1, column2 ) AS
SELECT 'items1',  'car'                 FROM DUAL UNION ALL
SELECT 'items2',  'car,car'             FROM DUAL UNION ALL
SELECT 'items3',  'car,toy,car'         FROM DUAL UNION ALL
SELECT 'items4',  'car,toy,toy'         FROM DUAL UNION ALL
SELECT 'items5',  'car,toy,cards'       FROM DUAL UNION ALL
SELECT 'items6',  'toy,cards,cards'     FROM DUAL UNION ALL
SELECT 'items7',  'toy,cards,toy'       FROM DUAL UNION ALL
SELECT 'items8',  'car,cards,toy,cards' FROM DUAL UNION ALL
SELECT 'items9',  'car,cards,cards'     FROM DUAL UNION ALL
SELECT 'items10', 'toy,cards,car'       FROM DUAL;

输出:

COLUMN1 | COLUMN2             | COLUMN3 | COLUMN4
:------ | :------------------ | :------ | ------:
items1  | car                 | car     |       1
items2  | car,car             | car     |       2
items3  | car,toy,car         | car     |       2
items4  | car,toy,toy         | car     |       1
items5  | car,toy,cards       | car     |       1
items6  | toy,cards,cards     | toy     |       1
items7  | toy,cards,toy       | toy     |       2
items8  | car,cards,toy,cards | car     |       1
items9  | car,cards,cards     | car     |       1
items10 | toy,cards,car       | car     |       1

db<>fiddle here


如果您想要第一个非 car 项,否则 car 如果只有 car 项,则:

SELECT column1,
       column2,
       column3,
       REGEXP_COUNT( double_delimited, ',' || column3 || ',' ) AS column4
FROM   (
  SELECT t.*,
         CASE
         WHEN REPLACE( double_delimited, ',car,' ) IS NOT NULL
         THEN REGEXP_SUBSTR( REPLACE( double_delimited, ',car,' ), '[^,]+' )
         ELSE 'car'
         END AS column3
  FROM   (
    SELECT column1,
           column2,
           ',' || REPLACE( column2, ',', ',,' ) || ',' AS double_delimited
    FROM   table_name
  ) t
) t

输出:

COLUMN1 | COLUMN2              | COLUMN3 | COLUMN4
:------ | :------------------- | :------ | ------:
items1  | car                  | car     |       1
items2  | car,car              | car     |       2
items3  | car,toy,car          | toy     |       1
items4  | car,toy,toy          | toy     |       2
items5  | car,toy,cards        | toy     |       1
items6  | toy,cards,cards      | toy     |       1
items7  | toy,cards,toy        | toy     |       2
items8  | car,cards,toy,cards  | cards   |       2
items9  | car,cards,cards      | cards   |       2
items10 | toy,cards,car        | toy     |       1

db<>fiddle here