2011-12-17 75 views
0

我在编写MySQL查询时遇到了一些麻烦。我不知道如何描述我的问题,以便在网上搜索它,所以如果我的问题很愚蠢,那么很抱歉。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; 

,但它给了我同样的结果。

我会感激甚至指向我可以开始的地方,因为此刻我不知道该如何处理它。

+0

适当的[示例代码](http://sscce.org/)(对于SQL问题,意味着'CREATE TABLE'语句)比专用模式更有帮助。还要注意,使自动递增的列无符号可以使生成值的数量增加一倍(而不是问题中的表可能会达到许多条目)。 – outis 2011-12-17 21:39:24

+0

谢谢,我已经从电影,游戏和技术文档中学到了英语,所以我认为至少我可以写一些说英语的人可以理解的东西是很好的。但下个月我打算吸取一些经验教训来更好地学习。 – navij 2011-12-17 22:18:19

回答

0

像这样的事情

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个表时。

+0

不要忘记“会员m”后的逗号。 – 2011-12-17 21:35:59

+0

不,对不起,这样的查询仍然返回g.name中的一些随机的东西。 – navij 2011-12-17 21:41:50

+0

[隐式连接](http://stackoverflow.com/questions/44917/)不应该用于[显式连接](http://stackoverflow.com/questions/2241991/)。 – outis 2011-12-17 22:05:00

0

我不知道你为什么想要你做什么,但是,如果你想要的信息最早的会员资格日期(因为没有发布自己的日期),没有问题。现在,我们拥有最早的会员资格,这些会员资格会始终指向同一个人,因为您不需要特定的团体。(或者您是否想要最早的人员PER会员资格小组 - 这就是我要写的查询)。现在,我们有最早的用户,并且可以链接到帖子表(显然是作者),但是如果某人有20个帖子在他们的名下,那么该怎么办?您是否还希望该作者的FIRST 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

抱歉,如果我的问题不清楚。最初,我必须展示一些帖子,并且对于每一个我也显示它是作者的昵称和链接到他早些时候加入的组(这个用户的成员资格的第一个成员记录)。 – navij 2011-12-17 21:49:40

+0

也许我应该保留第一个用户将加入“用户”的组作为附加字段。它会免费为我的论坛中的每个帖子的三重连接,这是非常好的性能 – navij 2011-12-17 21:54:29

0

我建议从成员表中移动您的日期列到您的组表,因为这似乎是在那里你”重新跟踪这些信息。成员资格表只是多对多用户< - >组表中的交集表。它应该只包含用户ID和组ID列。

这个怎么样?

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

是的,这是一个多对多的用户<->组的交集。但是在'members'中也存储了一段时间的时间戳,当这个特定用户和该特定组之间的连接已经建立时。我需要获得该用户的第一个(通过时间戳)连接。 – navij 2011-12-17 22:28:34