2017-08-31 22 views
0

因此,讓我先解釋一下我們的設置。我們有SQL Server 2012的兩個表我們正在尋找:所有帳戶的客人的最短日期

PL_Guest and PL_MergedGuests 

PL_Guest結構如下:

Create Table PL_Guest(
GuestID [int] IDENTITY(1,1) NOT NULL Primary Key, 
CreatedDate [date] NOT NULL) 

PL_MergedGuests結構如下:

Create Table PL_MergedGuests(
MergeID [int] IDENTITY(1,1) NOT NULL Primary Key, 
VictimID [int] NOT NULL, 
SurvivorID [int] NOT NULL) 

所以情況這個:

PL_Guest表記錄了每一位客人創造的記錄, r從中刪除了任何記錄。當我們將兩個賬戶合併在一起時,PL_MergedGuests表格列出了victimid和survivorid的列表。例如,如果某人由於某種原因獲得了多個Guestid,我們會這樣做。現在,合併完成後,一線員工只需選擇該人員要保留的多個賬戶中的哪一個,通常根據客人手中的卡片完成,以便對客人進行更少的更改。如果嘉賓GuestID 5的CreatedDate 1/1/2013和嘉賓ID 10的CreatedDate 10/1/2015;並且合併完成後GuestID 5合併爲GuestID 10,則GuestID 5成爲Victim,GuestID 10成爲倖存者。當我們運行報告時,我們只查看倖存者賬戶。但是我們被要求爲每位客人查找最早的創建日期。因此,對於上面的示例,他們希望和條目返回GuestID 10創建日期2013年1月1日,因爲具有GuestID 10的訪客也具有GuestID 5,其具有較早創建日期的1/1/2013。

現在對於真正困難的部分,訪客可能被合併的次數沒有限制,並且這些表每個都有超過1億條記錄。我以爲這需要某種循環(我認爲這可能涉及到遞歸編碼,儘管我不確定這一點),但是我對如何編寫代碼感到迷茫。如果有幫助但無法修改當前表格,我可以創建新表格。

+0

你說:「當我們運行報告中,我們只能看着生還者賬戶」。你現在怎麼知道哪些客人是倖存者? 「PL_Guest」表中有一些標誌嗎?如果是,請相應地編輯問題。 –

+0

倖存者帳戶可以通過PL_Guest對PL_MergedGuest進行左加入來發現GuestID = VictimID,其中VictimID爲空 –

回答

1

由於缺乏「真實」的例子,我自己定義了幾個例子,並保持了幾次合併。爲了評估所需的「最小創建日期」,我使用了遞歸cte。我不知道該怎麼漲快跌慢這在你的桌子會工作,但至少它應該提供進一步發展的有用起點:

DECLARE @PL_Guest TABLE(
    GuestID INT NOT NULL, 
    CreatedDate [date] NOT NULL 
) 

DECLARE @PL_MergedGuests TABLE(
    MergeID INT NOT NULL, 
    VictimID [int] NOT NULL, 
    SurvivorID [int] NOT NULL 
) 


INSERT INTO @PL_Guest 
    VALUES (1, '2016-11-01'), (2, '2016-12-01'), (3, '2016-11-01'), (4, '2016-12-01'), (5, '2017-01-01'), (6, '2017-01-01'), (7, '2017-02-01'), (8, '2017-02-01'), (9, '2017-03-01'), (10, '2017-04-01'); 

INSERT INTO @PL_MergedGuests 
    VALUES (1, 3, 4), (2, 4, 6), (3, 9, 6), (4, 10, 2), (5, 8, 5); 

WITH cteRecursice AS(
    SELECT mg1.SurvivorID, mg1.VictimID, 1 AS lvl, mg1.SurvivorID AS LastSurvivor, pg1.CreatedDate AS LastSurvivorCreatedDate 
    FROM @PL_MergedGuests mg1 
    JOIN @PL_Guest pg1 ON pg1.GuestID = mg1.SurvivorID 
    UNION ALL 
    SELECT mg2.SurvivorID, mg2.VictimID, c.lvl + 1 AS lvl, c.LastSurvivor, c.LastSurvivorCreatedDate 
    FROM @PL_MergedGuests mg2 
    JOIN cteRecursice c ON mg2.SurvivorID = c.VictimID 
), 
cteGrouped AS(
    SELECT LastSurvivor, LastSurvivorCreatedDate, MIN(CreatedDate) AS MinCreatedDate 
    FROM cteRecursice 
    JOIN @PL_Guest AS pg ON pg.GuestID = VictimID 
    WHERE LastSurvivor NOT IN (SELECT VictimID FROM @PL_MergedGuests AS pmg) 
    GROUP BY LastSurvivor, LastSurvivorCreatedDate 
    UNION ALL 
    SELECT GuestID, CreatedDate, CreatedDate 
    FROM @PL_Guest pg 
    WHERE GuestID NOT IN (SELECT VictimID FROM @PL_MergedGuests UNION ALL SELECT SurvivorID FROM @PL_MergedGuests) 
) 
SELECT LastSurvivor, IIF(MinCreatedDate < LastSurvivorCreatedDate, MinCreatedDate, LastSurvivorCreatedDate) AS MinCreatedDate 
    FROM cteGrouped cg 
    ORDER BY LastSurvivor 
    OPTION (MAXRECURSION 0) 
+1

非常感謝。這已經回答了我的問題。我將在本週晚些時候在我們的測試實驗室測試它的速度。然而,無論這至少讓我有一個工作的答案。 –

+1

我可以在我們的測試實驗室測試這個,它運行得很好。我能夠將它移動到生產服務器上,並且該代碼運行在1分鐘左右,這非常棒。非常感謝你的幫助。 –

+0

很高興我能幫到你。 :-) – Tyron78

相關問題