我有一个巨大的MySQL查询,取决于JOIN。
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原则,不重复这三行,并使这个查询更简洁?
答案 0 :(得分: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)
答案 1 :(得分: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
子查询过滤指定用户标识上的matches
表,将其连接到locations
,从两个表中提取必要的列并准备一个userID
列(使用任一{要加入user1ID
,{1}}或user2ID
,取决于两者中的哪一个不是指定的ID)。外部查询将内部SELECT的结果集连接到users
,并拉出由于连接而获得的其余列。
答案 2 :(得分:-1)
1)我看到您正在匹配用户,并且您保留了与该匹配相关的一些信息。
设计有点复杂。简单的方法就是使匹配中的数据变得多余。通过这种方式,您将始终获得user1ID = 2的匹配。意味着您需要在一个user1ID和user2ID中存储每个匹配2次,在第二个中使用相反的user1ID和user2ID值存储。然而,正如我所说,这是多余的,如果你期望很多记录我不推荐它。
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
像这样的东西,查询可能是错的我没有测试它,但你会明白的。