0

我有按主题划分的小组会议出席数据,其中一行是一位用户在给定日期/时间出席会议。一个小组提供可以有一定数量的会话,例如 10 个,它们通常在同一时间 (StartTime) 和星期几 (DayOfWeek) 提供。

我想确定小组课程的开始和结束日期,即给定群组的第一个会话和最后一个会话。群组将从参加过小组会议的相同用户的列表中确定。

Table: ---GroupSessions--- GroupSessionDate UserID Topic StartTime DayOfWeek ArrivalStatus Jan-08-2015 1 A 11:30:00 AM Thursday Arrived Jan-08-2015 2 A 11:30:00 AM Thursday Arrived Jan-08-2015 3 A 11:30:00 AM Thursday Arrived Jan-08-2015 4 A 11:30:00 AM Thursday Arrived Jan-15-2015 1 A 11:30:00 AM Thursday Arrived Jan-15-2015 2 A 11:30:00 AM Thursday Arrived Jan-15-2015 3 A 11:30:00 AM Thursday Arrived Jan-15-2015 4 A 11:30:00 AM Thursday Arrived Jan-22-2015 1 A 11:30:00 AM Thursday Arrived Jan-22-2015 2 A 11:30:00 AM Thursday Arrived Jan-22-2015 3 A 11:30:00 AM Thursday Arrived Jan-22-2015 4 A 11:30:00 AM Thursday Missed May-15-2015 5 A 09:00:00 AM Friday Arrived May-15-2015 2 A 09:00:00 AM Friday Arrived May-15-2015 6 A 09:00:00 AM Friday Arrived May-22-2015 5 A 09:00:00 AM Friday Arrived May-22-2015 6 A 09:00:00 AM Friday Arrived May-22-2015 2 A 09:00:00 AM Friday Missed May-29-2015 5 A 09:00:00 AM Friday Arrived May-29-2015 6 A 09:00:00 AM Friday Arrived May-29-2015 2 A 09:00:00 AM Friday Missed

在上面的示例中,有 2 个群组。群组 1 将由用户 1、2、3 和 4 组成,并且几乎所有人都在 2015 年 1 月 8 日至 2015 年 1 月 22 日期间参加了小组产品(主题 A)。与 2015 年 1 月 8 日会议一样,参加 2015 年 1 月 15 日会议的相同用户几乎都参加了 2015 年 1 月 22 日会议。

群组 2(也适用于主题 A)由用户 2、5、6 组成,提供日期为 2015 年 5 月 15 日至 29 日。

每个产品的会话数不是设置的,因为它可以根据需求而变化,所以我不能考虑从产品日期开始的会话数。

我查看了Oracle/SQL:将两个相互关联的列表拆分为独立的群组 ,但问题仍未得到解答。

通常我会直观地进行检查并将用户分配给群组,但我有数万行,并且希望有一种更有效的方法来使用 SQL 来完成这项工作。我正在运行 MSSQL 2014。

我曾尝试将 OUTER APPLY 与表格一起使用,但我并没有真正得到我正在寻找的结果。

你能指出我正确的方向吗?

SQL:

SELECT src.UserID
  ,src.GroupSessionDate
  ,src.StartTime
  ,src.DayofWeek
  ,src.Topic
  ,prevsessdata.GroupSessionDate
  FROM GroupSessions src OUTER APPLY
  (SELECT TOP 1 * GroupSessions prevsd WHERE src.Topic=prevsd.Topic
  AND src.UserID=prevsd.UserID AND src.DayOfWeek=prevsd.DayOfWeek
  AND src.StartTime=prevsd.StartTime 
  AND prevsd.GroupSessionDate<src.GroupSessionDate) prevsessdata

编辑: 可以做出的假设:

  • 会议通常相隔 1 周(节假日除外)
  • 同一群组中的所有会话将具有相同的主题、在一周中的同一天和相同的开始时间
  • 用户可以停止参加,但他们会被列在他们错过的会议中——(对不起,我错过了原始问题中的这个关键细节!)
  • 尽管用户可以参加多个主题的小组,但通常会为所有小组提供的会话列出相同的用户,因此可能存在用户也被列为另一个群组的一部分的情况(这里用户 2 在 1 月和 1 月参加了提供可能)。但这仅限于一个群组中的 1 或 2 个 10-12 的用户。

期望的输出: 对于每个主题、开始时间和 DoW,列出队列开始/结束日期。

谢谢!

4

1 回答 1

0

我想你正在寻找这样的东西:

; WITH T AS (
    SELECT CONVERT(DATE, REPLACE(GroupSessionDate, '-', ' ')) GroupSessionDate, Topic, StartTime, [DayOfWeek]
        , STUFF((SELECT ', ' + CONVERT(NVARCHAR, UserID)
            FROM GroupSessions
            WHERE GroupSessionDate = G.GroupSessionDate
            AND Topic = G.Topic
            AND StartTime = G.StartTime
            AND [DayOfWeek] = G.[DayOfWeek]
            ORDER BY UserID
            FOR XML PATH ('')), 1, 2, '') [Cohort]
    FROM GroupSessions G
    GROUP BY GroupSessionDate, Topic, StartTime, [DayOfWeek])
SELECT Cohort, MIN(GroupSessionDate) SessionStartDate, MAX(GroupSessionDate) SessionEndDate, Topic, StartTime, [DayOfWeek]
FROM T
GROUP BY Topic, StartTime, [DayOfWeek], Cohort, DATEDIFF(dd, 0, GroupSessionDate) % 7
ORDER BY MIN(GroupSessionDate)

一个简单的 group by 语句。真的,从您所问的情况来看,您需要做的就是按主题、开始时间、星期几和 groupsessiondate 分组以找到每个“群组”,然后再次对其进行排序以找到每个这些的最小/最大日期。

如果这不能产生正确的结果,则可能需要使用其他一些标准来进一步缩小范围。

于 2016-01-20T22:17:55.400 回答