SQL Server - SELECT ROWS有连续的订单

时间:2017-01-05 06:13:28

标签: sql-server sql-server-2014

我有一个日常房间的价格表。我的桌子如下。

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

1 个答案:

答案 0 :(得分:0)

解决

我自己解决了这个案子而没有使用CTE。这是complate测试代码。

            EngagementAgent engagementAgent = EngagementAgent.getInstance(mContext);
            Bundle signInExtras = new Bundle();
            signInExtras.putString("username", mEmail);
            engagementAgent.startJob("sign_in", signInExtras);