Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Выбор одной записи из группы

274
26 сентября 2011 года
Lone Wolf
1.3K / / 26.11.2006
Есть таблица
 
Код:
CREATE TABLE `content_general` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `city` BIGINT(20) NOT NULL,
  `title` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL,
  `link` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=359 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


Нужно выбрать список, но для тех записей у которых link- одинаков, должна быть показана только одна с максимальной created_at. Т.е. так как требуются полноценные записи, то варианты Group by не подходят.
кто что подскажет? уже испробывал много вариантов, даже подзапрос в WHERE.. но везде возникалы проблемы
напрмер:
 
Код:
SELECT c.* FROM content_general c WHERE c.created_at IN (SELECT MAX(c2.created_at) FROM content_general c2 WHERE c.link=c2.link)

вроде работает, но если окажутся две записи с одинаковыми ссылками и датой, будет дубль. избавится от него не получилось.
Хотя вариант дикий и без этого
был еще вариант с аналогичной проблемой
 
Код:
SELECT c.* FROM content_general c LEFT JOIN content_general c2 ON (c.link=c2.link AND c.created_at<c2.created_at) WHERE c2.id IS NULL


так как тут я представил упрощеный вариант задачи, то добавлю что нужно также учесть вариант, когда выбирается не из всей таблицы, а только из определенных id(это выхлоп sphinx-а)

Вобщем я в ступоре. может кто подскажет куда покопать можно?
8.2K
26 сентября 2011 года
Ora-cool
211 / / 20.09.2007
А если дубли, то по какому принципу отбирать? Произвольно? Как вариант, ваш 1-й запрос обернуть еще одним. Сначала находить минимальный/максимальный id для записей-дублей, а в самом внешнем отбирать записи для найденных id.
P.S. В Оракле для таких вещей есть конструкция keep dense_rank, но как я понял у вас не Оракл.
412
26 сентября 2011 года
grgdvo
323 / / 04.07.2007
не совсем понятно, что же должно быть в итоге, что с остальными полями в случае идентичности link и created_id.
можете привести пример.
если правильно понял задание, то вот как вариант

Код:
CREATE VIEW content_general_with_maxdate AS
SELECT
  cg1.*,
  (SELECT MAX(created_at) FROM content_general AS cg2 WHERE cg2.link=cg1.link) AS max_created_at
FROM
  content_general AS cg1;

SELECT
  *
FROM
  content_general_with_maxdate AS cg1
WHERE
  max_created_at=created_at AND
  id = (SELECT MAX(id) FROM content_general_with_maxdate AS cg2 WHERE cg1.created_at = cg2.created_at);
274
26 сентября 2011 года
Lone Wolf
1.3K / / 26.11.2006
да. у меня мускуль. при дублях - да любую, главное одну.
насчет обернуть первый запрос.. я боюсь представить что это будет. за DEPENDENT SUBQUERY и так, по рукам бить надо, так как мускуль его не оптимизирует правильно и получается что подзапрос в where будет выполнятся столько раз, сколько строк в таблице..
я этот пример привел скорее для того, что бы сразу отмести такие варианты в ответах.

P.S. А насчет оракла, если не ошибаюсь то там проще использывать row_number()
274
26 сентября 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: grgdvo
не совсем понятно, что же должно быть в итоге, что с остальными полями в случае идентичности link и created_id.
можете привести пример.
если правильно понял задание, то вот как вариант

create view content_general_with_maxdate
select
cg1.*,
(select max(created_at) from content_general as cg2 where cg2.link=cg1.link and cg2.created_id>cg1.created_id) as max_created_at
from
content_general as cg1

select * from content_general where created_at=max_created_at




и опять же dependent subquery.. считаете без него не обойтись?

8.2K
26 сентября 2011 года
Ora-cool
211 / / 20.09.2007
Цитата: Lone Wolf
и опять же dependent subquery.. считаете без него не обойтись?



Ну если в MySQL нет специальных конструкций, то боюсь, что нет.

412
26 сентября 2011 года
grgdvo
323 / / 04.07.2007
Я там подправил пост свой... цитированный вариант совсем неправильный.
Без subquery пока не представляю, критерий отобра нетривиальный.
В оракле проще (partition by + аналитические функции).
Аналог partition by стандартным sql реализуется только через subquery.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог