使用TSQL触发时间段?

时间:2012-01-12 05:28:28

标签: tsql sql-server-2008-r2

在一个事件表中,我有一个列,其中填充了自特定用户记录最后一个事件以来的秒数。第一个事件时间显然为空,因为之前没有事件存在(desc order):

9fb63b905a004106bd26c80a5caec52b    9   2012-01-12 00:05:56.890
9fb63b905a004106bd26c80a5caec52b    11  2012-01-12 00:05:47.097
9fb63b905a004106bd26c80a5caec52b    10  2012-01-12 00:05:36.713
9fb63b905a004106bd26c80a5caec52b    6   2012-01-12 00:05:26.963
9fb63b905a004106bd26c80a5caec52b    NULL    2012-01-12 00:05:20.500

我有另一张桌子,我有一些触发值。例如,10秒,30秒,90秒带有我想在每个目标被击中时读取的触发值。

记录事件后,我有一个查询,检查是否已超出触发时间:

SELECT TriggerValue, SUM(p.LastEventTimeSpan)
FROM PageVisitEvents p RIGHT JOIN Segments s ON p.CampaignID = s.CampaignID
WHERE p.VisitorID = '9fb63b905a004106bd26c80a5caec52b'
GROUP BY TriggerValue

如果我只想一次触发,这个效果很好。但是,上面的查询返回以下(触发值)总时间):

30  357
60  357
90  357

使用一个值,进行比较就可以了,但是我的比较现在只显示超过此时间的90,而且两者之间没有任何内容。

当满足每个触发器时,我只想返回该触发器。例如,当事件之间的时间达到35秒时,只返回触发值30,而不是10秒。

我可以就如何解决这个问题得到一些建议吗?

感谢。

2 个答案:

答案 0 :(得分:0)

我猜测触发器值来自Segments。首先,让我们将PageVisitEvents表中的值与对Segments表的匹配分开。我们可以用子查询或CTE做到这一点,我选择了一个CTE(并称之为SummedEvents)。

然后,我们需要在Segments中找到匹配行,该行具有低于总和的最高触发值。我们可以通过以下几种方式之一做到这一点,我首选的方法是进行反加入。您可以使用TOP/ORDER BY,但仅在需要一个结果时才有效。

所以,我们有:

;WITH SummedEvents as (
    SELECT VisitorID,SUM(LastEventTimeSpan) as TotalSpan from PageVisitEvents
    GROUP BY VisitorID
)
SELECT
    TriggerValue,TotalSpan
FROM
    SummedEvents se
        inner join
    Segments s
        on
            se.TotalSpan > s.TriggerValue
        left join
    Segments s_anti
        on
            se.TotalSpan > s_anti.TriggerValue and
            s_anti.TriggerValue > a.TriggerValue
WHERE
    se.VisitorID = '9fb63b905a004106bd26c80a5caec52b' AND
    s_anti.TriggerValue is null

反连接是左连接到s_anti的组合(我们尝试在Segments中找到比s更好的匹配行)和{ {1}}子句过滤器WHERE,确保左连接失败。

您可能会担心CTE会很昂贵,并计算所有s_anti.TriggerValue is null值的总和。它可能是(如果SQL Server特别愚蠢),但通常它应该确定它可以只过滤到VisitorID行并且只计算一行。但我已经这样做了,因为上述查询的形状将更普遍地用于其他查询。但是如果性能很差,请将第一个9fb63b905a004106bd26c80a5caec52b子句条件移到CTE中,看看这是否有所改善。

答案 1 :(得分:0)

@Damien_The_Unbeliever,

我看到你说的有关昂贵的东西,我想远离很多连接,所以我把它们放在一个视图中,做了一个子查询:

SELECT TOP (1) TriggerValue
FROM dbo.vw_CombinedView
WHERE SegmentID = 2
AND TriggerValue < (
    SELECT SUM(p.LastEventTimeSpan) AS TotalTime
    FROM PageVisitEvents p
        WHERE p.VisitorID = '9fb63b905a004106bd26c80a5caec52b'
    )
ORDER BY TriggerValue DESC

到目前为止,这似乎适用于数值。但是,我会遇到一个问题,我将在“#contains”包含的内容中执行此操作。场景类型。我可以修改上面的方法。

感谢。