Oracle SQL - 从分隔字段返回计数

时间:2015-06-22 20:35:25

标签: oracle

我对SQL相当缺乏经验,所以希望这个问题不是太傻。这是场景:

我有一个VARCHAR2列,用于存储由product分隔的一系列值。根据帐户的不同,他们可以拥有一个或多个产品。我正在尝试编写一个返回值的查询,但也为每种类型或产品提供计数。

例如:

ProductColumn: P1, P2, P3, P4
Table: TableAccount
Sample Value 1: P1:P2:P3
Sample Value 2: P1
Sample Value 3: P2:P3

我当前的查询只返回所有不同值类型的计数,包括分隔值:

select 
ProductColumn,
count(8) cnt
from TableAccount
group by ProductColumn

任何建议都将不胜感激!

2 个答案:

答案 0 :(得分:2)

如果产品代码以冒号分隔,则可以使用子字符串来拉取代码值,与分隔符冒号分开。这允许你返回到调用者,每个都在单独的字段中,所以求和,分组等等。但是,如果任何值超过两个,那将会变得混乱 字节。这就是数据规范化规则明确规定不将多个数据放入单个表列的原因。如果是我,我会编写一个PL SQL,将它们拆分出来并将其全部写入NORMALIZED表,然后从该表中查询。让我的老板知道这个设计缺陷是固定不变的。

答案 1 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE TableAccount ( value ) AS
          SELECT 'P1:P2:P3' FROM DUAL
UNION ALL SELECT 'P1' FROM DUAL
UNION ALL SELECT 'P2:P3' FROM DUAL
UNION ALL SELECT 'P1:P3' FROM DUAL
UNION ALL SELECT 'P1:P4' FROM DUAL
UNION ALL SELECT 'P5' FROM DUAL;

查询1

SELECT item,
       COUNT(1) AS frequency
FROM   (
        SELECT REGEXP_SUBSTR( value, '[^:]+', 1, COLUMN_VALUE ) AS item
        FROM   TableAccount t,
               TABLE(
                  CAST(
                    MULTISET(
                      SELECT LEVEL
                      FROM   DUAL
                      CONNECT BY  LEVEL <= REGEXP_COUNT( t.value, '[^:]+')
                    ) AS sys.OdciNumberList
                  )
                )
        )
GROUP BY item
ORDER BY item

<强> Results

| ITEM | FREQUENCY |
|------|-----------|
|   P1 |         4 |
|   P2 |         2 |
|   P3 |         3 |
|   P4 |         1 |
|   P5 |         1 |