Ограничить результаты объединением, не считая объединенные результаты? - PullRequest
3 голосов
/ 25 мая 2010

Не знаю, возможно ли это, я ищу пишущий код для социальной сети, но мне нужна помощь.

SELECT wall.Wid, wall.uid, wall.wcomment, wall.name, comment.wid, comment.comment,comment.wid 
FROM wall 
LEFT JOIN comment ON wall.Wid=comment.wid 
WHERE wall.uid in (SELECT fid from friends where uid = 3) 

Ура, ребята

Ответы [ 2 ]

0 голосов
/ 25 мая 2010

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

SELECT
   wall.Wid,
   wall.uid,
   wall.wcomment,
   wall.name,
   comment.id,
   comment.comment,
   comment.wid
FROM
   wall
LEFT JOIN
   comment
      ON comment.id IN (SELECT id FROM comment WHERE wid = wall.wid ORDER BY id DESC LIMIT 4)
WHERE
   wall.uid IN (SELECT fid from friends where uid = 3)
   AND wall.Wid IN (SELECT Wid FROM wall ORDER BY Wid DESC LIMIT 30)

Примечание: MSSQL Server теперь очень хорош в оптимизации условий IN для выполнения так же хорошо, как и для соединений. Я не имею представления о производительности MySQL в этом отношении.

EDIT:

Если вы не можете использовать LIMIT таким образом, то вам, кажется, придется написать запрос, который получает все комментарии, но затем добавить некоторые условия, чтобы удалить те, которые вам не нужны. Казалось бы, это связано с вычислением «номера строки» для каждого комментария, о котором я могу думать только одним способом, и это может быть не особенно эффективным ...

SELECT
   wall.Wid,
   wall.uid,
   wall.wcomment,
   wall.name,
   comment.id,
   comment.comment,
   comment.wid
FROM
   wall
LEFT JOIN
   comment
      ON comment.wid = wall.wid
      AND 4 >= (
               SELECT
                  COUNT(*)
               FROM
                  comment AS [newer_comment]
               WHERE
                  [newer_comment].wid = comment.wid
                  AND [newer_comment].date_added > comment.date_added
               )
WHERE
   wall.uid IN (SELECT fid from friends where uid = 3)
   AND 30 >= (
             SELECT
                COUNT(*)
             FROM
                wall AS [newer_wall]
             WHERE
                [newer_wall].uid IN (SELECT fid from friends where uid = 3)
                AND [newer_wall].date_added > wall.date_added
             )

ПРИМЕЧАНИЕ. Я добавил поле [date_added] в таблицы [wall] и [comment] для определения порядка, в котором вы выбираете «первые 30» записей ...

Для того, чтобы это было даже отдаленно эффективно, необходимо добавить индексы, чтобы сделать подзапросы COUNT (*) максимально быстрыми.

Существует финальная (более сложная, но, возможно, более интеллектуальная и эффективная версия, которую я могу представить позже сегодня, но мне нужно вернуться к работе сейчас. Если это сработает для вас, я опубликую эту «лучшую» версию)

0 голосов
/ 25 мая 2010

расширяется как ответ:

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

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

SELECT wall.Wid, wall.uid, wall.wcomment, wall.name, comment.wid, comment.comment, comment.wid
FROM wall LEFT JOIN comment ON wall.Wid=comment.wid 
WHERE wall.Wid in (SELECT Wid FROM wall WHERE wall.uid IN (SELECT fid from friends where uid = 3) LIMIT 0, 10)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...