减少天数SQL

时间:2018-01-04 11:19:51

标签: sql sql-server tsql count

我有一个非常简单的要求,但我正努力寻找解决方法。但是,我知道使用代码而不是SQL可能会更好。

我有一个非常简单的查询:

SELECT
  ServiceCode,
  StartDate,
  Available
FROM @tmpAvailability
ORDER BY StartDate;

产生如下输出:

Code    |    Dates    |    Available
TEST    | 2018-01-04  |        1
TEST    | 2018-01-05  |        1
TEST    | 2018-01-06  |        0    
TEST    | 2018-01-07  |        0
TEST    | 2018-01-08  |        0
TEST    | 2018-01-09  |        0
TEST    | 2018-01-10  |        1
TEST    | 2018-01-11  |        1
TEST    | 2018-01-12  |        1
TEST    | 2018-01-13  |        0

我需要的是可用天数减少,例如:

Code    |    Dates    |    Available    |  Days Available
TEST    | 2018-01-04  |        1        |        2
TEST    | 2018-01-05  |        1        |        1
TEST    | 2018-01-06  |        0        |        0
TEST    | 2018-01-07  |        0        |        0
TEST    | 2018-01-08  |        0        |        0
TEST    | 2018-01-09  |        0        |        0
TEST    | 2018-01-10  |        1        |        3
TEST    | 2018-01-11  |        1        |        2
TEST    | 2018-01-12  |        1        |        1
TEST    | 2018-01-13  |        0        |        0

2 个答案:

答案 0 :(得分:2)

通过在可用列和简单row_number上使用row_number和分区,我们可以实现输出

Program Main

Implicit none

Open(15,File='Output.txt')

  Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_01(67.45),Writing_01(-4.04)
  Write(15,'(1x,a,1x,"j",1x,a,1x,"Juhu!")') Writing_02(67.45),Writing_02(-4.04)

Close(15)

Contains

Function Writing_01 ( Deg ) Result ( Str )

Real,intent(in) :: Deg
Character(:),allocatable :: Str
Character(len = 15 ) :: Str_temp

If ( int( Deg ) > 0 ) then

    Write(Str_temp , '(F0.2)' ) 100000.0 + Deg
    Str_temp = Str_temp(2:)

Else

    Write(Str_temp, '(F0.2)' ) 100000.0 + abs(Deg)
    Str_temp = "-"//Str_temp(3:)

Endif

Str = trim ( adjustl ( Str_temp ))

End Function Writing_01

Function Writing_02 ( Deg ) Result ( Str_temp )

Real,intent(in) :: Deg
Character(:),allocatable :: Str_temp
Character(len=1561) :: Form_02 , Res

If (int( Deg ) > 0 ) then

  Form_02 = '(i5.5,f0.2)'   ! allow a total of 4 leading zeros.

Else

  Form_02 = '(i5.4,f0.2)'   ! "-" sign takes up one space, so 3 leading zeros remain.

Endif

Write(Res , Form_02 )  int( Deg ), abs( Deg - int( Deg ) )

Str_temp = trim ( adjustl ( Res ))

End Function Writing_02

End program Main

答案 1 :(得分:0)

认为这可能会对@Rams'回答。请注意,通过使用SUM函数,零可用性组自动总和为零,因此我可以消除那些纯粹根据ROW_NUMBER处理这些情况的逻辑。

它还可以在同一个表中容纳不同的代码(如果可能的话)。

SELECT
    code
    ,dates
    ,available
    ,SUM(available) OVER (PARTITION BY code, available, avail_group_num ORDER BY dates DESC) AS days_available

FROM
    (
        SELECT
            *
            ,( ROW_NUMBER() OVER (PARTITION BY code ORDER BY dates ASC)
                - ROW_NUMBER() OVER (PARTITION BY code, available ORDER BY dates ASC) 
                ) AS avail_group_num

        FROM
            tmpAvailability

    ) AS grouped_availability

ORDER BY
    dates ASC

结果:

code       dates      available   days_available
---------- ---------- ----------- --------------
TEST       2018-01-04 1           2
TEST       2018-01-05 1           1
TEST       2018-01-06 0           0
TEST       2018-01-07 0           0
TEST       2018-01-08 0           0
TEST       2018-01-09 0           0
TEST       2018-01-10 1           3
TEST       2018-01-11 1           2
TEST       2018-01-12 1           1
TEST       2018-01-13 0           0

(10 rows affected)