![](/img/trans.png)
[英]T-SQL: How to return separate columns of data for different date ranges selected from same table?
[英]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.