MySQL Query: выберите самые последние элементы с изюминкой - PullRequest
3 голосов
/ 23 сентября 2008

Извините, название больше не поможет. У меня есть база данных URL-адресов медиа-файлов из двух источников:

(1) RSS-каналы и (2) записи вручную.

Я хочу найти десять последних добавленных URL, но не более одного из любого канала. Для упрощения в таблице «urls» есть столбцы 'url, feed_id, timestamp'.

feed_id='' для любого URL, который был введен вручную.

Как бы я написал запрос? Помните, я хочу десять самых последних URL, но только один из любого feed_id.

Ответы [ 6 ]

3 голосов
/ 23 сентября 2008

Принимая эту таблицу

  CREATE TABLE feed (
  feed varchar(20) NOT NULL,
  add_date datetime NOT NULL,
  info varchar(45) NOT NULL,
  PRIMARY KEY  (feed,add_date);

этот запрос должен делать то, что вы хотите . Внутренний запрос выбирает последнюю запись по фиду и выбирает 10 самых последних, а затем внешний запрос возвращает исходные записи для этих записей.

  select f2.*
  from (select feed, max(add_date) max_date
          from feed f1
         group by feed
         order by add_date desc
         limit 10) f1
  left join feed f2 on f1.feed=f2.feed and f1.max_date=f2.add_date;
3 голосов
/ 23 сентября 2008

Предполагая, что feed_id = 0 - это введенный вручную материал, который делает свое дело:

select p.* from programs p
left join 
(
    select max(id) id1 from programs
    where feed_id <> 0
    group by feed_id
    order by max(id) desc
    limit 10
) t on id1 = id
where id1 is not null or feed_id = 0 
order by id desc
limit 10;

Это работает, потому что столбец id постоянно увеличивается, и это также довольно быстро. t это псевдоним таблицы.

Это был мой первоначальный ответ:

(
select 
    feed_id, url, dt 
    from feeds  
    where feed_id = ''
    order by dt desc 
    limit 10
)
union
(

select feed_id, min(url), max(dt) 
        from feeds
        where feed_id <> '' 
        group by feed_id
        order by dt desc    
        limit 10
)
order by dt desc
limit 10
1 голос
/ 23 сентября 2008

Вот (сокращенно) таблица:

CREATE TABLE programs (
  id int(11) NOT NULL auto_increment,
  feed_id int(11) NOT NULL,
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (id)
) ENGINE=InnoDB;

А вот мой запрос, основанный на концепции sambo99:

(SELECT feed_id,id,timestamp 
    FROM programs WHERE feed_id='' 
    ORDER BY timestamp DESC LIMIT 10)
UNION
    (SELECT feed_id,min(id),max(timestamp) 
    FROM programs WHERE feed_id<>'' GROUP BY feed_id 
    ORDER BY timestamp DESC LIMIT 10)
ORDER BY timestamp DESC LIMIT 10;

Кажется, работает. Необходимы дополнительные тесты, но, по крайней мере, я это понимаю. (Хорошая вещь!). В чем улучшение с помощью столбца id?

0 голосов
/ 23 сентября 2008

Будет ли работать группировка по полю, которое вы хотите выделить?

ВЫБРАТЬ url, feedid ИЗ urls GROUP BY feedid ЗАКАЗАТЬ по отметке времени DESC LIMIT 10;

0 голосов
/ 23 сентября 2008

MySQL не имеет наибольшей поддержки для этого типа запроса.

Вы можете сделать это, используя комбинацию предложений "GROUP-BY" и "HAVING", но вы отсканируете всю таблицу, что может стать дорогостоящим.

Здесь опубликовано более эффективное решение, если у вас есть индекс по групповым идентификаторам: http://www.artfulsoftware.com/infotree/queries.php?&bw=1390#104

(По сути, создайте временную таблицу, вставьте в нее верхнюю K для каждой группы, выберите из таблицы, отбросьте таблицу. Таким образом, вы получаете преимущество досрочного завершения из предложения LIMIT).

0 голосов
/ 23 сентября 2008

Возможно, вам нужен союз . Примерно так должно работать:

    (SELECT 
        url, feed_id, timestamp 
    FROM rss_items  
    GROUP BY feed_id 
    ORDER BY timestamp DESC 
    LIMIT 10)
UNION
    (SELECT 
        url, feed_id, timestamp 
    FROM manual_items  
    GROUP BY feed_id 
    ORDER BY timestamp DESC 
    LIMIT 10)
ORDER BY timestamp DESC
LIMIT 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...