2012-04-08 15 views
2

私はジョインに依存して巨大なMySQLのクエリを持っています。MySQLクエリをより簡潔にするにはどうすればよいですか?

SELECT m.id, l.name as location, CONCAT(u.firstName, " ", u.lastName) AS matchee, u.email AS mEmail, u.description AS description, m.time AS meetingTime 
FROM matches AS m 
LEFT JOIN locations AS l ON locationID=l.id 
LEFT JOIN users AS u ON (u.id=m.user1ID) 
WHERE m.user2ID=2 

UNION 

SELECT m.id, l.name as location, CONCAT(u.firstName, " ", u.lastName) AS matchee, u.email AS mEmail, u.description AS description, m.time AS meetingTime 
FROM matches AS m 
LEFT JOIN locations AS l ON locationID=l.id 
LEFT JOIN users AS u ON (u.id=m.user2ID) 
WHERE m.user1ID=2 

各サブステートメントの最初の3行は、UNIONで分割されています。どのようにDRYの原則を守り、3つの行を繰り返さずに、このクエリをより簡潔にすることができますか?このように

+0

* re:* 'LEFT JOIN users AS u u ON(u.id = m.user1ID) WHERE m.user2ID = 2' - 実際のSQLはuser1IDとuser2IDを実際に比較していますか? – Leigh

答えて

1

てみ、動作するはずです:

SELECT m.id, l.name as location, CONCAT(u.firstName, " ", u.lastName) AS matchee, u.email AS mEmail, u.description AS description, m.time AS meetingTime 
FROM matches AS m 
LEFT JOIN locations AS l ON locationID=l.id 
LEFT JOIN users AS u 
ON ((u.id=m.user1ID AND m.user2ID=2) OR (u.id=m.user2ID AND m.user1ID=2)) 
WHERE (m.user1ID=2 OR m.user2ID=2) 
+3

私はそれが同じ結果を与えるとは思わない。私はあなたもWHERE句が必要だと思う、そうしないと、あまりにも多くの行を取得します。 –

+0

私はMark Byersに同意します。期待以上に復帰する可能性があります。 –

+0

あなたはクエリを試しましたか? – aleroot

-1

1)私はあなたがユーザーに一致していることを確認し、その試合に関連するいくつかの情報を保持します。設計が少し複雑だ

。簡単な方法は、マッチするデータを冗長にすることです。このようにすると、常にuser1ID = 2の一致が得られます。あなたは1 user1IDとuser2IDにし、user1IDとuser2IDの反対の値を有する第二に、2回のためにすべての試合を保存する必要があるということです。しかし、私はこれが重複していると言っていました。あなたが多くのレコードを期待するなら、私はそれをお勧めしません。

2)他のアプローチは、あなたのデザインを正規化されます。別のテーブルにmatchUser(matchId、USERID)(主キーは両方attrsにある)

SELECT ... FROM matches AS m 
LEFT JOIN locations AS l ON locationID=l.id 
LEFT JOIN users AS u ON (u.id=mu2.userId) 
INNER JOIN matchUser mu1 ON mu1.userId=2 
INNER JOIN matchUser mu2 ON mu2.matchId=mu1.matchId AND mu2.userId != 2 

このような何か、私はそれをテストしていないが、あなたのアイデアを得るでしょう、多分間違ったクエリを作成します。

0
SELECT 
    s.id, 
    s.location, 
    CONCAT(u.firstName, " ", u.lastName) AS matchee, 
    u.email AS mEmail, 
    u.description AS description, 
    s.meetingTime 
FROM (
    SELECT 
    m.id, 
    l.name AS location, 
    m.time AS meetingTime, 
    CASE m.user1ID when @userID THEN m.user2ID ELSE m.user1ID END AS userID 
    FROM matches AS m 
    LEFT JOIN locations AS l ON m.locationID = l.id 
    WHERE m.user1ID = @userID OR m.user2ID = @userID 
) AS s 
LEFT JOIN users AS u ON s.userID = u.id 

サブクエリは、指定されたユーザIDにmatchesテーブルをフィルタリングlocationsにそれを接合する2つのテーブルから必要な列を引くのかに応じuser1ID又はuser2IDのいずれかを使用して単一userIDカラム(準備します2つは指定されたIDではありません)をusersに結合します。外部クエリはusersに内側のSELECTの結果セットを結合し、残りの列を引き出し、結合の結果として得られます。

関連する問題