Sql-Server

基於表中“相似”行的 SQL 計算

  • April 12, 2012

我正在使用 SQL Server 2008 R2,為 SSAS 建構一個事實表。

因此,我可以通過對 SSIS 任務的 SQL 查詢來接受解決方案。

假設我有一個看起來有點像這樣的事實表,它記錄了人們何時吃過蛋糕,以及吃了多少(用於說明目的)。

Surrogate Key | CakeType | PersonKey | CakesEaten | Date     | HadSeconds
1               20         1234        4            20120412   0
2               41         2345        3            20120401   0 
3               25         3456        4            20120408   0
4               39         2345        2            20120402   0
5               20         4567        3            20120409   0
6               89         9876        2            20120405   0
7               31         1579        4            20120408   0
8               29         2709        3            20120402   0
9               27         3456        3            20120410   0
10              26         2345        2            20120408   0

CakeType 和 PersonKey 和 Date 都是維度的外鍵。

CakesEaten 和 HadSeconds 是度量。

技術型問題:我想做的是將一個事實標記為“HadSeconds”,其中一個人在前一個事實的 2 天內在表中有記錄。

業務類型問題:向我展示人們在前 2 天已經吃過蛋糕後去吃蛋糕的實例。

例如,Person ‘2345’ 在這個事實表中有 3 條記錄,ID 分別為 2、4、10。

我想將 ID ‘4’ 的 ‘HadSeconds’ 標記為 ‘1’,因為 ID 4 的日期在 ID2 的 2 天內,因此該人連續快速吃蛋糕,並且此實例需要標記為 ‘HadSeconds ‘。ID ‘10’ 的日期戳是 ID ‘4’ 後 6 天,因此不需要標記 ID 10 的 ‘HadSeconds’ 列。

請注意,只有記錄是一個人有多個條目的事實需要考慮。

最好的(笑)事情?這個事實表有大約。其中有 6000 萬條記錄。

實現這一目標的最有效方法是什麼?把東西分解成臨時表?排序?游標(ew…),SSIS 中的聚合任務…

只是一個UPDATE使用EXISTS將是你最好的選擇:

UPDATE c
SET HadSeconds = 1
FROM Caketable C
WHERE EXISTS (SELECT 1
             FROM CakeTable C2
             WHERE c2.personid = c.personid
             AND c2.date > DATEADD(day, -2, c.date))

如果您認為這會執行太長時間,您可以隨時按日期範圍、蛋糕類型等將其分解以進行小批量生產。

如果你有一個複合索引,personid, date這應該很快。

您也可以進行自加入,但我非常有信心它EXISTS會執行得更快:

UPDATE c
SET HadSeconds = 1
FROM Caketable C
INNER JOIN CakeTable C2
 ON c2.personid = c.personid
 AND c2.date > DATEADD(day, -2, c.date)

引用自:https://dba.stackexchange.com/questions/16452