我有两个表,一个存储用户,另一个存储用户的电子邮件地址。
userId
username``etc
emailId
userId``email
我想做一个查询,使我可以获取最新的电子邮件地址以及用户记录。 我基本上是在寻找一个说
FIRST ORDER BY userEmail.emailId DESC THEN GROUP BY userEmail.userId
这可以通过以下方式完成:
SELECT users.userId , users.username , ( SELECT userEmail.email FROM userEmail WHERE userEmail.userId = users.userId ORDER BY userEmail.emailId DESC LIMIT 1 ) AS email FROM users ORDER BY users.username;
但这对每一行都执行子查询,并且效率很低。(执行2个单独的查询并将它们“联接”到我的程序逻辑中更快)。
编写我想要的内容的直观查询将是:
SELECT users.userId , users.username , userEmail.email FROM users LEFT JOIN userEmail USING(userId) GROUP BY users.userId ORDER BY userEmail.emailId , users.username;
但是,这没有我想要的功能。(由于GROUP BY是在排序之前执行的,因此ORDER BY userEmail.emailId与之无关)。
GROUP BY
ORDER BY userEmail.emailId
所以我的问题是: 是否可以在不使用子查询的情况下编写第一个查询?
我已经搜索并阅读了关于stackoverflow的其他问题,但是似乎没有人回答有关此查询模式的问题。
但这对每一行都执行子查询,并且效率很低
首先,您是否有一个证明这一点的查询计划/时间安排?您完成操作的方式(使用子选择)几乎是执行操作的“直观”方式。许多DBMS(尽管我不确定MySQL)都针对这种情况进行了优化,并且将只能执行一次查询。
另外,您应该能够仅使用一个(user id, latest email id)元组创建一个子表,并JOIN在其上:
(user id, latest email id)
JOIN
SELECT users.userId , users.username , userEmail.email FROM users INNER JOIN (SELECT userId, MAX(emailId) AS latestEmailId FROM userEmail GROUP BY userId) AS latestEmails ON (users.userId = latestEmails.userId) INNER JOIN userEmail ON (latestEmails.latestEmailId = userEmail.emailId) ORDER BY users.username;