首先,将多个值作为分隔字符串存储在单个列中是一种糟糕的设计。您应该考虑将数据规范化作为永久解决方案。
使用非规范化数据,您可以在单个 SQL 中使用 REGEXP_SUBSTR:
SELECT COUNT(DISTINCT(regexp_substr(country, '[^ ]+', 1, LEVEL))) as "COUNT"
FROM table_name
CONNECT BY LEVEL <= regexp_count(country, ' ')+1
/
演示:
SQL> WITH sample_data AS
2 ( SELECT 'japan singapore japan chinese chinese chinese' str FROM dual
3 )
4 -- end of sample_data mocking real table
5 SELECT COUNT(DISTINCT(regexp_substr(str, '[^ ]+', 1, LEVEL))) as "COUNT"
6 FROM sample_data
7 CONNECT BY LEVEL <= regexp_count(str, ' ')+1
8 /
COUNT
----------
3
请参阅Split single comma delimited string into rows in Oracle 以了解查询的工作原理。
更新
对于多个分隔字符串行,您需要注意由 CONNECT BY 子句形成的行数。
请参阅Split comma delimited strings in a table in Oracle 了解执行相同任务的更多方法。
设置
假设你有一个这样的 3 行表:
SQL> CREATE TABLE t(country VARCHAR2(200));
Table created.
SQL> INSERT INTO t VALUES('japan singapore japan chinese chinese chinese');
1 row created.
SQL> INSERT INTO t VALUES('singapore indian malaysia');
1 row created.
SQL> INSERT INTO t VALUES('french french french');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM t;
COUNTRY
---------------------------------------------------------------------------
japan singapore japan chinese chinese chinese
singapore indian malaysia
french french french
- 使用 REGEXP_SUBSTR 和 REGEXP_COUNT:
我们希望输出为 6,因为有 6 个唯一字符串。
SQL> SELECT COUNT(DISTINCT(regexp_substr(t.country, '[^ ]+', 1, lines.column_value))) count
2 FROM t,
3 TABLE (CAST (MULTISET
4 (SELECT LEVEL FROM dual
5 CONNECT BY LEVEL <= regexp_count(t.country, ' ')+1
6 ) AS sys.odciNumberList ) ) lines
7 ORDER BY lines.column_value
8 /
COUNT
----------
6
还有许多其他方法可以实现所需的输出。让我们看看如何:
SQL> 选择计数(DISTINCT(国家))计数
2 从
3 (SELECT trim(COLUMN_VALUE) 国家
4 从吨,
5 xmltable(('"'
6 ||替换(国家,'','","')
7 || '"'))
8)
9 /
数数
----------
6
SQL> 与
2 模型参数 AS
3 (
4 选择国家作为 orig_str ,
5''
6 ||国家
7 || ' ' 作为 mod_str ,
8 1 作为开始位置,
9 长度(国家) AS end_pos ,
10(长度(国家)-
11 LENGTH(REPLACE(country, ' '))) + 1 AS element_count ,
12 0 AS element_no ,
13 ROWNUM AS rn
14 从吨)
15 SELECT COUNT(DISTINCT(Substr(mod_str, start_pos, end_pos-start_pos))) 计数
16 从 (
17 选择 *
18 来自模型参数
19 模型分区依据 (rn, orig_str, mod_str)
20 DIMENSION BY (element_no)
21 MEASURES (start_pos, end_pos, element_count)
22 条规则迭代 (2000)
23 直到 (ITERATION_NUMBER+1 = element_count[0])
24 ( start_pos[ITERATION_NUMBER+1] =
25 instr(cv(mod_str), '', 1, cv(element_no)) + 1,
26 end_pos[ITERATION_NUMBER+1] =
27 instr(cv(mod_str), ' ', 1, cv(element_no) + 1) )
28)
29 哪里 element_no != 0
30 按 mod_str 、 element_no 排序
31 /
数数
----------
6