我是SQL脚本的新手,我试图从表格中获取一些计数,其中我计算3种不同的方式,COUNT(1)不是问题,但接下来的两个计数非常慢。
WHERE子句中使用的所有列都有单独的索引,但仍然很慢。是否有更容易和更好的方法来执行这些COUNT?
在下面的代码中,我希望在每个父级SELECT GROUP BY时间戳上获得所有唯一的CustomerID:
(SELECT COUNT(DISTINCT al2.CustomerID) FROM ActionLog al2
WHERE CONVERT(VARCHAR(10),al2.Timestamp,110) = CONVERT(VARCHAR(10),al1.Timestamp,110) and al2.ActionTypeID = al1.ActionTypeID and al2.CampaignID = al1.CampaignID and al2.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al2.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al2.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
AND al2.Timestamp BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),-7) AND DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),0)) as Count_Total_DayUnique
下一个我想得到之前未成为父SELECT GROUP BY子句一部分的所有新的唯一CustomerID:
(SELECT COUNT(DISTINCT al3.CustomerID) FROM ActionLog al3
WHERE al3.ActionTypeID = al1.ActionTypeID and al3.CampaignID = al1.CampaignID and al3.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al3.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al3.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
and al3.CustomerID not in (SELECT COUNT(DISTINCT al4.CustomerID) FROM ActionLog al4
WHERE al4.ActionTypeID = al1.ActionTypeID and al4.CampaignID = al1.CampaignID and al4.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al4.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al3.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
AND al4.Timestamp > DATEADD(dd, -1, CONVERT(VARCHAR(10),al1.Timestamp,110)))) as Count_Total_UniqueOnEvent
请参阅下面的整个脚本:
SELECT CONVERT(VARCHAR(10),Timestamp,110) as Timestamp
,ActivityTypeID
,ActionTypeID
,CampaignID
,EventID
,COUNT(1) as Count_Total_Day
,(SELECT COUNT(DISTINCT al2.CustomerID) FROM ActionLog al2
WHERE CONVERT(VARCHAR(10),al2.Timestamp,110) = CONVERT(VARCHAR(10),al1.Timestamp,110) and al2.ActionTypeID = al1.ActionTypeID and al2.CampaignID = al1.CampaignID and al2.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al2.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al2.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
AND al2.Timestamp BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),-7) AND DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),0)) as Count_Total_DayUnique
,(SELECT COUNT(DISTINCT al3.CustomerID) FROM ActionLog al3
WHERE al3.ActionTypeID = al1.ActionTypeID and al3.CampaignID = al1.CampaignID and al3.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al3.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al3.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
and al3.CustomerID not in (SELECT COUNT(DISTINCT al4.CustomerID) FROM ActionLog al4
WHERE al4.ActionTypeID = al1.ActionTypeID and al4.CampaignID = al1.CampaignID and al4.EventID = al1.EventID and CASE WHEN CHARINDEX('?', al4.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al3.URL)-1) ELSE URL END = CASE WHEN CHARINDEX('?', al1.URL) > 0 THEN LEFT(URL, CHARINDEX('?', al1.URL)-1) ELSE URL END
AND al4.Timestamp > DATEADD(dd, -1, CONVERT(VARCHAR(10),al1.Timestamp,110)))) as Count_Total_UniqueOnEvent
,ReportTag
,CASE WHEN CHARINDEX('?', URL) > 0 THEN LEFT(URL, CHARINDEX('?', URL)-1) ELSE URL END as URL
,TemplateID
FROM ActionLog al1
WHERE Timestamp BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),-7) AND DATEADD(dd, DATEDIFF(dd, 0, GETDATE()),0)
GROUP BY CONVERT(VARCHAR(10),Timestamp,110),ActivityTypeID,ActionTypeID,CampaignID,EventID,ReportTag,URL,TemplateID
我将尝试为您提供有关数据库,样本数据和预期结果的背景信息。
数据库结构:
[dbo].[ActionLog](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Timestamp] [datetime] NULL CONSTRAINT [DF_ActionLog] DEFAULT (getdate()),
[CustomerID] [int] NULL,
[ActivityTypeID] [int] NULL,
[ActionTypeID] [int] NULL,
[CampaignID] [int] NULL,
[EventID] [int] NULL,
[ReportTag] [varchar](500) NULL,
[URL] [varchar](500) NULL,
[TemplateID] [int] NULL,
)
样品:
ID Timestamp CustomerID ActivityTypeID ActionTypeID CampaignID EventID ReportTag URL TemplateID
1 2014-09-24 11:55:27.900 1 1 12 35 68 NULL NULL NULL
2 2014-09-24 12:58:26.710 2 1 12 35 68 NULL NULL NULL
3 2014-09-24 13:54:34.993 2 1 12 35 68 NULL NULL NULL
4 2014-09-24 16:35:33.810 4 1 12 35 68 NULL NULL NULL
5 2014-09-24 16:53:17.623 1 1 12 35 68 NULL NULL NULL
6 2014-09-25 20:36:30.190 1 1 12 35 68 NULL NULL NULL
7 2014-09-25 20:36:33.050 4 1 12 35 68 NULL NULL NULL
8 2014-09-25 23:35:38.520 3 1 12 35 68 NULL NULL NULL
9 2014-09-25 08:35:15.247 4 1 12 35 68 NULL NULL NULL
10 2014-09-25 08:36:11.363 6 1 12 35 68 NULL NULL NULL
11 2014-09-26 11:23:58.223 1 1 12 35 68 NULL NULL NULL
12 2014-09-26 11:55:12.640 2 1 12 35 68 NULL NULL NULL
13 2014-09-26 12:03:28.563 6 1 12 35 68 NULL NULL NULL
14 2014-09-26 12:39:53.003 7 1 12 35 68 NULL NULL NULL
15 2014-09-26 15:55:55.843 8 1 12 35 68 NULL NULL NULL
16 2014-09-27 15:55:55.890 1 1 12 35 68 NULL NULL NULL
17 2014-09-27 16:22:05.540 3 1 12 35 68 NULL NULL NULL
18 2014-09-27 17:34:43.093 8 1 12 35 68 NULL NULL NULL
19 2014-09-27 09:40:23.743 9 1 12 35 68 NULL NULL NULL
20 2014-09-27 10:08:50.240 11 1 12 35 68 NULL NULL NULL
21 2014-09-28 10:12:37.330 11 1 12 35 68 NULL NULL NULL
22 2014-09-28 11:22:26.413 12 1 12 35 68 NULL NULL NULL
23 2014-09-28 11:23:06.520 13 1 12 35 68 NULL NULL NULL
24 2014-09-28 11:52:26.757 14 1 12 35 68 NULL NULL NULL
25 2014-09-28 13:05:13.850 15 1 12 35 68 NULL NULL NULL
26 2014-09-29 13:05:24.900 16 1 12 35 68 NULL NULL NULL
27 2014-09-29 13:06:07.017 16 1 12 35 68 NULL NULL NULL
28 2014-09-29 13:07:26.993 14 1 12 35 68 NULL NULL NULL
29 2014-09-29 14:13:04.893 13 1 12 35 68 NULL NULL NULL
30 2014-09-29 19:54:11.350 12 1 12 35 68 NULL NULL NULL
我的预期结果:
Timestamp ActivityTypeID ActionTypeID CampaignID EventID Count Count_Total_DayUnique Count_Total_UniqueOnEvent Report Url TemplateID
2014-09-24 1 12 35 68 5 3 3 NULL NULL NULL
2014-09-25 1 12 35 68 5 4 2 NULL NULL NULL
2014-09-26 1 12 35 68 5 5 2 NULL NULL NULL
2014-09-27 1 12 35 68 5 5 3 NULL NULL NULL
2014-09-28 1 12 35 68 5 5 4 NULL NULL NULL
2014-09-29 1 12 35 68 5 4 1 NULL NULL NULL
我真的希望有人可以帮助我。
提前致谢
答案 0 :(得分:1)
对于此子查询:
(SELECT COUNT(DISTINCT al2.CustomerID)
FROM ActionLog al2
WHERE CONVERT(VARCHAR(10),al2.Timestamp,110) = CONVERT(VARCHAR(10),al1.Timestamp,110) and
al2.ActionTypeID = al1.ActionTypeID and
al2.CampaignID = al1.CampaignID and
al2.EventID = al1.EventID and
(CASE WHEN CHARINDEX('?', al2.URL) > 0
THEN LEFT(URL, CHARINDEX('?', al2.URL)-1)
ELSE URL
END) = (CASE WHEN CHARINDEX('?', al1.URL) > 0
THEN LEFT(URL, CHARINDEX('?', al1.URL)-1)
ELSE URL
END) AND
al2.Timestamp BETWEEN DATEADD(day, DATEDIFF(dd, 0, GETDATE()),-7) AND DATEADD(day, DATEDIFF(dd, 0, GETDATE()),0)
) as Count_Total_DayUnique
这很复杂。但您可以从ActionLog(ActionTypeId, CampaignId, EventId, TimeStamp, url, CustomerId)
上的索引开始。这应该涵盖子查询,因此只有索引才会用于子查询。