#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'