[英]How do I make my MySQL query with joins more concise?
I have a huge MySQL query that depends on JOINs.我有一个巨大的 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
The first 3 lines of each sub-statement divided by UNION are identical.除以 UNION 的每个子语句的前 3 行是相同的。 How can I abide by the DRY principle, not repeat those three lines, and make this query more concise?
怎样才能遵守DRY原则,不重复那三行,让这个查询更加简洁呢?
Try in this way, should work:以这种方式尝试,应该工作:
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)
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
The subquery filters the matches
table on the specified user ID, joins it to locations
, pulls the necessary columns from the two tables and prepares a single userID
column (using either user1ID
or user2ID
, depending on which of the two is not the specified ID) to joining with users
.子查询根据指定的用户 ID 筛选
matches
表,将其连接到locations
,从两个表中提取必要的列并准备单个userID
列(使用user1ID
或user2ID
,具体取决于两者中的哪一个不是指定的 ID)加入users
。 The outer query joins the inner SELECT's result set to users
and pulls the rest of the columns, obtained as a result of the join.外部查询将内部 SELECT 的结果集连接到
users
,并提取作为连接结果获得的列的 rest。
1) I see that you are matching users and you keep some information related to that match. 1)我看到你在匹配用户,你保留了一些与匹配相关的信息。
That's a little complicated to design.设计起来有点复杂。 The easy approach is just make the data in matches redundant.
简单的方法就是让 matches 中的数据冗余。 By this way you will always get the match of user1ID=2.
通过这种方式,您将始终获得 user1ID=2 的匹配项。 Means you need to store every match for 2 times, in one user1ID and user2ID and in the second with the opposite values of user1ID and user2ID.
意味着您需要将每个匹配项存储两次,一次是 user1ID 和 user2ID,第二次是 user1ID 和 user2ID 的相反值。 However as I said this is redundant and if you expect many records I don't recommend it.
然而,正如我所说,这是多余的,如果您希望有很多记录,我不推荐它。
2) Other approach is normalizing your design. 2)其他方法是规范化您的设计。 Create another table matchUser(matchId, userId) (primary key is both attrs)
再建一张表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
Something like this, the query maybe wrong I didn't test it but you'll get the idea.像这样,查询可能是错误的我没有测试它,但你会明白的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.