У меня есть следующие три строки данных:
id price type
1 19.99 PERM
1 30.13 TEMP
2 14.44 SOME
Я хотел бы сгруппировать по id и получить цену, а цена TEMP всегда существует, используйте ее по умолчанию. Вот пример того, что должно быть на выходе:
id price
1 30.13
2 14.44
Пока я застрял на group by:
SELECT
GROUP_CONCAT(tp.price_value order by tp.price_type='temp' desc limit 1)
FROM prices GROUP BY id
Как бы я отдал приоритет цене (order by, limit 1) выше?
Теперь у меня две идеи: сделать два запроса (объединение кажется излишним?!) или постобработать group_concat на языке программирования. Ни то, ни другое не кажется слишком желательным, поэтому, надеюсь, здесь есть лучший и более простой подход.
@saravanatn как именно это будет работать?
@ David542 Дэвид542, я думаю, вам нужно больше разъяснений по вашему вопросу, потому что в соответствии с образцом вывода ваш запрос прост, но ваше описание неясно, пожалуйста, добавьте больше данных в образец.
Как насчет того, чтобы у id=2 было несколько типов цен, и оба не были 'TEMP'? Какой из них возьмет .. первый?






попробуйте, как показано ниже, используя объединение и связанный подзапрос
select id,max(price) as price from prices
where type='temp' group by id
union
select id,max(price) from prices t1
where not exists( select 1 from prices t2 where t1.id=t2.id
and type='temp')
group by id
так как вам нужен весь временный тип, поэтому 1-й запрос будет принимать все временные выходные данные, а 2-й запрос будет фильтровать всю временную группу
выход
id price
1 30.13
2 14.44
@nikhilsugandh, почему бы и нет
лучше возьми это
@nikhilsugandh я знаю, что это будет работать в соответствии с образцом вывода, можете ли вы попробовать это на скрипке
2 13.33 temp для одной из строк, ваш запрос не будет выполнен, нужно показать 13.33, он покажет 14.44, спасибо
@nikhilsugan я понял суть и отредактировал свой ответ, но «продолжайте отрицать все мои вопросы», что это значит, я вас не понимаю
Давайте продолжить обсуждение в чате.
@nikhilsugandh, почему я удалю, где этот ответ дает мне правильный результат
Вы можете использовать следующее решение, используя GROUP BY с MAX:
SELECT id, IFNULL(maxTemp, maxOther) AS maxPrice
FROM (
SELECT id,
MAX(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) maxTemp,
MAX(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) maxOther
FROM table_name
GROUP BY id
)t;
Это решение должно дать вам правильные результаты для ваших требований (ORDER BY ... DESC LIMIT 1).
Но вы также можете использовать другие агрегатные функции, чтобы получить SUM или список (используя GROUP_CONCAT) ценовых значений.
Решение для получения SUM ценовых значений:
SELECT id, IFNULL(sumTemp, sumOther) AS sumPrice
FROM (
SELECT id,
SUM(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) sumTemp,
SUM(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) sumOther
FROM table_name
GROUP BY id
)t;
... или получить список ценовых значений с помощью функции GROUP_CONCAT:
SELECT id, IFNULL(gTemp, gOther) AS listPrice
FROM (
SELECT id,
GROUP_CONCAT(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) gTemp,
GROUP_CONCAT(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) gOther
FROM table_name
GROUP BY id
)t;
Добавляем скрипку :) dbfiddle.uk/…
@ArunPalanisamy уже работал над скрипкой, но спасибо! - Если возможно, я добавляю скрипку, а также провожу тестирование.
@SebastianBrosch спасибо за этот ответ. Ничего себе, это довольно сложный запрос для относительно «простой» задачи. Спасибо за публикацию, это очень полезно!
это будет работать:
select * from(select a.id,a.type,
(select b.price from Table1 b where b.type=a.type and b.type in ('Temp')) mn
from Table1 a group by id,type)ab where mn is not null
union
select id,type,max(price) from Table1
where type is not null
and id not in(select id from(select a.id,a.type,
(select b.price from Table1 b where b.type=a.type and b.type in ('Temp')) mn
from Table1 a group by id,type)ab where mn is not null)
group by id,type;
проверить http://sqlfiddle.com/#!9/c166a9/9
Вы можете использовать союз между идентификатором с «TEMP» и запросом для идентификатора без «TEMP».
select id, price
from my_table
where type ='TEMP'
union
select id, max(price)
from my_table m1
inner join (
select id from my_table where id not in (
selet id
from my_table
where type 'TEMP'
)
group by id
) t1 on t1.id= m1.id
Это, безусловно, самый хакерский подход (два других ответа здесь являются более правильными ответами), но вы также можете использовать оператор CONCAT, чтобы добавить сортировку «в» само поле. Вот основной пример:
SELECT id, RIGHT(
max(CONCAT(if (type='temp', 1,0), '^', price)),
length(max(CONCAT(if (type='temp', 1,0), '^', price)))-2
) price FROM prices group by id
1 30.13
2 14.44
Однако, учитывая, что он не зависит от подвыборки, возможно, он будет работать лучше.
используйте type='temp'