Построение SQL-запроса - PullRequest
       3

Построение SQL-запроса

0 голосов
/ 03 сентября 2011

Я использую SQL и PL / SQL.

У меня есть таблица с одним столбцом «имя». Данные в этом столбце являются разделенной точкой с запятой строкой. Я хочу посчитать количество элементов в каждой строке.

Например, если в таблице есть две строки, одна со строкой «кузнец; черный; тигр» и одна со строкой «x; y», я хочу, чтобы результат запроса был 3 для первого ряд и 2 для второго ряда.

Как мне написать SQL-запрос, который будет подсчитывать количество элементов в отдельном списке значений?

Ответы [ 2 ]

6 голосов
/ 03 сентября 2011

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

Строковые функции PLSQL могут вам помочь, но на самом деле вы говорите о написании программного кода для выполнения этой задачи (обычно это не работа для языка запросов к базе данных). Например, вы можете использовать этот трюк для подсчета количества точек с запятой, а затем добавить один:

LENGTH(name) - LENGTH(TRANSLATE(name,'x;','x')) + 1

Но @Johan указывает на то, что это плохой способ структурировать ваши данные. Например, это делает невозможным поиск по имени должным образом. Вы не можете сказать where name == "smith", потому что имя не равно "smith", оно равно "smith;black;tiger". Вам нужно будет выполнить поиск по подстроке, говоря where name like "smith", и это будет неэффективно и неправильно. Что делать, если я попрошу найти имя "smi"? Вы скажете where name like "smi", который неверно найдет этот результат - невозможно сказать, что «кузнец» находится в таблице, а «smi» нет, потому что обе подстроки «кузнец; черный; тигр».

Гораздо лучшим решением, если вы хотите, чтобы запись имела несколько имен, является присвоение этой записи уникального идентификатора; скажем, 123. (Вы можете попросить SQL автоматически генерировать уникальные идентификаторы для строк таблицы.) Затем создайте отдельную таблицу для имен, которая сопоставляется с этой строкой. Допустим, вы дали строке «кузнец; черный; тигр» идентификатор 123, а строке «x; y» идентификатор 124. Теперь у вас будет другая таблица NameMap с двумя столбцами:

name    |  entry
------------------
smith   |   123
black   |   123
tiger   |   123
x       |   124
y       |   124

Теперь вы можете искать имена в этой таблице и сопоставлять их с таблицей записей имен с помощью объединения.

И вы сможете ответить на ваш вопрос: «сколько имен соответствуют каждой строке таблицы записей» с помощью оператора GROUP BY , например:

SELECT name, count(*) as value_count FROM NameMap GROUP BY name
4 голосов
/ 03 сентября 2011

Вы можете взломать это с помощью этого кода

Ужас SQL кода

SELECT name
       ,(LENGTH(COALESCE(vals,'')) 
        - LENGTH(TRANSLATE(COALESCE(vals,''), ';',''))) + 1 AS value_count
FROM table1
ORDER BY name

Примечания
CSV в базе данных - очень плохой анти-паттерн.
VALUES - зарезервированное слово, плохая идея называть столбец после зарезервированного слова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...