2016-09-04 4 views
-1

Как я могу получить первое непустое значение группы в MySQL?Получить первое значение группы в 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_VALUE(), мин(), не более() ... Я достаточно сделать это в прямом запросе MySQL, чем смешивать его с PHP логики.

+0

Возможный дубликат [Выберите столбец, если пустой выбрать из другого источника] (HTTP://stackoverflow.com/questions/1747750/select-column-if-blank-select-from-another) – zanderwar

+0

@ Zanderwar: Вы знаете разницу в строке и столбце? Вы просто связали решение с альтернативными столбцами. – tim

+0

Извините @Tim, строка не возвращает набор столбцов, один из которых вы хотите проверить, пуст, и если это так возвращается к другой таблице и столбцу? Ваше соединение: http://www.w3schools.com/sql/sql_join.asp - всегда можно проверить на стороне php – zanderwar

ответ

3

Вы можете попробовать что-то вроде этого:

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 привел к null.

Затем мы разделяем запятую и получаем первую информацию.

Предостережение в том, что ваше имя или описание могут содержать запятую. Вам нужно будет так или иначе объяснить это, о чем запрос в настоящее время нет.

Живой пример или данные, чтобы попробовать, если кто-то хочет

http://rextester.com/RFI82565

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'); 

Примечание

клубничный Пользователь отметил благоразумно, что мой запрос был пропущен order by положение, который ОП может найти ценным.

Заказ может быть сделан в предложении 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'); 
+0

Хороший глаз, @Strawberry. Спасибо. В нижней части ответа я добавил несколько заметок. – zedfoxus

+1

Я принял ваш ответ как лучший ответ на мой вопрос. Спасибо :) – tim

-1

Я не уверен, но я думаю, что следующий запрос будет получить только поле, где есть не нуль не дорожит

SELECT item_id,name,description,locale FROM test WHERE (name != '' AND description != '') 

Надеется, что это работает

+0

Вы также можете выполнить итерацию с помощью цикла, чтобы получить все остальные строки с не нулевыми значениями – ocnet

+0

Этот вопрос не позволяет оставить только один из предоставленных решений – ocnet

0
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 
) 
+0

Вы придумали бы результат, который я продемонстрировал именно так? – tim

+0

Это возвращает результаты, которые вы обсуждаете. Вы пытаетесь сделать что-то с группировкой, но с предоставленным вами данным, я не могу следовать тому, что вы пытаетесь сгруппировать. Может потребоваться добавить некоторые данные для набора данных идентификатора второго элемента в вашем примере, чтобы можно было продемонстрировать группу с образцами данных. –

+0

Это вернет результат с именем Bar. Мой пример показывает Foo. Мне нужно «первое значение» «группы» в этом определенном технологическом заказе. Просто каковы первые значения столбцов сгруппированного результата. – tim

2

Подобно @ zedfoxus решение которого, но с использованием раствора Стандартный 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 
Смежные вопросы