2010-05-03 3 views
2

Я создаю запрос для получения последних сообщений в форуме с использованием SQL DB.SQL для извлечения последних записей, группировки с помощью уникальных внешних ключей

У меня есть таблица под названием «Почта». Каждое сообщение имеет отношение внешнего ключа к «Thread» и «User», а также дату создания.

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

# Grab the last 10 posts. 
SELECT id, user_id, thread_id 
FROM posts 
ORDER BY created_at DESC 
LIMIT 10; 

# Grab the last 10 posts, max one post per user 
SELECT id, user_id, thread_id 
FROM post 
GROUP BY user_id 
ORDER BY date DESC 
LIMIT 10; 

# Grab the last 10 posts, max one post per user, max one post per thread??? 

ответ

0

Попробуйте это, увидеть, если это помогает:

SELECT DISTINCT 
id, user_id, thread_id 
FROM posts 
ORDER BY created_at DESC LIMIT 10; 

SELECT DISTINCT 
id, user_id, thread_id 
FROM post 
GROUP BY user_id 
ORDER BY date DESC 
LIMIT 10; 

Вы также можете увидеть tutorial об этом и discussion об этом.

ура! :)

+0

Возможно, мне что-то не хватает, но почему бы DISTINCT помочь? Разве это не столбец id pk? – hgulyan

+0

DISTINCT не поможет - потому что ID всегда будет отличаться! – jbox

+0

Я знал, что DISTINCT является частью решения, но не был уверен в его правильном использовании, поэтому включил в него также учебную ссылку. – DMin

0

Я не проверял, но дать этому попытку:

(
    SELECT p1.id, p1.user_id, p1.thread_id 
    FROM post AS p1 LEFT OUTER JOIN post AS p2 
    ON (p1.user_id = p2.user_id AND p1.date < p2.date) 
    WHERE p2.id IS NULL 
    ORDER BY p1.date DESC 
    LIMIT 10 
) 
UNION DISTINCT 
(
    SELECT p3.id, p3.user_id, p3.thread_id 
    FROM post AS p3 LEFT OUTER JOIN post AS p4 
    ON (p3.thread_id = p4.thread_id AND p3.date < p4.date) 
    WHERE p4.id IS NULL 
    ORDER BY p3.date DESC 
    LIMIT 10 
) 
ORDER BY date DESC 
LIMIT 10; 
0

Что об этом? Первый запрос для каждого пользователя, второй для каждого пользователя и для потока.

SELECT id, user_id, thread_id 
FROM post p1 
WHERE id = (SELECT id 
      FROM post 
      WHERE user_id = p1.user_id 
      ORDER BY date DESC 
      LIMIT 1) 
ORDER BY date DESC 
LIMIT 10; 

SELECT id, user_id, thread_id 
FROM post p1 
WHERE id = (SELECT id 
      FROM post 
      WHERE user_id = p1.user_id 
      ORDER BY date DESC 
      LIMIT 1) 
AND id = (SELECT id 
      FROM post 
      WHERE thread_id = p1.thread_id 
      ORDER BY date DESC 
      LIMIT 1) 
ORDER BY date DESC 
LIMIT 10; 
+0

Если вы получите только 10 записей по первому запросу, вы можете получить менее 10 секунд во втором правиле? – jbox

+0

@jbox, Да, конечно, бывают случаи, когда в обоих запросах может быть меньше 10 строк. В первом запросе было бы возможно, если не было 10 пользователей, которые отправили smth. Во втором случае это было бы, когда не было 10 потоков на 10 разных пользователей. – hgulyan

+0

@jbox, Query просто находит последнее сообщение для текущего пользователя и текущего потока. Вы попробовали? – hgulyan