2

我有一个庞大的 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 原则,不重复这三行,让这个查询更简洁?

4

3 回答 3

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)
于 2012-04-08T18:17:50.713 回答
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指定用户 ID 上的表,将其连接到locations,从两个表中提取必要的列并准备单个userID列(使用user1IDuser2ID,取决于两者中的哪一个不是指定的 ID)与 连接users。外部查询将内部 SELECT 的结果集连接到users并提取作为连接结果获得的其余列。

于 2012-04-08T23:09:29.290 回答
-1

1)我看到您正在匹配用户,并且您保留了与该匹配相关的一些信息。

设计起来有点复杂。简单的方法就是使匹配中的数据冗余。通过这种方式,您将始终获得 user1ID=2 的匹配。意味着您需要将每个匹配项存储 2 次,一个是 user1ID 和 user2ID,另一个是 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

像这样,查询可能是错误的,我没有测试它,但你会明白的。

于 2012-04-08T20:08:24.677 回答