MySQL сложное соединение - PullRequest
       2

MySQL сложное соединение

0 голосов
/ 18 декабря 2011

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

У меня есть 3 таблицы:

CREATE TABLE posts( id INT, author INT );
CREATE TABLE users( id INT, nick varchar(64) );
CREATE TABLE groups( id INT, name varchar(64) );
CREATE TABLE membership (user INT, group INT, date INT ) ;

Членство содержит информацию о пользователях, которые присоединились к некоторым группам. «Дата» в таблице членства - это время, когда пользователь присоединился к этой группе.

Мне нужен запрос, который вернет сообщение, ник его автора и название группы с наименьшей датой присоединения.

Все, что у меня сейчас есть:

SELECT p.id, u.nick, g.name
FROM posts AS p 
    LEFT JOIN users AS u ON u.id = p.author 
    LEFT JOIN membership AS m ON m.user = p.author
    LEFT JOIN groups AS g ON g.id = m.group
WHERE 1;

но, конечно, он возвращает случайное имя группы, а не имя с самой ранней датой присоединения.

Я также попробовал следующий вариант:

SELECT p.id, u.nick, g.name
FROM posts AS p 
    LEFT JOIN users AS u ON u.id = p.author 
    LEFT JOIN 
              (SELECT * FROM membership WHERE 1 ORDER BY date ASC) 
              AS m ON m.user = p.author
    LEFT JOIN groups AS g ON g.id = m.group
WHERE 1;

но это дало мне тот же результат.

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

Ответы [ 3 ]

0 голосов
/ 18 декабря 2011

Я не знаю, почему вы хотите, чтобы вы делали, однако, если вы хотите получить информацию на самую раннюю дату членства (поскольку нет даты для публикации), нет проблем. Теперь у нас самое раннее членство, которое всегда будет указывать на одного и того же человека, так как вы не запрашиваете конкретную группу ... (или вы хотели, чтобы членство в группе PER было самым ранним человеком - это то, для чего я напишу запрос ). Теперь у нас есть самый ранний пользователь, и мы можем ссылаться на таблицу сообщений (по-видимому, автора), но что, если у кого-то есть 20 сообщений под своим именем ... Вам также нужен ПЕРВЫЙ ID для этого автора.

Просто копирование из предоставленных таблиц в качестве справки ... сообщения: id (int), автор (int) пользователи: id (int), ник (varchar) группы: id (int), имя (varchar) членство: пользователь (int), группа (int), дата (int)

select
      u1.nick,
      m2.date,
      g1.name,
      p1.id as PostID
   from 
      ( select m.group, 
               min( m.date ) as EarliestMembershipSignup
           from
              Membership m
           group by 
              m.group ) EarliestPerGroup

      join Membership m2
         on EarliestPerGroup.Group = m2.Group
        AND EarliestPerGroup.EarliestMembershipSignup = m2.Date

         join groups g1
            on m2.group = g1.id

         join users u1
            on m2.user = u1.ID

            join posts p1
               on u1.id = p1.author
0 голосов
/ 18 декабря 2011

Я бы порекомендовал перенести столбец даты из таблицы членства в таблицу групп, поскольку именно там вы отслеживаете эту информацию.Таблица членства - это просто таблица пересечений для таблиц групп «многие ко многим пользователям» <->.Он должен содержать только идентификатор пользователя и столбцы идентификатора группы.

Как насчет этого?

SELECT p.id, u.nick, g.name 
FROM 
  users u, 
  posts p, 
  groups g
INNER JOIN membership m
  ON u.id = m.user
INNER JOIN groups 
  ON m.group = groups.id
ORDER BY g.timestamp DESC
LIMIT 1;
0 голосов
/ 18 декабря 2011

Примерно так:

SELECT p.id, u.nick, g.name
  FROM posts p,
       users u,
       membership m,
       groups g
 WHERE p.author = u.id
   AND m.user = u.id
   AND m.group = g.id
 ORDER BY m.date ASC
 LIMIT 1;

Позаботьтесь о хороших показателях при объединении этих 4 таблиц.

...