如何在Oracle SQL中计算分隔字符串中的字数



例如,我有一个名为"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_SUBSTRREGEXP_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

最新更新