2013-01-23 98 views
3

我想了解在同一類別的另一個表中找到的時間戳的閾值時間內發生的事件數量。什麼是最快的方式來改變三角洲(在下面給出的情況下,增量爲5分鐘)?我剛剛使用遊標測試了一種方法(將變量設置爲5,然後繼續增加並執行相同的查詢),但每次迭代需要10秒。在我的實際數據中,#EVENTS中的行數大約等於100K,#CHANGES大約爲500K。我可以在沒有CURSOR的情況下編寫這個查詢嗎?

我的表如下所示:

CREATE TABLE #EVENTS(Category varchar(20), Timestamp datetime) 
GO 

INSERT INTO #EVENTS VALUES('A', '2013-01-23 05:02:00.000') 
INSERT INTO #EVENTS VALUES('A', '2013-01-23 05:04:00.000') 
INSERT INTO #EVENTS VALUES('B', '2013-01-23 05:03:00.000') 
INSERT INTO #EVENTS VALUES('B', '2013-01-21 05:02:00.000') 
GO 

CREATE TABLE #CHANGES(Category varchar(10), Timestamp datetime) 
GO 

INSERT INTO #CHANGES VALUES('A', '2013-01-23 05:00:00.000') 
INSERT INTO #CHANGES VALUES('B', '2013-01-21 05:05:00.000') 

SELECT * 
FROM 
(
    SELECT X.Category, X.Timestamp, Y.Timestamp BeforeT, DATEADD(MINUTE, 5, Y.Timestamp) AfterT 
    FROM #EVENTS X, #CHANGES Y 
    WHERE X.Category = Y.Category 
) X 
WHERE X.Timestamp BETWEEN BeforeT AND AfterT 

DROP TABLE #CHANGES 
DROP TABLE #EVENTS 
GO 
+1

你明白,隱式聯接是一個非常糟糕的prgramming preactice和SQL反模式?它們在SQL服務器中特別不好,因爲左連接隱式語法在當前版本中不受支持,並且在oplder版本中不正確,並且混合隱式和顯式連接通常會導致錯誤的結果。你也可以得到意外的交叉連接。這個語法在幾年前就被取代了,在本世紀沒有任何理由使用它。 – HLGEM

+1

@HLGEM:謝謝你糾正我。你對這個被棄用是正確的。我已經改變了我的代碼和我自己未來的參考,相關的線程在這裏:http://stackoverflow.com/questions/44917/explicit-vs-implicit-sql-joins – Legend

回答

6

這是你在找什麼?它交叉連接到定義增量變化的CTE:

with deltas as (
    select 5 as delta union all 
    select 10 union all 
    select 20 
) 
SELECT * 
FROM (SELECT e.Category, e.Timestamp, c.Timestamp BeforeT, 
      DATEADD(MINUTE, deltas.delta, c.Timestamp) AfterT, 
      deltas.delta 
    FROM #EVENTS e join 
      #CHANGES c 
      on e.Category = c.Category cross join 
      deltas 
    ) X 
WHERE X.Timestamp BETWEEN BeforeT AND AfterT 

我也修復了你的別名。當別名與基礎表名相關時,查詢讀得更好。

+0

+1是的!這真是太棒了〜對於我如何通過這種方式自動創建更長範圍的增量表有什麼建議? – Legend

+1

問這是另一個問題,人們往往不會看回答問題 –

+0

@Legend。 。 。最簡單的方法是將值放入Excel的列中並創建一個像「=」的公式,在另一列中選擇「&A1&」作爲delta union all「',複製公式並編輯第一行和最後一行以成爲準確的語法。 –

相關問題