Sql 第一批订单由。。。然后分组
我有两个表,一个存储用户,另一个存储用户的电子邮件地址Sql 第一批订单由。。。然后分组,sql,mysql,Sql,Mysql,我有两个表,一个存储用户,另一个存储用户的电子邮件地址 表用户:(userId,username,等) 表userEmail:(emailId,userId,email) 我想做一个查询,允许我获取最新的电子邮件地址以及用户记录。 我基本上是在寻找一个 FIRST ORDER BY userEmail.emailId DESC THEN GROUP BY userEmail.userId 这可以通过以下方式实现: SELECT users.userId , users.userna
- 表用户:(
,userId
,username
)等
- 表userEmail:(
,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;
但这会对每一行执行子查询,效率非常低。(在我的程序逻辑中,执行两个单独的查询并将它们“连接”在一起会更快)
为我想要的内容编写的直观查询是:
SELECT
users.userId
, users.username
, userEmail.email
FROM users
LEFT JOIN userEmail USING(userId)
GROUP BY users.userId
ORDER BY
userEmail.emailId
, users.username;
但是,这不是我想要的。(排序之前会执行分组依据
,因此按userEmail.emailId排序
与此无关)
所以我的问题是:
是否可以在不使用子查询的情况下编写第一个查询
我已经搜索并阅读了有关stackoverflow的其他问题,但似乎没有人回答有关此查询模式的问题。如果这是您经常执行的查询,我建议优化您的表以处理此问题 我建议在
users
表中添加一个emailId
列。当用户更改其电子邮件地址,或将较旧的电子邮件地址设置为主要电子邮件地址时,请更新users
表中用户的行,以指示当前的emailId
修改代码以执行此更新后,可以返回并更新旧数据,为所有用户设置emailId
或者,您可以将电子邮件
列添加到用户
表中,这样您就不必通过加入来获取用户的当前电子邮件地址
但这会对每一行执行子查询,效率非常低
首先,您是否有一个可以证明这一点的查询计划/时间安排?您所使用的方法(使用subselect)基本上是一种“直观”的方法。许多数据库管理系统(尽管我不确定MySQL)对此情况进行了优化,并且可以只执行一次查询
或者,您应该能够仅使用(用户id、最新电子邮件id)
元组创建子表,并将连接到该子表上:
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;
我可以问一下,您将电子邮件单独存储的动机是什么吗?您是否使用最新的emailId来指示用户的主要电子邮件地址是哪个电子邮件地址?这将阻止用户选择旧的电子邮件地址作为主地址。您是否考虑过只向用户表中添加一个emailId?当用户更改其电子邮件地址时,会添加新地址,旧电子邮件地址会保留一年,然后再被删除(根据规范),我想通过适当的表设计可以使查询更有效、更有意义。@NamshubWriter,我已经考虑过,但它会创建一个循环引用,我想阻止它。此外,我在其他情况下也有上述问题,因此我想了解一般情况下的最佳解决方案。