Вывод строк с максимальным значением

aliokero

Как правильно изменить запрос так, чтобы в колонке subject выводились строки с максимальным значением views?

SELECT e.subject, 
       e.tid        AS thread_id, 
       Date(e.time) AS arch_time 
FROM   entries e 
WHERE  e.pid = 0 
GROUP  BY Date(e.time) 
ORDER  BY arch_time DESC 
LIMIT  0, 20
2 ответа

aliokero

SELECT subject, thread_id, arch_time
  FROM (
   SELECT e.subject,e.tid AS thread_id,Date(e.time) AS arch_time,
          @n:=if(@ldt=Date(e.time),@n+1,1) N, -- N=1 если у пред. строки была другая дата
                                              -- N=N+1 если дата такая же как в предыдущей
          @ldt:=Date(e.time)                -- Запоминаем дату, для проверки в след. записи
     FROM entries e,(select @ldt:=NULL,@n:=0) A
    WHERE e.pid = 0
    ORDER BY Date(e.time) DESC,e.views DESC
  ) A WHERE N=1
LIMIT  0, 20

Используем переменные. @ldt помнит какая дата была у предыдущей записи, @n считает записи с конкретной датой с 1. Так как все данные отсортированы по дате и views в обратном порядке, то на каждую дату у записи с максимальным views N=1. Группировка происходит сама собой, без group by т.к. мы явно выбираем по одной записи для каждой даты.

Если бы нам была нужна только одна колонка (subject) для записи с максимальным views, т.е. e.tid был бы не нужен, то я бы предложил такой вариант:

select substr(max(concat(lpad(e.views,12,'0'),e.subject)),13) as subject,
       Date(e.time) AS arch_time
  from entries e where e.pid=0
 group by Date(e.time) 
 order by arch_time DESC 
 limit  0, 20

тут фокус в том, что мы собираем строки вида 000000000123SUBJECT, где ведущие цифры это views, берем от этого поля max, получая таким образом значение с максимальным views и вырезаем из него обратно интересующую нас информацию. В принципе можно применить этот подход и для нескольких колонок, но это неудобно, когда их много


aliokero

Погуглите или здесь

В MySQL такая задача выполняется в два этапа:

  1. Следует получить список (изделие, максимальная цена)

  2. Для каждого изделия, получить соответствующие записи, в которых цена соответствует максимальной.

Это легко делается с помощью временной таблицы:

CREATE TEMPORARY TABLE tmp (
        article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
        price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL);

LOCK TABLES shop read;

INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;

SELECT shop.article, dealer, shop.price FROM shop, tmp
WHERE shop.article=tmp.article AND shop.price=tmp.price;

UNLOCK TABLES;

DROP TABLE tmp;

licensed under cc by-sa 3.0 with attribution.