2012-05-12 8 views
0

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

copy_blocks 
id (auto-increment int) 
content (text) 
parent_id (int) 

Когда часть копии вставляется в первый раз, parent_id устанавливается в себе. Пример:

copy_blocks 
id content  parent_id 
1  Hello, World 1 

Когда эта копия обновляется пользователем, новые строки вставляются, но те строки всегда указывает на первую версию блока копирования.

copy_blocks 
id content   parent_id 
2  Hello, World! 1 
3  Heya, World!! 1 

структурирование вещи таким образом, позволяет мне либо запрашивать конкретную версию контента или найти блок родительского копирования, а затем посмотреть на последнюю версию. (В этом случае версия № 3)

Итак, вот мой вопрос: может ли кто-нибудь придумать запрос, который всегда будет возвращать последнюю версию каждого блока контента? В идеале запрос будет возвращать результаты ниже:

id content   parent_id 
3  Heya, World!! 1 

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

+1

, что RDBMS вы используете? и что вы пробовали? – Taryn

+0

Я использую MySQL, и сейчас я делаю это на стороне сервера, что непривлекательно. – Anthony

ответ

1

Один из вариантов:

SELECT 
     c.* 
FROM 
     (SELECT parent_id 
       , MAX(id) AS id 
      FROM copy_blocks 
      GROUP BY parent_id 
     ) AS dc 
    JOIN 
     copy_blocks AS c 
     ON 
     (c.parent_id, c.id) = (dc.parent_id, dc.id) 
+0

Из того, что я читал, JOIN более эффективен, чем IN(), поэтому я думаю, что мне больше нравится ваш ответ. В небольшом тесте ваш запрос занял 0,0359 секунды, в то время как Pablo побежал в 0.0365. Это довольно маленькая разница, но опять же, таблица содержит только три тестовых строки. В целом, я проголосовал за ваш победитель! Однако, спасибо Пабло, за вашу версию. – Anthony

+0

@ Энтони: это ваш стол с использованием системы хранения InnoDB или MyISAM? –

+0

В настоящее время я устанавливаю вещи в MyISAM. Из того, что я прочитал, MyISAM лучше читает, и InnoDB лучше пишет быстро. – Anthony

2

Попробуйте это:

select id, content, parent_id 
    from copy_blocks 
where (id, parent_id) in (
    select max(id), parent_id from copy_blocks group by parent_id 
) 

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

+1

Это хорошо работает! Я добавил индекс на parent_id и id, так что, надеюсь, это сохранит все разумное. Спасибо, Пабло! – Anthony

Смежные вопросы