例如,我有一个名为"Table1"的表。以及名为"country"的专栏。我想计算字符串中单词的值。下面是我在"国家"列的数据:
country:
"japan singapore japan chinese chinese chinese"
预期输出:在以上数据中,我们可以看到日本出现了两次,新加坡出现了一次,中国出现了三次。因此输出将是3。请帮我
ValueOfWord: 3
首先,将多个值作为分隔字符串存储在一列中是一种糟糕的设计。您应该将规范化数据视为永久解决方案。
使用非规范化数据,您可以使用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
请参阅在Oracle中将单个逗号分隔的字符串拆分为行以了解查询的工作原理。
更新
对于多个分隔字符串行,您需要注意CONNECTBY子句形成的行数。
有关执行相同任务的更多方法,请参阅在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
还有许多其他方法可以实现所需的输出。让我们看看如何:
- 使用XMLTABLE
SQL>SELECT COUNT(DISTINCT(country))COUNT来自的23(SELECT trim(COLUMN_VALUE)country4从t开始,5 xmltable((")6||替换(国家/地区,'',''","')7)8)9/计数----------6.
- 使用MODEL子句
SQL>2型号RAM AS3(4选择国家作为orig_ str,5英寸6||国家7||''AS mod_str,8 1 AS start_pos,9长度(国家)AS end_pos,10(长度(国家)-11长度(更换(国家/地区,''))+1 AS element_count,12 0 AS元素no,13 ROWNUM AS rn14自t)15 SELECT COUNT(DISTINCT(Substr(mod_str,start_pos,end_pos-start_pos))计数16来自(17选择*18 FROM model_param19模型分区依据(rn,orig_str,mod_str)20 DIMENSION BY(element_no)21措施(开始_pos、结束_pos、元素计数)22条规则迭代(2000)23 UNTIL(ITERATION_NUMBER+1=元素计数[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!=030按mod_str、element_no订购31/计数----------6.
您是否将这种字符串存储在单个条目中?
如果没有,请尝试
SELECT COUNT(*)
FROM (SELECT DISTINCT T.country FROM Table1 T)
如果是,我会编写一个外部程序来解析字符串并返回您想要的结果。
喜欢使用java。
创建一个字符串集。
我将使用JDBC来检索记录,并使用split来使用"分隔符拆分令牌中的字符串。对于每个令牌,如果它不在集合中,则将其添加到集合中。
解析完成后,获取集合的长度,这就是您想要的值。
根据空格分隔符中断字符串
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
FIDDLE