我想在这种情况下得到一些帮助。我有一个带有uuid(unique)、email(repeated)、timestamp(unique)的表,并且有\u sales(如果是可以是1,如果否可以是0)
样本数据
uuid email timestamp has_sales
1 a@gmail.com 2016-10-02 10:28:23 0
2 a@gmail.com 2017-10-03 10:28:23 0
3 a@gmail.com 2017-10-06 17:08:15 1
4 a@gmail.com 2017-12-04 20:47:17 0
5 a@gmail.com 2018-05-21 15:27:04 0
6 b@gmail.com 2016-10-02 10:28:23 1
7 b@gmail.com 2017-10-03 10:28:23 0
我想选择最老的时间戳,除非有一个较新的销售(这是罕见的,但它可能发生)。所以,预期的结果是
uuid email timestamp has_sales
3 a@gmail.com 2017-10-06 17:08:15 1
6 b@gmail.com 2016-10-02 10:28:23 1
目前,我只使用第一个条件(最早的时间戳),如下所示:
SELECT
dm1.uuid,
dm1.email,
dm1.timestamp,
dm1.has_sales
FROM dup_mail dm1
where
time_stamp = (select min(time_stamp)
from dup_mail dm2
where dm1.email = dm2.email
)
order by 2
如何升级这个代码,我可以添加一个条件,如果有销售给一个较新的用户,而没有销售给旧的,我会选择一个较新的?每封电子邮件都与“无销售”(所有重复帐户中为0)或“是销售”(其中一个重复帐户中为1,其他帐户中为0)相关。即使有一个以上的重复帐户与销售,我只想知道是否有销售或没有
1条答案
按热度按时间mu0hgdu01#
相关子查询可以重写
这将对行进行排序
has_sales=1
在具有的行之前has_sales=0
,然后timestamp
. 这个LIMIT 1
子句选择第一行(在对集合排序之后)我们需要一个合适的索引
dup_mail
带的表格email
作为第一列。包括timestamp
以及has_sales
索引中的列将使其成为子查询的覆盖索引。这应该满足规范,但是相关子查询在性能方面可能不是最优的。
(时间戳在所有行中都是唯一的,这有点奇怪;但如果是这样,那么这个查询就可以工作了。)
我们可以通过以下方式获得更好的性能:
然后将其用作内联视图并连接到
dup_mail
表以获取与最小时间戳关联的行笔记
上面给出的sql语法是特定于mysql的(问题被标记为mysql)。
我认为
IF()
函数是仅限mysql的扩展。对于postgresql,替换为:
更便携,更符合ansi标准