计数子查询中的记录

mak*_*mak 5 sql-server

我有一张表,其中记录着SQL Server 2008R2中的守卫巡逻。

每当值班开始时,都会创建一个新的警报编号,并在此警报编号内巡逻并启动一个时间。

如果执行了至少一次巡逻,则每12个小时我们将收取固定费用。如果在相同的警报编号下超过了12小时范围,则必须另外支付固定费用。

12小时的计算从第一次巡逻开始。

我尝试了一个临时表,但到目前为止无法解决。

DECLARE @t1 TABLE (
    AlertNo INT,
    Starttime SMALLDATETIME,
    Endtime SMALLDATETIME
)

INSERT INTO @t1 (AlertNo, Starttime, Endtime)

SELECT AlertNo,
       Starttimepatrol,
       DATEADD(HOUR, 12, Starttimepatrol)
FROM tblAllPatrols
WHERE PatrolNo = 1

SELECT AlertNo,
       (
           SELECT COUNT(*)
           FROM [tblAllPatrols] a
           INNER JOIN @t1 b ON b.AlertNo = a.AlertNo
           WHERE a.Starttimepatrol BETWEEN b.Starttime AND b.Endtime
       ) AS patrols
FROM [vwAlleDatensaetze]
GROUP BY AlertNo
Run Code Online (Sandbox Code Playgroud)

我知道这还不是故事的结局,但由于我什至无法计算巡逻的次数,因此无法找到解决问题的方法。

它应该以某种方式在每个警报编号的12小时范围内对巡逻进行“分组”,然后计算在同一警报编号下存在多少组。

希望你们中的某人可以带领我实现我需要的结果。

谢谢迈克尔的帮助

Ste*_*ord 0

试试这个,假设第一次巡逻后计费周期是从此时开始的 8 小时的倍数:

SQL小提琴

MS SQL Server 2008 架构设置

查询1

DECLARE @Patrols TABLE
(
    AlertNo INT IDENTITY PRIMARY KEY,
    StartTime DateTime
)

INSERT INTO @Patrols (StartTime)
VALUES ('20160126 09:57'), 
       ('20160126 10:21'),
       ('20160126 19:54'),
       ('20160126 23:21'),
       ('20160127 08:13'),
       ('20160127 16:43'),
       ('20160128 07:33')

;WITH FirstBillingPeriodCTE
AS
(
    SELECT MIN(StartTime) as BillingStartTime, 
           DateAdd(HOUR, 12, MIN(StartTime)) As BillingEndTime, 
           1 As BillingPeriod 
    FROM @Patrols
),
Numbers
As
(
    SELECT num
    FROM (Values (0),(1), (2), (3), (4), (5), (6), (7), (8), (9)) AS n(Num)
), 
BillingPeriodsCTE
AS
(
    SELECT DATEADD(Hour, 8 * (BillingPeriod + Numbers.Num), BillingStartTime) AS BillingStartTime, 
           DATEADD(Hour, 8 * (BillingPeriod + Numbers.Num), BillingEndTime) AS BillingEndTime, 
           BillingPeriod + Numbers.Num As BillingPeriod
    FROM FirstBillingPeriodCTE
    CROSS JOIN Numbers
)
SELECT COUNT(DISTINCT BillingPeriod)
FROM @Patrols P
INNER JOIN BillingPeriodsCTE B
    ON P.StartTime >= B.BillingStartTime AND P.StartTime < B.BillingEndTime
Run Code Online (Sandbox Code Playgroud)

结果

|   |
|---|
| 4 |
Run Code Online (Sandbox Code Playgroud)