2011-12-17 72 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