如何计算 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_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
  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

FIDDLE