如何计算 Oracle 中分隔字符串中的单词数 SQL
How to count number of words in delimited string in Oracle SQL
例如,我有一个名为 'Table1' 的 table。和名为 'country' 的列。
我想计算 string.below 中单词的值是我的列 'country':
的数据
country:
"japan singapore japan chinese chinese chinese"
预期输出:在上面的数据中我们可以看到 japan 出现了两次,singapore 出现了一次,chinese 3 times.i 想要计算 japan 算作一个,singapore 算作一个,chinese 算作一个的单词的值.因此输出将是 3。请帮助我
ValueOfWord: 3
您是否将那种字符串存储在单个条目中?
如果不行,试试
SELECT COUNT(*)
FROM (SELECT DISTINCT T.country FROM Table1 T)
如果是,我会编写一个外部程序来解析字符串和return你想要的结果。
喜欢使用 java。
创建字符串集。
我会使用 JDBC 来检索记录,并使用 split 来使用 ' ' 分隔符拆分标记中的字符串。对于每个令牌,如果它不在集合中,则将其添加到集合中。
parse结束后,得到集合的长度,就是你想要的值。
首先,将多个值作为分隔字符串存储在单个列中是一种糟糕的设计。您应该考虑 规范化 数据作为永久解决方案。
使用非规范化数据,您可以使用 REGEXP_SUBSTR:
在单个 SQL 中完成
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。
设置
假设您的 table 有 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
还有许多其他方法可以实现所需的输出。让我们看看如何:
- 使用XMLTABLE
SQL> SELECT COUNT(DISTINCT(country)) COUNT
2 FROM
3 (SELECT trim(COLUMN_VALUE) country
4 FROM t,
5 xmltable(('"'
6 || REPLACE(country, ' ', '","')
7 || '"'))
8 )
9 /
COUNT
----------
6
- 使用 MODEL 子句
SQL> WITH
2 model_param AS
3 (
4 SELECT country AS orig_str ,
5 ' '
6 || country
7 || ' ' AS mod_str ,
8 1 AS start_pos ,
9 Length(country) AS end_pos ,
10 (LENGTH(country) -
11 LENGTH(REPLACE(country, ' '))) + 1 AS element_count ,
12 0 AS element_no ,
13 ROWNUM AS rn
14 FROM t )
15 SELECT COUNT(DISTINCT(Substr(mod_str, start_pos, end_pos-start_pos))) count
16 FROM (
17 SELECT *
18 FROM model_param
19 MODEL PARTITION BY (rn, orig_str, mod_str)
20 DIMENSION BY (element_no)
21 MEASURES (start_pos, end_pos, element_count)
22 RULES ITERATE (2000)
23 UNTIL (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 WHERE element_no != 0
30 ORDER BY mod_str , element_no
31 /
COUNT
----------
6
根据 space 分隔符拆分字符串
SELECT COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL))
FROM T
CONNECT BY LEVEL <= regexp_count(col, ' ')+1
用于计算 DISTINCT 单词
SELECT col,
COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL))
FROM T
CONNECT BY LEVEL <= regexp_count(col, ' ')+1
GROUP BY col
例如,我有一个名为 'Table1' 的 table。和名为 'country' 的列。 我想计算 string.below 中单词的值是我的列 'country':
的数据country:
"japan singapore japan chinese chinese chinese"
预期输出:在上面的数据中我们可以看到 japan 出现了两次,singapore 出现了一次,chinese 3 times.i 想要计算 japan 算作一个,singapore 算作一个,chinese 算作一个的单词的值.因此输出将是 3。请帮助我
ValueOfWord: 3
您是否将那种字符串存储在单个条目中?
如果不行,试试
SELECT COUNT(*)
FROM (SELECT DISTINCT T.country FROM Table1 T)
如果是,我会编写一个外部程序来解析字符串和return你想要的结果。
喜欢使用 java。
创建字符串集。
我会使用 JDBC 来检索记录,并使用 split 来使用 ' ' 分隔符拆分标记中的字符串。对于每个令牌,如果它不在集合中,则将其添加到集合中。
parse结束后,得到集合的长度,就是你想要的值。
首先,将多个值作为分隔字符串存储在单个列中是一种糟糕的设计。您应该考虑 规范化 数据作为永久解决方案。
使用非规范化数据,您可以使用 REGEXP_SUBSTR:
在单个 SQL 中完成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。
设置
假设您的 table 有 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
还有许多其他方法可以实现所需的输出。让我们看看如何:
- 使用XMLTABLE
SQL> SELECT COUNT(DISTINCT(country)) COUNT 2 FROM 3 (SELECT trim(COLUMN_VALUE) country 4 FROM t, 5 xmltable(('"' 6 || REPLACE(country, ' ', '","') 7 || '"')) 8 ) 9 / COUNT ---------- 6
- 使用 MODEL 子句
SQL> WITH 2 model_param AS 3 ( 4 SELECT country AS orig_str , 5 ' ' 6 || country 7 || ' ' AS mod_str , 8 1 AS start_pos , 9 Length(country) AS end_pos , 10 (LENGTH(country) - 11 LENGTH(REPLACE(country, ' '))) + 1 AS element_count , 12 0 AS element_no , 13 ROWNUM AS rn 14 FROM t ) 15 SELECT COUNT(DISTINCT(Substr(mod_str, start_pos, end_pos-start_pos))) count 16 FROM ( 17 SELECT * 18 FROM model_param 19 MODEL PARTITION BY (rn, orig_str, mod_str) 20 DIMENSION BY (element_no) 21 MEASURES (start_pos, end_pos, element_count) 22 RULES ITERATE (2000) 23 UNTIL (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 WHERE element_no != 0 30 ORDER BY mod_str , element_no 31 / COUNT ---------- 6
根据 space 分隔符拆分字符串
SELECT COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL))
FROM T
CONNECT BY LEVEL <= regexp_count(col, ' ')+1
用于计算 DISTINCT 单词
SELECT col,
COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL))
FROM T
CONNECT BY LEVEL <= regexp_count(col, ' ')+1
GROUP BY col