2012-01-04 65 views
2

我有兩個表,分別叫messagesusers。在messages表中,有一個字段是users表的外鍵,基本上是用戶標識。我試圖使用SELECT查詢從messages表中檢索結果,但我想要用戶用戶名而不是他們的用戶ID。這個SQL是錯誤的,但我認爲它橫跨什麼,我試圖做的想法得到:另一個SELECT語句內的SELECT語句

SELECT (SELECT username FROM `users` WHERE u_id=?), message, sent FROM `messages` WHERE r_id=? AND sent > ? 

基本上,我想用存儲在messages表中的用戶ID來獲取用戶名稱要返回並在一個查詢中獲得messages表的結果。

我認爲JOINs就是這個工具,但我很少有沒有SQL經驗。

謝謝。

回答

4

您想使用常見的u_id列將兩個表聯接在一起。

SELECT u.username, m.message, m.sent 
    FROM messages m 
     INNER JOIN users u 
      ON m.u_id = u.u_id 
    WHERE m.r_id = ? 
     AND m.sent > ? 
1

這是一個inner join的情況:

select 
    u.username, 
    m.message, 
    m.sent 
from 
    messages m 
    inner join users u on 
     m.u_id = u.u_id 
where 
    m.r_id = ? 
    and u.u_id = ? 
    and m.sent > ? 

你在做什麼在這裏走的是messages表,說:「好吧,我搶在users表一切在u_id列from messages等於u_idusers

where子句然後根據第米你想通過它。

您可以將表加入nauseum,所以您不必只做一個,以備將來參考。

如果您想了解更多關於連接和不同類型的信息,我強烈建議您閱讀Atwood的文章here

+0

我不認爲'和u.u_id =?'是OP想要的。 – 2012-01-04 22:27:10

0

您可以加入兩個表是這樣過:

SELECT 
    u.username, 
    m.message, 
    m.sent 
FROM 
    messages m, 
    users u 
WHERE 
    m.r_id=? AND 
    m.sent > ? AND 
    m.u_id = u.u_id 

m.u_id是信息表用戶ID

+2

我會*強烈*阻止你使用這種較老的,隱式的JOIN風格。 – 2012-01-04 22:15:16

+0

我同意@JoeStefanelli。你正在創建一個「交叉連接」,然後在這裏過濾結果。這不是編寫清晰,可讀和可維護代碼的方式。 – Eric 2012-01-04 22:21:20

+0

好吧,我們有些人是老派,仍然在使用它。:)但我同意,使用JOINs好得多,我的例子 – emustac 2012-01-04 22:58:48

0

可以稍微重構這樣的查詢:

select 
    u.username, 
    m.message, 
    m.sent 
from 
    (
     select u_id,message,sent 
     from messages 
     where r_id = ? 
     and sent > ? 
    ) m 
    inner join 
    (
     select u_id,username 
     from users 
     where u_id = ? 
    ) u using (u_id); 

你需要確保你有r_id上的複合索引並且發送

ALTER TABLE messages ADD INDEX (r_id,sent); 
+2

當然,我想你可以,但爲什麼你會想要? – Eric 2012-01-04 22:21:47

+0

如果表格很大,重構的查詢只會連接每個表格中所需的數據。以另一種方式寫,通過'messsages'和'users'的笛卡爾乘積產生的臨時表然後被掃描以實現WHERE子句。 – RolandoMySQLDBA 2012-01-04 22:31:11

0

您的查詢只需要小幅回調,然後它等同於LEFT JOIN(或INNER JOIN,正是因爲@Joe Stefanelli的答案,如果messages.u_id是從來沒有NULL):

SELECT 
     (SELECT username FROM `users` WHERE u_id = messages.u_id) AS username 
    , message 
    , sent 
FROM messages 
WHERE r_id = ? 
    AND sent > ?