2013-03-21 32 views
1

我试图找到一天中我的数据库中的用户打开大多数电子邮件的小时。SQL Server编译和计算多个表中的数据

我有一堆用户ID的表,我有另一个表与电子邮件打开记录映射到一个表,存储发送的电子邮件,然后映射到特定的用户ID。

所以我的基本愿望是获得一个表格输出,每行是特定的用户(用户ID)和他们打开大多数电子邮件的时间。因此,我需要先查看每个用户ID,然后我猜创建一个临时表,每一行与他们在那个小时内打开的电子邮件数量相关联的时间不同。然后我需要做一个选择Max以从该临时表中获取最大行,然后我需要将它放到我的输出表中,然后重复下一个订阅者。

我只关心一天中的哪一小时。我不在乎月,年或时间。我只想知道一天中的哪个小时大部分人打开电子邮件。

我一直在努力,努力,使用CTE和while循环,但无济于事。任何帮助将不胜感激。

这里的(最小化)结构:

表:认购

| subscriber_id | last_name | first_name |
| 9999999999 |史密斯|约翰|

表:发送邮件

| message_id | subscriber_id |
| 9028340 | 9999999999 |

表:OpenEmails

| open_id | message_id | dtopened |
| 9923489 | 9028340 | '2011-11-22 15:53:02.157'|

我的目标,这样的输出表(最后一栏是不必要的),每个subscriber_id是列表中的独特之处:

| subscriber_id | OpenHour | NumOpens |
| 999999999 | 10 | 32 |

+0

欢迎来到SO。处理这个问题的最好方法是使用SQLFiddle(http://sqlfiddle.com/)创建您的数据定义以及您迄今尝试的内容(DML)。 – 2013-03-21 21:17:36

+0

尝试加入这些表,然后按用户ID,DATEPART(HH,opendate)分组,然后依靠电子邮件ID或其他内容。如果您需要查询代码,则需要共享您的架构和一些示例数据。 – ljh 2013-03-21 21:25:55

回答

0

我做了一些假设,因为没有一个结构中包括。

这是我使用的结构。

CREATE TABLE Subscriber (
    Id int not null identity(1,1), 
    SubscriberId varchar(50) 
    ) 
CREATE TABLE EmailOpened (
    OpenDate DateTime, 
    EmailId int 
    ) 
CREATE TABLE Emails (
    EmailId int not null identity(1,1), 
    SubscriberId varchar(50), 
    EmailText varchar(max) 
) 
GO 

这是我结束的查询。

WITH OpenedByHour AS (
    SELECT 
     SubscriberId, 
     DATEPART(YEAR, OpenDate) AS OpenYear, 
     DATEPART(DAYOFYEAR, OpenDate) AS OpenDOY, 
     DATEPART(HOUR, OpenDate) AS OpenHour, 
     COUNT(1) AS OpenCount 
    FROM Emails 
    JOIN EmailOpened 
     ON Emails.EmailId = EmailOpened.EmailId 
    GROUP BY 
     SubscriberId, 
     DATEPART(YEAR, OpenDate), 
     DATEPART(DAYOFYEAR, OpenDate), 
     DATEPART(HOUR, OpenDate) 
    ), 
    MaxOpenedByHour AS (
    SELECT 
     SubscriberId, 
     OpenYear, 
     OpenDOY, 
     OpenHour, 
     OpenCount, 
     Row_Number() Over (Partition By SubscriberId 
       Order By OpenCount Desc) AS MaxRow 
    FROM OpenedByHour 
    ) 
SELECT SubscriberId, 
    OpenYear, 
    OpenDOY, 
    OpenHour, 
    OpenCount 
FROM MaxOpenedByHour 
WHERE MaxRow = 1 
+0

这将返回它们在数据库中具有的每个小时的所有用户标识和计数的列表。所以我得到每个用户多行 – 2013-03-21 22:29:34

+0

我做了一个改变。现在试试。 – 2013-03-21 22:34:10

+0

这看起来很有前途,但我得到了奇怪的结果,如0000000Jay和 =“00919322作为订户ID。订阅者ID存储为varchar的,是否导致此问题? – 2013-03-21 22:44:34

0

你必须弄清楚如何以正确的列调整它并没有什么,因为没有提供的架构......

With orderedHourly As 
(
     Select SubscriberID, 
       Convert(Date,OpenDateTime) OpenDate, 
       Hour(OpenDateTime) OpenHour, 
       Row_Number() Over (Partition By SubscriberID, Convert(Date,OpenDateTime) Order By Count(1) Desc) As HourPriority 
     From subscriber s 
     Join email e 
       On s.subscriberID = e.subscriberID 
     Group By SubscriberID, Convert(Date,OpenDateTime), Hour(OpenDateTime) 
) 
Select SubScriberID, OpenDate, OpenHour 
From orderHourly 
Where HourPriority = 1 
+0

它看起来像它的工作,但我得到不止一行每subscriber_id – 2013-03-21 22:10:56

+0

这会给你每天一行。你是否想要在延长的时间内完成最多活动的时间? – 2013-03-22 16:40:20

+0

它看起来像你有一个适合你的答案,所以不用担心。很高兴你明白了。 – 2013-03-22 16:41:52