我有三个表:userProfile
,loginTimes
,orders
。
我正在尝试获取每个用户的个人资料行,他的上次登录时间以及他的最后一个订单行。
这是我的疑问:
Select u.*, t.loginTime, orders.* From userProfiles u
Inner Join
(Select userId, MAX(time) loginTime From loginTimes Group By userID) t
On u.userId = t.userID
Inner Join
(Select userId, MAX(enterDate) orderDate From orders Group By userId) o
On u.userID = o.userID
Inner Join
orders On orders.userId = u.userId And orders.enterDate = o.orderDate
有没有办法在没有这么多子查询的情况下重写?
答案 0 :(得分:1)
OP我认为这是您要查询的查询,这仍然需要2个子查询,但我不相信您的原始查询按预期运行。
您可以移除loginTimes
子查询,并在外部MAX(loginTime)
列表中使用SELECT
,但是您需要GROUP BY
order
中的每个字段表,这可以说是不洁净的。
以下查询检索用户最近订单的UserId
,最新LoginTime
和整个order
记录:
SELECT u.userId,
u.userName,
l.loginTime,
o.*
FROM userProfiles u
INNER JOIN ( SELECT userId,
loginTime = MAX(time)
FROM loginTimes
GROUP BY userID) l ON u.userId = l.userId
INNER JOIN ( SELECT *,
rowNum = ROW_NUMBER() OVER (PARTITION BY userId
ORDER BY enterDate DESC)
FROM orders) o ON u.userId = o.userId AND o.rowNum = 1
答案 1 :(得分:0)
我相信这样做:
SELECT u.userID
,u.otherColumn
,MAX(t.time) AS loginTime
,MAX(o.enterDate) AS orderDate
FROM userProfiles u
JOIN loginTimes t ON t.userID = u.userID
JOIN orders o ON o.userID = u.userID
GROUP BY u.userID, u.otherColumn
对于您添加到SELECT子句的userProfiles中的每个其他列,您还需要将它添加到GROUP BY子句中。
<强>更新强>
只是因为它可以完成..我在没有任何子查询的情况下尝试过它:)
SELECT u.userID
,MAX(t.time) AS loginTime
,o.*
FROM userProfiles u
JOIN loginTimes t ON t.userID = u.userID
JOIN orders o ON o.userID = u.userID
LEFT JOIN orders o1 ON o.userID = o1.userID AND o.enterDate < o1.enterDate
WHERE o1.orderID IS NULL
GROUP BY u.userID
,o.* --write out the fields here
您还必须在select
子句的GROUP BY
子句中记下所需的订单表的字段。
答案 2 :(得分:0)
您可以使用以下内容轻松重写聚合。
-- Aggregation
(
SELECT
T.userId,
MAX(time) as loginTime,
MAX(enterDate) as orderDate
FROM
loginTimes as T INNER JOIN orders as O
ON
T.userId = O.userId
GROUP BY
T.userId
)
但是,我不明白为什么要计算MAX(enterDate)而不使用它。
在没有聚合的情况下连接的两个表也很容易。你应该远离使用*。如果没有使用所有字段,那就是浪费开销。
SELECT
U.*, O.*
FROM
userProfiles as U
INNER JOIN
orders as O
ON O.userId = U.userId
请解释您尝试从查询中返回的值。 什么是业务逻辑?