#sql #string #sqlite #csv
#sql #строка #sqlite #csv
Вопрос:
Я пытаюсь найти итоговые значения для каждого числа в диапазоне от 1 до 7. Но данные содержат разные комбинации этих чисел. Например, для 1; 2; 3,7; 1,2,3 и так далее. Я хочу найти общее количество раз, когда появляется каждое число. По сути, мне нужен код для SQLite, который выглядит так:
select <fields>, count(*)
from tablexyz
where <field> contains '2' (and '3','4',... individually)
Когда я ввожу «where like’2%'» и тому подобное, это дает мне только все серии, которые начинаются с 2, но отрицает серию, которая начинается с 1, но содержит 2.
Любая помощь будет оценена!
Комментарии:
1. Пожалуйста, предоставьте пример исходных данных и пример вывода, которые вы ожидаете от этих исходных данных.
2. Что вы имеете в виду
CONTAINS
? Это не стандартный оператор SQL. Например, в T-SQL это оператор произвольного текстового поиска, который требует, чтобы индексы FTS обеспечивали достойную производительность. Вы могли бы использоватьLIKE '%2%'
для поиска полей, содержащих 2, в любом месте. Если вам нужен оператор, который будет разделять данные и определять конкретные поля, вы используете неправильный дизайн. Вы должны создать отдельную таблицу для хранения этих данных. SQLite — это встроенная база данных без множества наворотов. У него даже нет типов, а тем более массивов3. Встроенная БД запускается вашим собственным приложением. Если вы пытаетесь делать то, с чем он не может справиться эффективно, вы в конечном итоге тратите время по сравнению с простым чтением данных и их анализом в своем коде. Вот что происходит в этом случае. SQLite не может индексировать эти значения, поэтому он должен сканировать их все. Было бы лучше, если бы вы просто прочитали все эти строки и использовали, например, регулярное выражение для проверки отдельных значений
Ответ №1:
Я хочу найти общее количество раз, когда появляется каждое число
Ваш пример кода и решение, которое, по вашим словам, вы хотите, не совсем совпадают. Самое близкое, о чем я могу думать, это
with t (txt) as -- a sample record from your table
(select '1; 2; 3,7; 1,2,3'),
t2 (num) as -- a lookup table we can create for range of numbers 1-7
(select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6 union all
select 7)
select t2.num, length(t.txt) - length(replace(t.txt,t2.num,'')) as num_occurence
from t2
left join t on t.txt like '%' || t2.num || '%'
Выводит
----- ---------------
| num | num_occurence |
----- ---------------
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | NULL |
| 5 | NULL |
| 6 | NULL |
| 7 | 1 |
----- ---------------
Ответ №2:
Используя приведенное ниже решение, вы можете создать «таблицу» из чисел от 1 до 7, затем присоединить ее к исходной таблице данных, чтобы подсчитать, встречается ли число в этой строке, а затем суммировать их вместе.
Запрос
WITH
sample_data (nums)
AS
(SELECT '1,2,3,4,5,6'
UNION ALL
SELECT '3,4,5,6'
UNION ALL
SELECT '1,2,7,6'
UNION ALL
SELECT '6' ),
search_nums (search_num)
AS
(VALUES(1)
UNION ALL
SELECT search_num 1 FROM search_nums WHERE search_num<7)
select search_num, sum(count_of_num) from (
SELECT s.nums,
n.search_num,
case
instr(s.nums, n.search_num)
when 0 then 0
else 1
end as count_of_num
FROM sample_data s, search_nums n
) group by search_num;
Результат
search_num sum(count_of_num)
1 2
2 2
3 2
4 2
5 2
6 4
7 1