我正在尝试运行一个查询来获取客户上次下订单的时间。问题是该网站允许人们查看登录和注销的情况。此外,我想合并在某个时刻更改过电子邮件的客户的记录。
我有一个有效的查询(我认为),但它涉及三个选择 - 一个用于最后一个订单,一个用于登录/注销切换,一个用于电子邮件切换。这对我的数据库来说有点慢!我在忽略什么?我怎样才能使这个查询更有效和/或更快?
SELECT last, email, user_id
FROM (
SELECT last, email, user_id
FROM (
SELECT time as last, email,
CASE WHEN user_id > 0 THEN CAST(user_id as CHAR(20))
ELSE email
END as user_id
FROM orders o1
WHERE time=(SELECT MAX(o2.time)
FROM orders o2
WHERE o1.email = o2.email)
ORDER BY last DESC
) as o3
GROUP BY email
) as o4
GROUP BY user_id
ORDER BY email
您可以按时间排列订单,并按复合值(user_id 或电子邮件)进行分区。
我认为有必要将 user_id 和 email 引入相同的数据类型 - 电子邮件数据类型(示例中为 varchar(50))。
参见示例:
测试数据
订单_id | 用户ID | 时间 | 电子邮件 |
---|---|---|---|
1 | 100 | 2024-09-01 14:00:00 | [电子邮件受保护] |
2 | 100 | 2024-09-10 09:00:00 | [电子邮件受保护] |
3 | 200 | 2024-09-12 09:00:00 | [电子邮件受保护] |
4 | 300 | 2024-09-10 09:00:00 | [电子邮件受保护] |
5 | 300 | 2024-09-12 09:00:00 | [电子邮件受保护] |
6 | 400 | 2024-09-10 09:00:00 | [电子邮件受保护] |
7 | 400 | 2024-09-12 09:00:00 | [电子邮件受保护] |
8 | 400 | 2024-09-14 09:00:00 | [电子邮件受保护] |
9 | 0 | 2024-09-11 09:00:00 | [电子邮件受保护] |
10 | 0 | 2024-09-15 15:00:00 | [电子邮件受保护] |
11 | 0 | 2024-09-10 09:00:00 | [电子邮件受保护] |
查询示例
select *
from(
select *
,row_number()over(partition by case when user_id<>0 then CAST(user_id as varCHAR(50)) else email end
order by time desc) rn
from orders
)ranged_orders
where rn=1
order by email
输出