MySQL получает первый и последний результат запроса

#mysql #sql

#mysql #sql

Вопрос:

Я создаю некоторые записи документов в базе данных, и каждый документ может иметь несколько версий. Каждая новая версия — это новая запись в базе данных. Чтобы сгруппировать версии документов вместе, я присваиваю им общий уникальный идентификатор groupId .

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

 documents table
- id
- group_id
- version
- created_at
 

примеры записей:

 id: 1, group_id: 'xyz', version: 1, created_at: date
id: 2, group_id: 'xyz', version: 2, created_at: date
id: 3, group_id: 'xyz', version: 3, created_at: date
etc...
 

Я думал использовать либо distinct, либо order by, а затем добавить ограничение 1 в запрос, чтобы получить только 1 результат:

 SELECT * FROM documents 
WHERE group_id='xyz'
ORDER BY 'created_at' DESC
LIMIT 1
 

но как я могу также включить дату created_at исходного документа в дополнение к (или вместо) дате created_at последней версии?

Я знаю, что могу повторно запустить запрос с ORDER BY 'created_at' ASC LIMIT 1 помощью, но есть ли способ сделать все это в 1 запросе?

Комментарии:

1. Ваш documents и versions должен быть в отдельных таблицах, с внешним ключом в versions таблице, указывающим на идентификатор документа.

2. @Zack уточните, почему «должны» они быть?

3. Сейчас нет компьютера, поэтому не могу ввести полный ответ. Но ваши данные должны быть правильно нормализованы.

Ответ №1:

вы можете использовать подзапросы:

 SELECT * FROM documents 
WHERE id in (
    select min(id) FROM documents WHERE group_id='xyz'
    union
    select max(id) FROM documents WHERE group_id='xyz'
)
 

Ответ №2:

Добавление подзапроса для запроса CREATED_AT оригинала может сработать:

 select id, group_id, created_at, (select min(created_at) from documents d2 where 
d2.group_id = d.group_id)
from documents d
where group_id = 'xyz'
order by created_at desc
limit 1 
 

Поскольку дата CREATED_AT для исходного документа не меняется, я мог бы предложить отменить нормализацию этих данных и добавить новый столбец ORIGINAL_CREATED_AT, который заполняется для всех новых строк.

Ответ №3:

SELECT MIN(created_at) AS date_created, MAX(created_at) AS date_updated, group_id FROM documents WHERE group_id = 'xyz' GROUP BY group_id

Ответ №4:

Если это для одной группы, я бы выбрал:

 select lastd.*,
       (select min(d2.created_at)
        from documents d2
        where d2.group_id = d.group_id
       ) as first_created_at
from (select d.*
      from documents d
      where group_id = 'xyz'
      order by created_at desc
      limit 1
     ) lastd;
 

В частности, это может использовать индекс on documents(group_id, created_at) .

Ответ №5:

Этот запрос:

 select d.* 
from documents d inner join (
  select group_id, min(created_at) mindate, max(created_at) maxdate
  from documents
  group by group_id 
) g on d.group_id = g.group_id and (d.created_at in (g.mindate, g.maxdate))
 

выдает все строки, содержащие минимальные и максимальные created_at значения для каждой group_id .
Вы можете добавить любое условие, которое вам нужно, например:

 where d.group_id = 'xyz'