#mysql #sql
#mysql #sql
Вопрос:
Я хотел бы объединить все названия элементов заказа; однако, если общее количество уникальных имен элементов превышает определенное число, тогда я хочу усечь каждое имя перед объединением имен. Ниже приведены условия:
Если общее количество уникальных имен элементов в заказе меньше 5, то используйте полное имя элемента и объедините имена; в противном случае, если общее количество уникальных имен элементов больше 5, то сократите каждое имя элемента до 20 символов и объедините усеченные имена. Например, ниже приведена моя таблица:
order_id | item_name | item_name_len
---------|-------------------------------------|--------------
1 | "pampers diapers ultra sensitive" | 31
1 | "cabbage salad pure organic greens" | 33
1 | "milky way" | 9
1 | "sea salt" | 8
1 | "cool waters fruit juice" | 23
| |
2 | "pure clear glass crystals" | 25
2 | "simple sugar edible paper" | 25
Я хочу следующие результаты:
order_id | all_item_names
---------|-----------------------------------------------------------
1 | "pampers diapers ultr ; cabbage salad pure o ; milky way ;
| sea salt ; cool waters fruit ju"
|
2 | "pure clear glass crystals ; simple sugar edible paper"
Для заказа № 1, поскольку в заказе есть 5 уникальных имен элементов, мы сокращаем каждое из имен элементов до 20 символов и объединяем усеченные имена. Для заказа № 2, поскольку в заказе всего 2 уникальных имени элемента, мы берем полную длину имени и объединяем их. (Я включил название элемента strlen в таблицу выше для иллюстрации.)
Я пытаюсь использовать троичное условие, но оно не работает.
IF( COUNT(DISTINCT item_name) < 5, item_name, SUBSTRING(item_name, 1, 20) )
Смотрите запрос ниже. Я получаю Error code: 1111. Invalid use of group function
SELECT
w.order_id,
(SELECT GROUP_CONCAT( IF ( COUNT(DISTINCT o.item_name) < 5 ,
o.item_name, SUBSTRING(o.item_name, 1, 20) ) ) separator ' ; ' )
FROM order_items o WHERE o.order_id = w.order_id)AS all_item_names
FROM order_items w
GROUP BY order_id
Ответ №1:
Вы можете сделать это с помощью одной агрегации и без join
:
select oi.order_id,
(case when count(*) < 5
then group_concat(oi.item_name separator '; ')
else group_concat(left(oi.item_name, 20) separator ';')
end) as all_item_names
from order_items oi
group by oi.order_id
Ответ №2:
Сгруппируйте один раз, чтобы получить количество элементов и присоединиться к таблице для окончательной группы_concat:
select
o.order_id,
group_concat(
case
when counter < 5 then item_name
else left(item_name, 20)
end SEPARATOR ' ; '
) all_item_names
from order_items o inner join (
select
order_id, count(*) counter
from order_items
group by order_id
) g on g.order_id = o.order_id
group by o.order_id
Смотрите демонстрацию
Результаты:
| order_id | all_item_names |
| -------- | ----------------------------------------------------------------------------------------- |
| 1 | pampers diapers ultr ; cabbage salad pure o ; milky way ; sea salt ; cool waters fruit ju |
| 2 | pure clear glass crystals ; simple sugar edible paper |