簡體   English   中英

比較同一資產的日期范圍(多行?)(T-SQL)

[英]Comparing date ranges for same asset (mulitple rows?)(T-SQL)

女士們,先生們,

我對T-SQl相當陌生,但我需要知道這是否有可能。 我有看起來像這樣的數據:

location_id,initial_date,final_date,asset_id,fixed_fee,uid
1,1/1/2005 0:00,11/3/2010 0:00,10025,21,22T0TG9UT 
1,1/1/2005 0:00,7/26/2010 0:00,10026,21,22T0TG8AC 
1,1/1/2005 0:00,7/26/2010 0:00,10027,21,22T0TG8AF 
1,1/1/2005 0:00,4/20/2011 0:00,10028,21,22T0TG8AI 
1,6/13/2011 0:00,12/31/2048 0:00,10028,12.5,38P0WGUV3 
1,4/20/2011 0:00,6/13/2011 0:00,10028,21,3770QEMG1 
1,4/20/2011 0:00,6/13/2011 0:00,10029,21,3770QEUYX 
1,6/13/2011 0:00,12/31/2048 0:00,10029,12.5,38P0WH6G4 
1,1/1/2005 0:00,4/20/2011 0:00,10029,21,22T0TG8AK 
1,1/1/2005 0:00,6/13/2011 0:00,10030,21,22T0TG8AM 
1,6/13/2011 0:00,12/31/2048 0:00,10030,12.5,38P0WHG30 
1,6/13/2011 0:00,12/31/2048 0:00,10031,12.5,38P0WHN50 
1,1/1/2005 0:00,6/13/2011 0:00,10031,21,22T0TG8AR 
1,1/1/2005 0:00,4/14/2014 0:00,10158,21,22T0TG8AW 
1,4/15/2014 0:00,12/31/2048 0:00,10158,12.5,41M0TAZNL 
1,4/15/2014 0:00,12/31/2048 0:00,10159,12.5,41M0TBXIS 
1,1/1/2005 0:00,4/14/2014 0:00,10159,21,22T0TG8B0 
1,1/1/2005 0:00,4/14/2014 0:00,10160,21,22T0TG8B2 
1,4/15/2014 0:00,12/31/2048 0:00,10160,12.5,41M0TCKZM 
1,4/15/2014 0:00,12/31/2048 0:00,10161,12.5,41M0TD5P7 
1,1/1/2005 0:00,4/14/2014 0:00,10161,21,22T0TG8BH 
1,1/1/2005 0:00,7/26/2010 0:00,10162,21,22T0TG8BJ 
1,1/1/2005 0:00,11/3/2010 0:00,10163,21,22T0TG8BL 
1,1/1/2005 0:00,7/26/2010 0:00,10164,21,22T0TG8BN 
1,12/13/2010 0:00,12/31/2048 0:00,10333,15,33L0OR1MH 
1,12/13/2010 0:00,12/31/2048 0:00,10334,15,33L0ORB5R 
1,1/1/2005 0:00,12/31/2048 0:00,10336,5,22T0TG8BQ 
1,1/1/2005 0:00,12/31/2048 0:00,10337,5,22T0TG8BR 
1,1/1/2005 0:00,12/31/2048 0:00,10338,5,22T0TG8BT 
1,1/1/2005 0:00,12/31/2048 0:00,10339,5,22T0TG8BV 

我遇到的是,某些資產被轉移或它們的費用結構發生了變化。 在這時給他們一個final_date(12/31/2048只是一個占位符的結束日期),然后使用相同的信息創建一個新資產,但是新的初始日期,UID和final_date為12/31 / 2048。

日期不允許重疊,這似乎會導致大量其他錯誤。 如果費用結構在1月1日發生變化,則下一個列出的日期必須是1月2日。 因此,我需要使用一些T-SQL,以便在多個行之間的asset_id和location_id匹配的情況下,根據下一個日期范圍檢查每個日期范圍。

我將對此有任何建議或一般指導。 救命!

是的,用SQL解決這樣的問題是很有可能的!

首先,我想出了這個解決方案,這很簡單。 它使用BETWEEN運算符檢查表中所有具有匹配記錄(基於資產ID和位置ID)的日期范圍重疊的記錄,並使用BETWEEN運算符檢查可能的組合。

SELECT
    A.[uid],
    A.[location_id],
    A.[asset_id],
    A.[initial_date],
    A.[final_date],
    A.[fixed_fee]
FROM [tbl] A
WHERE   EXISTS
            (
                SELECT 
                    * 
                FROM [tbl] B
                WHERE   A.[location_id] = B.[location_id]
                    AND A.[asset_id] = B.[asset_id]
                    AND A.[uid] != B.[uid]
                    AND (
                            A.[initial_date] BETWEEN B.[initial_date] AND B.[final_date]
                         OR A.[final_date] BETWEEN B.[initial_date] AND B.[final_date]
                         OR B.[initial_date] BETWEEN A.[initial_date] AND A.[final_date]
                         OR B.[final_date] BETWEEN A.[initial_date] AND A.[final_date]
                        )
            )
ORDER BY 
    A.[location_id],
    A.[asset_id],
    A.[initial_date]

...但是后來我覺得自己有點創意,也想出了這個。 它給出的結果相同,但是這一過程建立了所有可能日期的范圍,然后將其與數據連接起來以查找哪些資產+位置組合具有多個條目,然后返回找到的所有記錄。

WITH [cte_min_max] AS
    (
        SELECT
            MIN([initial_date]) [min_date],
            MAX([initial_date]) [max_date]
        FROM #tbl
    ),
[cte_recursion] AS
    (
        SELECT
            [min_date] [date],
            [max_date]
        FROM [cte_min_max]

        UNION ALL

        SELECT
            DATEADD(DAY, 1, [date]),
            [max_date]
        FROM [cte_recursion]
        WHERE   [date] <= [max_date]
    ),
[cte_duplicates] AS
    (
        SELECT
            A.[date],
            B.[location_id],
            B.[asset_id]
        FROM [cte_recursion] A
        INNER JOIN #tbl B
        ON      A.[date] BETWEEN B.[initial_date] AND B.[final_date]
        GROUP BY 
            A.[date],
            B.[location_id],
            B.[asset_id]
        HAVING COUNT(*) >= 2
    )
SELECT
    A.[uid],
    A.[location_id],
    A.[asset_id],
    A.[initial_date],
    A.[final_date],
    A.[fixed_fee]
FROM #tbl A
WHERE   EXISTS
            (
                SELECT 
                    * 
                FROM [cte_duplicates] B
                WHERE   A.[location_id] = B.[location_id]
                    AND A.[asset_id] = B.[asset_id]
                    AND B.[date] IN (A.[initial_date], A.[final_date])
            )
ORDER BY 
    A.[location_id],
    A.[asset_id],
    A.[initial_date]
OPTION (MAXRECURSION 0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM