Выборка неповторяющихся записей из таблицы

Тема в разделе "PHP", создана пользователем kwin, 19 мар 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. kwin

    kwin

    Регистр.:
    22 авг 2007
    Сообщения:
    413
    Симпатии:
    167
    Здравствуйте, помогите пожалуйста правильно организовать запрос к БД(mysql).

    Имеется 2 таблицы:

    `comments` - коментарии

    id | post_id | autor| date

    и `post`- статьи

    id | autor | date | title


    На данный момент запрос выглядит так:

    PHP:
    SELECT comments.post_idcomments.id as comm_idcomments.autorpost.idpost.date as newsdatepost.title FROM pref_comments as commentspref_post as post WHERE post.id=comments.post_id ORDER BY comments.date DESC LIMIT 0,10
    Задача — выбрать 10 последних коментов, при этом id статиь не должно повторяться.


    Краткий пример

    Сейчас выводять все подряд:

    Статья - anonym
    Статья - anonym
    Статья2 - admin

    Надо только по последнему коменту из каждой статьи:

    Статья - anonym
    Статья2 - admin


    Может кому будет легче понять мои сумбурные объяснения, на примере блока последних коментов на хабре.

    Заранее спасибо.
     
  2. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    236
    Симпатии:
    60
    добавь GROUP BY
    т.е.
    Код:
     
    SELECT comments.post_id, comments.id as comm_id, comments.autor, post.id, post.date as newsdate, post.title FROM pref_comments as comments, pref_post as post WHERE post.id=comments.post_id GROUP BY comments.post_id ORDER BY comments.date DESC LIMIT 0,10 
    
    кстати тут совсем рядом есть раздел Базы данных
    почему тема не там?
     
  3. kwin

    kwin

    Регистр.:
    22 авг 2007
    Сообщения:
    413
    Симпатии:
    167
    К сожалению GROUP BY comments.post_id не дал ожидаемых результатов, выводит непонятно по каким критериям ...

    Насчет раздела возможно и вправду ошибся.
     
  4. pslava

    pslava

    Регистр.:
    16 май 2007
    Сообщения:
    618
    Симпатии:
    122
    попробуй

    Код:
    SELECT distinct comments.post_id, comments.id as comm_id, comments.autor, post.date as newsdate, post.id, post.title 
    FROM pref_comments as comments, pref_post as post 
    WHERE post.id=comments.post_id ORDER BY comments.date DESC LIMIT 0,10
    поскольку нету таблиц то не могу проверить, но по логике должно помочь
     
  5. nuke333

    nuke333 Создатель

    Регистр.:
    8 дек 2008
    Сообщения:
    47
    Симпатии:
    12
    а еще лучше

    Код:
    SELECT distinct comments.post_id, comments.id as comm_id, comments.autor, post.date as newsdate, post.id, post.title
    FROM pref_post as post 
      LEFT JOIN pref_comments as comments 
        ON post.id=comments.post_id 
    ORDER BY comments.date DESC 
    LIMIT 0,10
    
    чтобы база не перелопачивала полное пересечение таблиц pref_comments и pref_post
     
  6. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    236
    Симпатии:
    60
    pslava, nuke333
    Ваши sql запросы не удаляют повторяющиеся строки
    результат будет таков:
    Код:
    post_id 	comm_id 	autor 	date 	newsdate 	id 	title 
    1	5	6	2009-03-15	2009-03-04	1	ddjdjddd
    2	7	6	2009-03-15	2009-03-11	2	2wwwwwwwwwwwwww
    1	4	6	2009-03-14	2009-03-04	1	ddjdjddd
    1	2	2	2009-03-13	2009-03-04	1	ddjdjddd
    1	1	1	2009-03-12	2009-03-04	1	ddjdjddd
    2	3	3	2009-03-10	2009-03-11	2	2wwwwwwwwwwwwww
    1	8	7	2009-03-04	2009-03-04	1	ddjdjddd
    
    а нужен
    Код:
    post_id 	comm_id 	autor 	date 	newsdate 	id 	title 
    1	5	6	2009-03-15	2009-03-04	1	ddjdjddd
    2	7	6	2009-03-15	2009-03-11	2	2wwwwwwwwwwwwww
    
    я добавил колонку date - дата комента для наглядности


    kwin:
    устроит запрос с временными таблицами?
    Код:
    CREATE TEMPORARY TABLE tmp_table (
      `post_id` int(11) NOT NULL,
      `comm_id` int(11) NOT NULL,
      `autor` int(11) NOT NULL,
      `id` int(11) NOT NULL,
      `date` date NOT NULL,
      `newsdate` date NOT NULL,
      `title` text
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
    
    INSERT INTO tmp_table SELECT comments.post_id, comments.id as comm_id, comments.autor, post.id, comments.date, post.date as newsdate, post.title FROM comments, post WHERE post.id=comments.post_id ORDER BY comments.post_id, comments.date DESC;
    
    SELECT * FROM tmp_table GROUP BY id LIMIT 0,10;
    
    DROP TABLE tmp_table;
    
     
  7. pslava

    pslava

    Регистр.:
    16 май 2007
    Сообщения:
    618
    Симпатии:
    122
    так скинь эти таблицы, иначе будут только гипотезы, без проверок.
    Хочь результат - дам материал на чем тестировать:)
     
  8. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    236
    Симпатии:
    60
    pslava мне не в падлу было набить тестовый пример в phpmyadmin
    делов то 5 минут, гуглить решени было дольше
    Код:
    -- 
    -- Структура таблицы `comments`
    -- 
    
    DROP TABLE IF EXISTS `comments`;
    CREATE TABLE IF NOT EXISTS `comments` (
      `id` int(11) NOT NULL,
      `post_id` int(11) NOT NULL,
      `autor` int(11) NOT NULL,
      `date` date NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
    
    -- 
    -- Дамп данных таблицы `comments`
    -- 
    
    INSERT INTO `comments` (`id`, `post_id`, `autor`, `date`) VALUES 
    (1, 1, 1, '2009-03-12'),
    (2, 1, 2, '2009-03-13'),
    (3, 2, 3, '2009-03-10'),
    (4, 1, 6, '2009-03-14'),
    (5, 1, 6, '2009-03-15'),
    (7, 2, 6, '2009-03-15'),
    (8, 1, 7, '2009-03-04');
    
    -- --------------------------------------------------------
    
    -- 
    -- Структура таблицы `post`
    -- 
    
    DROP TABLE IF EXISTS `post`;
    CREATE TABLE IF NOT EXISTS `post` (
      `id` int(11) NOT NULL,
      `autor` int(11) NOT NULL,
      `date` date NOT NULL,
      `title` text NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
    
    -- 
    -- Дамп данных таблицы `post`
    -- 
    
    INSERT INTO `post` (`id`, `autor`, `date`, `title`) VALUES 
    (1, 1, '2009-03-04', 'ddjdjddd'),
    (2, 2, '2009-03-11', '2wwwwwwwwwwwwww');
    
    хотя с реальными данными наверно лучше
     
    kwin нравится это.
  9. pslava

    pslava

    Регистр.:
    16 май 2007
    Сообщения:
    618
    Симпатии:
    122
    сейчас возвращает 2 строки
    Код:
    SELECT distinct comments.post_id, comments.id as comm_id, comments.autor, post.date as newsdate, post.id, post.title 
    FROM comments, post 
    WHERE post.id=comments.post_id 
    group by comments.post_id
    ORDER BY comments.date DESC LIMIT 0,10
    названия таблиц подредактировал,
    к ТС скинь реальные даннные строк по 20 с таблицы
     
  10. Виллен

    Виллен

    Регистр.:
    12 мар 2009
    Сообщения:
    236
    Симпатии:
    60
    pslava,
    это невреное решение,я его уже предлагал, см. второй пост.
    distinct тут нафиг не уперся, убери его и ты изменения не увидишь.

    (для потверждения неверности решения смотри автора
    он должен быть 6, именно 6 юзер написал последний коммент, а не 1)
     
Статус темы:
Закрыта.