2016-05-24 5 views
1

У меня есть таблица материал:SQL и группа По запросу

- id: int 
- Product: varchar (100) 
- Content: text 
- price: double 

Я хотел бы, чтобы отобразить список материалов с группой по продукции с последней ценой я попытался с:

SELECT * FROM materiel GROUP BY produit ORDER BY id 

Но мне представляется группа по продукту с первым призом

13, product1, dell, 25 
14, product2, hp, 4 
17, product3, acer, 15 

запрос без использования группы по

13, product1, dell, 25 
14, product2, hp, 4 
16, product1, acer, 35 
17, product3, acer, 15 

Я хотел бы это шоу

14, product2, hp, 4 
16, product1, acer, 35 
17, product3, acer, 15 
+0

Показать нам простые табличные данные. – jarlh

+1

MySQL или MS SQL Server? Не помещайте те продукты, которые не задействованы ... – jarlh

+0

'ORDER BY' запускается после' GROUP BY'. Вот что происходит: вы группируете по продукту, так что вы получаете по одной строке за произведение. Один - продукт; один из них является одним из его содержимого (вы не говорите, какой из них, например 'max (content)'), один из них является одним из его цен, снова произвольно выбранным и один из его идентификаторов. Затем вы сортируете все продукты по выбранным идентификаторам. Что не имеет смысла, как вы можете видеть. Всегда используйте агрегатные функции в столбцах, которые не входят в предложение GROUP BY, если вы не уверены, что делаете. Это может помочь вам установить режим ONLY_FULL_GROUP_BY, пока вы это изучаете. –

ответ

1

Вы можете использовать IN() заявление:

SELECT * FROM product p 
WHERE p.product,p.id IN(SELECT p1.product,max(p1.id) 
         FROM product p1 
         GROUP BY p1.product) 

Или в JOIN:

SELECT p.* FROM product p 
INNER JOIN (SELECT p1.product,max(p1.id) as max_id 
      FROM product p1 
      GROUP BY p1.product) p1 
ON(p.id = p1.max_id and p.product = p1.product) 
0
SELECT m.* 
FROM materiel m 
LEFT JOIN materiel m1 
ON m.produit = m1.produit 
    AND m.id<m1.id 
WHERE m1.id IS NULL 
1

Один метод использует связанный подзапрос:

select m.* 
from material m 
where m.id = (select max(m2.id) from material m2 where m2.product = m.product); 

Я предпочитаю этот метод, потому что подзапрос может воспользоваться индексом на material(product, id), поэтому он может быть быстрее, чем агрегация подход. Кроме того, если у вас есть дополнительные условия (скажем price > 100), то это должно быть быстрее.

Или, в SQL Server, типичный способ использует row_number():

select m.* 
from (select m.*, 
      row_number() over (partition by product order by id desc) as seqnum 
     from material m 
    ) m 
where seqnum = 1; 
Смежные вопросы