Как я могу получить первое непустое значение группы в MySQL?
У меня есть следующая таблица:
id | item_id | name | description | locale
----------------------------------------------------------
1 | 1 | (null) | (null) | en-GB
2 | 1 | Foo | (null) | en-US
3 | 1 | Bar | Lorem ipsum dolor. | en-AU
Я пытаюсь вернуть такой результат ?:
item_id | name | description
-------------------------------------------------------------------
1 | Foo | Lorem ipsum dolor.
Мне сказали, что coalsece
был подходящим вариантом, но, похоже, он не работает с группами. Хотя выстрел не выстрелил. Это должно дать хорошее представление о том, что я пытаюсь сделать.
select item_id, coalesce(name) as name, coalesce(description) as description from test
where item_id = 1
group by item_id
order by field(locale, 'en-GB', 'en-US', 'en-AU');
Другие попытки были сделаны с использованием first (), first_value (), min (), max () ... Я лучше выполняю это в прямом запросе MySQL, чем смешиваю его с логикой PHP.
4 ответа
Вы можете попробовать что-то вроде этого:
select
item_id,
substring_index(
coalesce(group_concat(name separator ','), ''),
',',
1
) as first_name,
substring_index(
coalesce(group_concat(description separator ','), ''),
',',
1
) as first_description
from test
group by item_id
См. Примечание внизу относительно order by
.
Результат
item_id first_name first_description
1 Foo Lorem ipsum dolor.
2
Объяснение
Используя функцию group_concat
, мы объединяем все имена и описания в CSV для каждого item_id.
Результат может быть нулевым. Поэтому мы используем coalesce
для предоставления пустой строки в качестве значения, если group_concat
привел к нулю.
Затем мы разделяем запятыми и получаем первую часть информации.
Предостережение: ваше имя или описание могут содержать запятую. Вам нужно будет как-то учесть это, чего в запросе сейчас нет.
Живой пример или данные, которые можно попробовать, если кто-то захочет
create table test (
id int,
item_id int,
name varchar(100),
description varchar(200),
locale varchar(10)
);
insert into test values
(1, 1, NULL, NULL, 'en-GB'),
(2, 1, 'Foo', NULL, 'en-US'),
(3, 1, 'Bar', 'Lorem ipsum dolor.', 'en-AU'),
(4, 2, NULL, NULL, 'en-GB');
Примечание
Пользователь Straberry мудро заметил, что в моем запросе отсутствует предложение order by
, которое OP может счесть ценным.
Заказ можно сделать в предложении group_concat
и после group by
. Ниже приведен пример того, как можно сделать заказ на обоих уровнях. Заказ на уровне заказов group_concat
гарантирует, что first_name соответствует указанному вами заказу. Упорядочивание после group by
помогает упорядочить итоговый результат.
select
item_id,
substring_index(
coalesce(group_concat(name order by field(locale, 'en-GB', 'en-US', 'en-AU') separator ','), ''),
',',
1
) as first_name,
substring_index(
coalesce(group_concat(description order by field(locale, 'en-GB', 'en-US', 'en-AU') separator ','), ''),
',',
1
) as first_description
from test
group by item_id
order by field(locale, 'en-GB', 'en-US', 'en-AU');
Аналогично решению @zedfoxus, но с использованием решения Standard SQL, работающего в каждой СУБД:
select
item_id,
coalesce(max(case when locale = 'en-GB' then name end)
,max(case when locale = 'en-US' then name end)
,max(case when locale = 'en-AU' then name end)) as first_name,
coalesce(max(case when locale = 'en-GB' then description end)
,max(case when locale = 'en-US' then description end)
,max(case when locale = 'en-AU' then description end)) as first_description
from test
group by item_id
select TT2.Id, TT2.Item_Id, TT2.MyName, TT2.MyDesc, TT2.Locale from #TempTest TT2
where convert(Varchar(12),TT2.Id) + '#' + convert(Varchar(12),TT2.Item_Id)
in
(
select X = convert(Varchar(12),Min(TT1.Id)) + '#' + convert(Varchar(12),Min(TT1.Item_Id))
from #TempTest TT1
where TT1.MyName is not null
group by TT1.Locale
)
Я не уверен, но я думаю, что следующий запрос получит только поле, в котором нет нулевых значений
SELECT item_id,name,description,locale FROM test WHERE (name != '' AND description != '')
Надеюсь, что это работает
Похожие вопросы
Связанные вопросы
Новые вопросы
php
PHP — это открытый, мультипарадигмальный, динамически типизированный и интерпретируемый язык сценариев, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.