Вот вопрос, который я ломал себе в голове. Допустим, у меня есть таблица, в которой в качестве первичного ключа используется серия меток времени и номер детали. В таблице хранятся инкрементные изменения. Это означает, что для каждой временной отметки, если поле изменяется, это изменение записывается. Если поле не изменяется, то для новой отметки времени оно равно NULL.
Вот основная идея.
part | timestamp | x-pos | y-pos | status
------+-----------+-------+-------+--------
a5 | 151 | 5 | 15 | g
a5 | 153 | NULL | 17 | NULL
(part, timestamp)
является первичным ключом. NULL
s во второй записи указывают значения, которые не изменились с момента первой записи.
Что я хочу сделать, это выбрать самые последние значения для каждого поля, сгруппированного по детали. Например, учитывая приведенные выше записи, результаты будут 153,5,17, г для части а5.
На данный момент у меня есть этот взломанный запрос.
((SELECT x-pos FROM part_changes WHERE x-pos IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1)
UNION
(SELECT y-pos FROM part_changesWHERE y-pos IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1)
UNION
(SELECT status FROM part_changes WHERE status IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1))
Но это возвращает один столбец, что означает, что я могу использовать группирование для организации.
Должен быть более элегантный способ сделать что-то, например, использовать COALESCE или IS NULL творчески. Но я застрял и не могу понять это. У кого-нибудь есть идея?
И нет, я не могу изменить структуру базы данных.
РЕДАКТИРОВАТЬ: ruakh имеет правильную идею. Единственная проблема сейчас - группировка по частям. Я не могу обойти LIMIT 1
для группировки по нескольким частям. Есть идеи?
mdahlman, я не слишком знаком с аналитическими функциями в postgresql. Так что, если это решение будет проще, чем сложный запрос, то обязательно опубликуйте свою идею.
РЕДАКТИРОВАТЬ 2: Спасибо всем за помощь. Мне кажется, я достаточно хорошо понимаю, что мне нужно делать.