#mysql
Вопрос:
SELECT SUM(LENGTH(room_id) - LENGTH(REPLACE(room_id, ',', '')) 1) as total
FROM booking
Я применил этот запрос MySQL, он работает нормально, но он учитывает повторяющиеся значения. Как я могу удалить повторяющиеся значения при подсчете из полей, разделенных запятыми, в MySQL.
Моя Колонка, Как
ID | room_id |
---|---|
1 | 2, 4, 5 |
2 | 4, 3 |
Я хочу показать результат подсчета всего = 4
Теперь он насчитывает 5
Комментарии:
1. Но в вашем примере есть 5 различных значений: 1, 2, 3, 4, 5. В примере говорится «сумма», а в вопросе — «количество». Вам нужно их посчитать или получить сумму всех различных значений?
2. Лучший подход-просто отказаться от текущего дизайна таблицы и прекратить хранить значения CSV таким образом. Вместо этого каждое
id - room_id
сопряжение должно отображаться в отдельной строке.3. Что вы пробовали до сих пор? Где ты застрял? Почему столбец
room_id
содержит что-либо еще, кроме числа?4. Уважаемый @ekochergin, мне нужно значение счетчика, значение моего столбца разделено запятыми, поэтому я применил СУММУ для подсчета значений, разделенных запятыми. Если у вас есть какой-либо лучший процесс для подсчета значений, разделенных запятыми, в MySQL, пожалуйста, поделитесь мной.
5.
SELECT *, (CHAR_LENGTH(room_id) - CHAR_LENGTH(REPLACE(room_id, ',', '')) 1) as total FROM booking
Попробуй это
Ответ №1:
Как отметил Тим Бигельштейн, лучший способ-изменить дизайн базы данных и никогда не использовать строки, разделенные запятыми, которые могут потребоваться для разбиения.
Но я понимаю, что это не всегда возможно, поэтому вот решение, которое у меня есть.
К сожалению, это применимо только к mysql версии 8 или новее. В 8-й версии они добавили рекурсивные CTE, которые используются здесь
with recursive booking_splitted(id, room_id, room_parsed, step, steps_needed) as (
select id,
substring(room_id, instr(room_id, ',') 1),
substring_index(room_id, ',', 1),
1,
char_length(room_id) - char_length(replace(room_id, ',', ''))
from booking
union all
select id,
substring(room_id, instr(room_id, ',') 1),
ifnull(substring_index(room_id, ',', 1), room_id),
step 1,
steps_needed
from booking_splitted
where step <= steps_needed
)
select count(distinct room_parsed) rooms
from booking_splitted
order by id;
CTE (часть «с рекурсивным …») разбивает строку, разделенную запятыми, на строки. Итак, линия с
room_id |
---|
2,4,5 |
будет разделен на 3 записи:
room_id |
---|
2 |
4 |
5 |
И прошлая часть («выберите количество(различных …») подсчитывает отдельные комнаты
UPD. см., например, dbfiddle