2012-01-12 30 views
1

在事件表中,我有一列填充了自特定用戶記錄上次事件以來的秒數。第一個事件的時間顯然是空,因爲沒有以前的事件存在(降序排列):使用TSQL觸發時間段?

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秒。

我可以就如何解決這個問題得到一些建議嗎?

謝謝。

回答

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 

到目前爲止,這似乎適用於數值。不過,我將遇到一個問題,我將在「包含」類型的場景中對此進行處理。我可以修改上面的方法。

謝謝。

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),以及WHERE子句過濾器s_anti.TriggerValue is null確保左連接失敗。

您可能擔心CTE將會很昂貴,並計算所有VisitorID值的總和。它可能是(如果SQL Server特別愚蠢),但通常應該確定它可以篩選到只有9fb63b905a004106bd26c80a5caec52b行並且只計算一行。但是我這樣做是因爲上述查詢的形狀將更普遍地用於其他查詢。但是,如果績效不佳,將第一個WHERE條款條件轉移到CTE中,看看是否改善了問題。

+0

稍後可能會使用它,但有點貴,正如您所提到的......參見上文。 – ElHaix 2012-01-12 13:51:25