【发布时间】:2019-09-27 10:54:18
【问题描述】:
情况:
我有两张桌子。 #t1 有登录名和电子邮件。 #t2 具有与每封电子邮件相关联的国家/地区。
我想加入从#t2 到#t1 的信息,而不必加入两次。在内部或外部查询中只加入一次会破坏cross apply 逻辑。
我当前的查询使用交叉应用来获取滚动信息(下面的小提琴数据):
SELECT DISTINCT CAST(logins AS DATE) AS Dates,
count(distinct d.email) AS DAU,
count(distinct m.MAU) AS MAU
FROM #t1 d
CROSS APPLY (
SELECT CAST(m.logins as date) as dates, m.email AS MAU
FROM #t1 m
WHERE m.logins BETWEEN d.logins and DATEADD(dd, 30, d.logins)
) m
group by CAST(logins as date)
我发现在不中断交叉应用的情况下加入两个表的唯一方法是在外部和内部查询中使用inner join 它,这可能是错误的,但至少输出是正确的。我这样做是为了在内部查询的 where 语句中添加我的第二个条件。当我将逻辑应用于我的实际表时,性能很糟糕(下面的小提琴数据):
SELECT distinct CASt(logins AS DATE) AS Dates,
#t2.country,
count(distinct d.email) AS DAU,
count(distinct m.MAU) AS MAU
FROM #t1 d
inner join #t2 on d.email=#t2.email
CROSS APPLY (
SELECT cast(m.logins as date) as dates, m.email AS MAU, country.country AS country
FROM #t1 m
inner join #t2 country on m.email=country.email
WHERE m.logins BETWEEN d.logins and DATEADD(dd, 30, d.logins)
and #t2.country = country.country
) m
group by cast(logins as date), #t2.country
+-------------+---------+-----+-----+
| Dates | country | DAU | MAU |
+-------------+---------+-----+-----+
| 2019-04-01 | france | 1 | 2 |
| 2019-04-02 | france | 1 | 2 |
| 2019-04-03 | france | 1 | 2 |
| 2019-04-10 | france | 1 | 1 |
| 2019-04-03 | italie | 2 | 2 |
+-------------+---------+-----+-----+
目标:
我怎样才能找到一种方法来将信息从一个表连接到另一个表而不必加入两次。 (下面摆弄数据)
结果应该是这样的(上面第二个查询的输出):
- DAU:每个国家/地区在“x”日发生了多少不同的登录
- MAU:每个国家/地区在第 'x' 天之间发生了多少不同的登录 30 天后。
小提琴:
create table #t1 (email varchar(max), logins datetime)
insert into #t1 values
('aa@gmail.com', '2019-04-01 00:00:00.000'),
('aa@gmail.com', '2019-04-02 00:00:00.000'),
('aa@gmail.com', '2019-04-03 00:00:00.000'),
('zz@gmail.com', '2019-04-10 00:00:00.000'),
('cc@gmail.com', '2019-04-03 00:00:00.000'),
('dd@gmail.com', '2019-04-03 00:00:00.000'),
('dd@gmail.com', '2019-04-03 00:00:00.000')
create table #t2 (country varchar(max), email varchar(max))
insert into #t2 values
('france', 'aa@gmail.com'),
('france', 'zz@gmail.com'),
('italie', 'cc@gmail.com'),
('italie', 'dd@gmail.com')
【问题讨论】:
-
请说明您希望整体查询做什么。
cross apply在做什么? -
@GordonLinoff 查询应该输出每天的每日登录和特定日期的每月登录(这两个指标的不同电子邮件)。交叉应用每天查看每个登录,并查看当天和 30 天后是否有任何登录发生,这就是我计算 MAU 的方式
-
为什么不想“加入两次”?您有性能问题吗?
-
@iamdave 因为我无法加入一次,因为电子邮件和登录不会与国家/地区分组
标签: sql sql-server