MySQL, выберите значение на основе условного количества сгруппированных элементов - PullRequest
1 голос
/ 22 апреля 2020

У меня есть таблица buildings, которая выглядит следующим образом:

+----+------------------+-------+
| id | accommodation_id | type  |
+----+------------------+-------+
| 1  | 2                | Villa |
+----+------------------+-------+
| 2  | 2                | Suite |
+----+------------------+-------+
| 3  | 5                | Villa |
+----+------------------+-------+

И для каждого жилья определить, к какому типу относится этот лог c: если в жилье больше чем 1 здание использует значение жесткого кода Accommodation в противном случае * столбец 1008 *.

Ожидаемый результат должен выглядеть следующим образом:

+---------------+
| type          |
+---------------+
| Accommodation | <- the result for accommodation_id=2
+---------------+
| Villa         | <- the result for accommodation_id=5
+---------------+

Я пробовал этот запрос

SELECT IF(Count(id) = 1, type, 'accommodation') AS type 
FROM   `buildings` 
WHERE accommodation_id = 2
GROUP  BY accommodation_id 

Сбой из-за использования type, которого нет в группе (ошибка only_full_group_by ).

Если я добавлю type к возвращаемой группе не требуется результат

+---------------+
| type          |
+---------------+
| Accommodation | <- the result for accommodation_id=2 & id=1
+---------------+
| Accommodation | <- the result for accommodation_id=2 & id=2
+---------------+
| Villa         | <- the result for accommodation_id=5 & id=3
+---------------+

Я использую MySQL8 с sql_mode = only_full_group_by

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020

Просто небольшое улучшение в ответе Ника на +1, чтобы сделать запрос саргмативным:

SELECT
    id,
    CASE WHEN MIN(type) <> MAX(type) THEN 'Accommodation' ELSE MIN(type) END AS type
FROM buildings
GROUP BY id;

Приведенный выше запрос должен иметь возможность использовать следующий индекс:

(id, type)

Причина этого в том, что он использует только MIN и MAX, поэтому для каждой группы id можно быстро найти значения min и max с помощью индекса.

2 голосов
/ 22 апреля 2020

Вам просто нужно посчитать различные значения type для каждого accommodation_id, и если больше 1, выведите Accommodation, в противном случае type:

SELECT accommodation_id,
       CASE WHEN COUNT(DISTINCT type) > 1 THEN 'Accommodation'
            ELSE MIN(type)
       END AS type
FROM buildings
GROUP BY accommodation_id

Выход:

accommodation_id    type
2                   Accommodation
5                   Villa

Демонстрация на dbfiddle

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