2012-01-04 32 views
2

messagesusersという2つのテーブルがあります。 messagesテーブルには、基本的にユーザIDである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を使用したいです1つのクエリでmessagesテーブルの結果を取得します。

私はJOINがこのためのツールだと思っていますが、SQLの経験はほとんどありません。

ありがとうございました。

答えて

4

一般的なu_id列を使用して、2つのテーブルを結合する必要があります。

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テーブルを取り、さて、私にu_idusersテーブル内のすべてをつかむ」、と言っているここで何をやっていますmessagesからu_id列はusersとなります。

where句は、メートルそれを渡したい。

将来の参照のために、テーブルnauseumに参加することはできますので、1つだけ行う必要はありません。

ジョイントとさまざまなタイプについて詳しく知りたい場合は、アットウッドの記事hereを読むことを強くお勧めします。

+0

私は 'とu.u_idを考えていません=?」はOPが望むものです。 –

0

あなたもこのような2つのテーブルを結合することができます。

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あなたは少し、このようなクエリをリファクタリングすることができ、メッセージテーブルに

+2

この古い暗黙的なJOINスタイルを使用することを強くお勧めします。 –

+0

私は@JoeStefanelliに同意します。あなたは 'クロスジョイン 'を作成し、ここで結果をフィルタリングしています。これは、明確で、読みやすく、保守可能なコードを書く方法ではありません。 – Eric

+0

さて、私たちのうちの何人かは古い学校で、まだそれを使っています。:)しかし、私は同意して、JOINsを使用して私の例よりもはるかに良い – emustac

0

ユーザーIDです:

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

+0

テーブルが巨大な場合、リファクタリングされたクエリは各テーブルから必要なデータだけを結合します。逆に書くと、 'messsages'と' users'のデカルト積から得られた一時テーブルは、WHERE句を満たすためにスキャンされます。 – RolandoMySQLDBA

0

あなたのクエリでは、わずかな修正を必要とし、(messages.u_idNULLことはありません場合は、正確に@Joeステファネッリの答えとして、またはINNER JOIN)それはLEFT JOINと同等です:

SELECT 
     (SELECT username FROM `users` WHERE u_id = messages.u_id) AS username 
    , message 
    , sent 
FROM messages 
WHERE r_id = ? 
    AND sent > ? 
関連する問題