2015-11-15 2 views
1

Например, у меня есть таблица под названием «Таблица1». и столбец «страна». Я хочу, чтобы подсчитать значение слова в string.below мои данные для столбца «страны»:Как подсчитать количество слов в разделительной строке в Oracle SQL

country: 
"japan singapore japan chinese chinese chinese" 

ожидается выход: в приведенных выше данных мы можем увидеть япония появляются два времени, Сингапурские раз и китайский 3 раза .i хочу подсчитать значение слова, где япония считается единым, сингапур - как один, так и китайский как один. следовательно, выход будет 3. Пожалуйста, помогите мне

ValueOfWord: 3 
+2

Вы не должны хранить несколько значений в одном столбце. Если вы правильно нормализуете свою модель, это очень простой запрос. –

+0

Вы сохранили эту строку в одной записи ??? – Tipton

+0

есть. он находится в одной записи. Я хочу подсчитать значение каждого слова в одной строке ввода. –

ответ

1

Во-первых, это плохая конструкция для хранения нескольких значений в одном столбце в виде строки с разделителями. Вы должны рассмотреть , нормализуя данные как постоянное решение.

С Денормализованные данных, вы можете сделать это в одном 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, чтобы понять, как работает запрос.


UPDATE

Для нескольких строк с разделителями строк, которые необходимо позаботиться о количестве строк, образованных 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 

Существует множество других способов достижения желаемого результата. Давайте посмотрим, как:

  • Использование 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 
  • Использования модели пункта
 
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 
+0

этот запрос работает нормально, но когда применяется в большом количестве данных, он никогда не показывает результат –

+0

вашей демонстрационной версии для строки в sample_data, но я уже храню данные в базе данных в столбец страна: запись 1 = «Япония сингапур японская китайская китайская китайская» запись 2 = «сингапурская индийская малайзия» я хочу, чтобы она включала запись 1 и запись2 @Lalit Kumar B –

+0

@HaziqAzmi Я дал полный ответ в обновлении. Пожалуйста, отметьте это как ответ, помогите другим! –

0

Вы сохранили эту строку в одной записи?

Если нет, попробуйте

SELECT COUNT(*) 
    FROM (SELECT DISTINCT T.country FROM Table1 T) 

Если да, то я хотел бы написать внешнюю программу для разбора строки и возвращает результат, который вы хотите.

Как использовать java.

Создать набор строк.

Я хотел бы использовать JDBC для извлечения записи и использовать split для разделения строк в токенах с использованием разделителя ''. Для каждого токена, если он не находится в наборе, добавьте его в набор.

Когда обработка синтаксического анализа завершается, получите длину набора, которое вы хотите.

+0

yes Строка в одной записи. это как длинная строка .. «japan singapore japan chinese chinese» представлен как строка 1 –

+0

Это непростой вопрос, о котором я думаю. Обычно люди считают определенное слово в строке. например: SELECT (LENGTH (QUESTION_ITEM) - LENGTH (REPLACE (QUESTION_ITEM, «EXPLAIN»)))/LENGTH («EXPLAIN») FROM CLASSIFY –

+0

, пожалуйста, покажите мне внешнюю программу для синтаксического анализа строки и возврата результата –

0

Разбить строку, основанную на пространстве разделителя

SELECT COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL)) 
    FROM T 
CONNECT BY LEVEL <= regexp_count(col, ' ')+1 

Для подсчета различных слов

SELECT col, 
COUNT(DISTINCT regexp_substr(col, '[^ ]+', 1, LEVEL)) 
    FROM T 
CONNECT BY LEVEL <= regexp_count(col, ' ')+1 
GROUP BY col 

FIDDLE

+1

На самом деле это не вопрос OP. Вы возвращаете счет каждого слова, однако OP хочет отличного подсчета. Кроме того, нет необходимости в 'trim', поскольку вам нужен только счет. –