我有一个日常房间的价格表。我的桌子如下。
RoomId Date(DD.MD.YY) RemainingQuota Price
-----------|------------------|--------------------|----------
1 1.5.2017 5 10.00
1 1.6.1017 0 10.00
1 1.7.1017 3 12.00
1 1.8.1017 0 10.00
1 1.9.1017 6 15.00
.....
.....
输入参数
@CheckIn date = CAST('1.5.2017' AS date)
@CheckOut date = CAST('1.8.2017' AS date)
我需要选择3个连续日期,其RemainingQuota
大于零,第一个日期最接近@CheckIn
我知道CTE递归解决方案。然而,它让我非常昂贵。有人知道一个廉价的解决方案吗?
谢谢。
我自己解决了这个案子而没有使用CTE。这是complate测试代码。
BEGIN /*PREPARE SAMPLE DATA*/
CREATE TABLE #priceSchedules(
RoomId int not null,
[Date] date not null,
Quota int not null,
Price decimal(18,4) not null
)
INSERT INTO #priceSchedules
select
RoomId = R.RoomId
,[Date] = D.[Date]
,Quota = abs(checksum(NewId()) % 5)
,Price = abs(checksum(NewId()) % 50)
from
(
select top 100
RoomId = row_number() over(order by R.number)
from master..spt_values R
) R
OUTER apply(
select top 60
[Date] = cast(DATEADD(day, row_number() over(order by t1.number), getdate()) as date)
from master..spt_values t1
) D
END
BEGIN /*PARAMETERS*/
DECLARE @RoomId int = 5,
@CheckIn date = cast(dateadd(day, 3, getdate()) as date),
@CheckOut date = cast(dateadd(day, 6, getdate()) as date);
DECLARE @TotalNight int = datediff(day, @CheckIn, @CheckOut)
END
BEGIN /*QUERY */
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON; --FOR CHECK PERFORMANCE
PRINT('-----------START SELECT---------------------------------')
SELECT
*
FROM
(
SELECT
_P.*
,RowNo = ROW_NUMBER() OVER(PARTITION BY RoomId ORDER BY DayDiffFromCheckIn)
FROM(
SELECT
P.RoomId
,StartDate = P.[Date]
,EndDate = MAX(P2.[Date])
,CalcDay = COUNT(*)
,DayDiffFromCheckIn = CAST(ABS(DATEDIFF(day,P.[Date],@CheckIn)) AS INT)
,MinQuota = IIF(MIN(P.Quota) > MIN(P2.Quota) ,MIN(P2.Quota),MIN(P.Quota))
,TotalPrice = MIN(P.Price) + SUM(P2.Price)
FROM #priceSchedules P
JOIN #priceSchedules AS P2 ON P2.RoomId = P.RoomId AND P2.[Date] > P.[Date] AND P2.[Date] < DATEADD(day, @TotalNight ,P.[Date]) AND P2.Quota > 0
WHERE P.RoomId = @RoomId AND P.Quota > 0 AND P.[Date] >= GETDATE()
GROUP BY P.RoomId,P.[Date]
HAVING(COUNT(*) = (@TotalNight) - 1) -- -1 is for first row
) _P
)__P
WHERE __P.RowNo < 3 -- for top 3 option colsest to @CheckIn date
PRINT('-----------END SELECT---------------------------------')
--SELECT * FROM #priceSchedules
DROP TABLE #priceSchedules
SET STATISTICS TIME OFF;
END
答案 0 :(得分:0)
我自己解决了这个案子而没有使用CTE。这是complate测试代码。
EngagementAgent engagementAgent = EngagementAgent.getInstance(mContext);
Bundle signInExtras = new Bundle();
signInExtras.putString("username", mEmail);
engagementAgent.startJob("sign_in", signInExtras);