Усекать и объединять результаты MySQL на основе количества результатов - PullRequest
1 голос
/ 28 марта 2019

Я хотел бы объединить все названия элементов заказа;однако, если общее количество уникальных имен элементов превышает определенное число, то я хочу обрезать каждое имя перед объединением имен.Ниже приведены условия:

Если общее количество уникальных имен элементов в заказе меньше 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

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Вы можете сделать это с одной агрегацией и без 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
1 голос
/ 28 марта 2019

Сгруппируйте один раз, чтобы получить количество элементов и присоединитесь к таблице для окончательного group_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

См. demo Результаты:

| 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                                     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...