我有一些表来存储飞行数据:

CREATE TABLE [dbo].[wings]
(
    [Id] [int] NOT NULL,
    [Manufacturer] [varchar](50) NOT NULL,
    [Model] [varchar](50) NULL,
    [Size] [decimal](3, 1) NULL,
    [hoursWhenBought] [tinyint] NULL,
    [purchaseDate] [date] NULL,

    CONSTRAINT [PK__wings__3214EC07E42B45BC] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
)

CREATE TABLE [dbo].[wingServiceHistory]
(
    [wingId] [int] NOT NULL,
    [date] [date] NOT NULL,
    [servicedBy] [varchar](100) NOT NULL,
    [comments] [varchar](200) NULL,

    CONSTRAINT [PK_wingServiceHistory] 
        PRIMARY KEY CLUSTERED ([wingId] ASC, [date] ASC)
)

CREATE TABLE [dbo].[flights]
(
    [Id] [int] NOT NULL,
    [Date] [date] NOT NULL,
    [TakeOffTime] [time](7) NOT NULL,
    [LandingTime] [time](7) NOT NULL,
    [WingId] [int] NULL
)

CREATE CLUSTERED INDEX [ClusteredIndex-Date] 
ON [dbo].[flights] ([Date] ASC)

-- Sample data
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (1, CAST(N'2019-09-02' AS Date), CAST(N'10:00:00' AS Time), CAST(N'12:00:00' AS Time), 3)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (2, CAST(N'2019-09-03' AS Date), CAST(N'09:30:00' AS Time), CAST(N'12:30:00' AS Time), 3)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (3, CAST(N'2020-05-05' AS Date), CAST(N'07:00:00' AS Time), CAST(N'08:45:00' AS Time), 3)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (4, CAST(N'2020-09-28' AS Date), CAST(N'13:00:00' AS Time), CAST(N'15:00:00' AS Time), 3)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (5, CAST(N'2021-01-03' AS Date), CAST(N'17:00:00' AS Time), CAST(N'19:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (6, CAST(N'2021-01-05' AS Date), CAST(N'15:30:00' AS Time), CAST(N'17:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (7, CAST(N'2021-08-25' AS Date), CAST(N'06:00:00' AS Time), CAST(N'08:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (8, CAST(N'2021-08-26' AS Date), CAST(N'07:00:00' AS Time), CAST(N'09:30:00' AS Time), 3)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (9, CAST(N'2021-09-01' AS Date), CAST(N'06:00:00' AS Time), CAST(N'07:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (10, CAST(N'2022-08-10' AS Date), CAST(N'07:00:00' AS Time), CAST(N'09:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (11, CAST(N'2022-10-17' AS Date), CAST(N'15:00:00' AS Time), CAST(N'17:00:00' AS Time), 13)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (12, CAST(N'2022-10-19' AS Date), CAST(N'16:00:00' AS Time), CAST(N'18:00:00' AS Time), 8)
INSERT INTO [dbo].[flights] ([Id], [Date], [TakeOffTime], [LandingTime], [WingId]) 
VALUES (13, CAST(N'2022-12-21' AS Date), CAST(N'13:00:00' AS Time), CAST(N'15:30:00' AS Time), 13)

INSERT INTO [dbo].[wings] ([Id], [Manufacturer], [Model], [Size], [hoursWhenBought], [purchaseDate]) 
VALUES (2, N'Dudek', N'Synthesis LT', CAST(31.0 AS Decimal(3, 1)), 45, CAST(N'2017-11-04' AS Date))
INSERT INTO [dbo].[wings] ([Id], [Manufacturer], [Model], [Size], [hoursWhenBought], [purchaseDate]) 
VALUES (3, N'Dudek', N'Universal 1.1', CAST(28.0 AS Decimal(3, 1)), 0, CAST(N'2019-08-23' AS Date))
INSERT INTO [dbo].[wings] ([Id], [Manufacturer], [Model], [Size], [hoursWhenBought], [purchaseDate]) 
VALUES (8, N'Dudek', N'Nucleon XX', CAST(24.0 AS Decimal(3, 1)), 150, CAST(N'2021-01-02' AS Date))
INSERT INTO [dbo].[wings] ([Id], [Manufacturer], [Model], [Size], [hoursWhenBought], [purchaseDate]) 
VALUES (13, N'Dudek', N'Hadron 3', CAST(20.0 AS Decimal(3, 1)), 3, CAST(N'2022-10-16' AS Date))

INSERT INTO [dbo].[wingServiceHistory] ([wingId], [date], [servicedBy], [comments]) 
VALUES (3, CAST(N'2020-09-21' AS Date), N'Joe Blogs', N'full trim service')
INSERT INTO [dbo].[wingServiceHistory] ([wingId], [date], [servicedBy], [comments]) 
VALUES (8, CAST(N'2021-08-24' AS Date), N'Joe Blogs', N'full trim service')
INSERT INTO [dbo].[wingServiceHistory] ([wingId], [date], [servicedBy], [comments]) 
VALUES (8, CAST(N'2022-08-03' AS Date), N'Joe Blogs', N'full trim service')

此查询返回所有航班上所有机翼的飞行持续时间和累计小时数:

SELECT
    Id,
    [Date],
    CAST(DATEADD(minute, DATEDIFF(minute, [TakeOffTime], [LandingTime]), 0) AS time) AS Duration,
    CAST ((SUM(DATEDIFF(minute, [TakeOffTime], [LandingTime])) OVER (ORDER BY [Id]) / 60.0) AS DECIMAL(10, 1)) AS CumulativeHours
FROM  
    flights

我需要一个查询,对于flights表中的每个航班,按flights.Id排序,自上次服务日期wingServiceHistory起或自wings年购买日期以来(以较早者为准),每个wingId航班的累计小时数.

或者,在英语中,对于每一次飞行,这一机翼自上次服务以来飞行了多少小时,或自购买以来的小时数,包括购买时的小时数.

所需的结果集是flights表中的每一列加上durationcumulativeHourscumulativeHoursSinceService

我希望结果看起来像是

Id Date TakeOffTime LandingTime WingId duration (HH:MM) cumulativeHours cumulativeHoursSinceService
1 2019-09-02 10:00 12:00 3 02:00 2.0 2.0
2 2019-09-03 09:30 12:30 3 03:00 5.0 5.0
3 2020-05-05 07:00 08:45 3 01:45 6.75 1.75
4 2020-09-28 13:00 15:00 3 02:00 8.75 2.0
5 2021-01-03 17:00 19:00 8 02:00 10.75 152.0
6 2021-01-05 15:30 17:00 8 01:30 12.25 153.5
7 2021-08-25 06:00 08:00 8 02:00 14.25 2.0
8 2021-08-26 07:00 09:30 3 02:30 16.75 4.75
9 2021-09-01 06:00 07:00 8 01:00 17.75 3.0
10 2022-08-10 07:00 09:00 8 02:00 19.75 2.0
11 2022-10-17 15:00 17:00 13 02:00 21.75 5.0
12 2022-10-19 16:00 18:00 8 02:00 23.75 4.0
13 2022-12-21 13:00 15:30 13 02:30 26.25 7.5

推荐答案

一种很好的方法是使用几个窗口函数来获取您需要的内容.在本例中,您还需要在服务历史记录中查找特定的相关行,因此我 Select 了外部应用程序.

SELECT f.Id, f.Date, f.TakeOffTime, f.LandingTime, w.id AS WingID, CAST(DATEADD(MINUTE,DATEDIFF(MINUTE,TakeOffTime,LandingTime),'00:00:00') AS TIME) AS Duration,
CAST(SUM(DATEDIFF(MINUTE,TakeOffTime,LandingTime)) OVER (ORDER BY f.id)/60.0 AS DECIMAL(4,2)) AS CumulativeHours,
CAST(SUM(DATEDIFF(MINUTE,TakeOffTime,LandingTime)) OVER (PARTITION BY w.id, wsh.date ORDER BY f.id)/60.0 AS DECIMAL(4,2))+CASE WHEN wsh.date IS NULL THEN hoursWhenBought ELSE 0 END AS CumulativeHoursSinceService 
  FROM @flights f
    INNER JOIN @wings w
      ON f.WingId = w.Id
    OUTER APPLY (SELECT TOP 1 * FROM @wingServiceHistory wsh WHERE wingid = w.id and date <= f.Date ORDER BY date) wsh
 ORDER BY f.id
Id Date TakeOffTime LandingTime WingID Duration CumulativeHours CumulativeHoursSinceService
1 2019-09-02 10:00:00.0000000 12:00:00.0000000 3 02:00:00.0000000 2.00 2.00
2 2019-09-03 09:30:00.0000000 12:30:00.0000000 3 03:00:00.0000000 5.00 5.00
3 2020-05-05 07:00:00.0000000 08:45:00.0000000 3 01:45:00.0000000 6.75 6.75
4 2020-09-28 13:00:00.0000000 15:00:00.0000000 3 02:00:00.0000000 8.75 2.00
5 2021-01-03 17:00:00.0000000 19:00:00.0000000 8 02:00:00.0000000 10.75 152.00
6 2021-01-05 15:30:00.0000000 17:00:00.0000000 8 01:30:00.0000000 12.25 153.50
7 2021-08-25 06:00:00.0000000 08:00:00.0000000 8 02:00:00.0000000 14.25 2.00
8 2021-08-26 07:00:00.0000000 09:30:00.0000000 3 02:30:00.0000000 16.75 4.50
9 2021-09-01 06:00:00.0000000 07:00:00.0000000 8 01:00:00.0000000 17.75 3.00
10 2022-08-10 07:00:00.0000000 09:00:00.0000000 8 02:00:00.0000000 19.75 5.00
11 2022-10-17 15:00:00.0000000 17:00:00.0000000 13 02:00:00.0000000 21.75 5.00
12 2022-10-19 16:00:00.0000000 18:00:00.0000000 8 02:00:00.0000000 23.75 7.00
13 2022-12-21 13:00:00.0000000 15:30:00.0000000 13 02:30:00.0000000 26.25 7.50

窗口函数允许您通过在OVER子句中指定窗口来定义它们使用的窗口:

按以下内容按组划分 排序依据-按此顺序

加上我们要求的累计时数总和,按航班ID排序.

对于自服务以来的小时数,我们再次要求运行总数,但这一次是按机翼ID和服务日期分组(因此,每个新的都是重新开始的),并按航班ID排序.

Sql相关问答推荐

按postquist中的日期查询json列

在SQL:2003(PGQ)中,Cypher查询语言、GQL、PGQL和属性图查询的常见子集是什么?'

为什么Prisma生成唯一索引,而不是基于方案上的唯一列约束?

SQL SELECT MOST NEST TIMESTAMP BEAT ORDER

在Postgres中合并相似的表

如何根据几个条件 Select 值:如果满足一个范围的SUM,则对另一个范围求和

根据标识符将两行合并为一行

SQL 查找 varchar 类型列及其值中多次出现的子字符串

SQL Server - 复杂场景 - 比较状态并填充值到后续行

SQL中如何转置表格 UNPIVOT是唯一的 Select 吗?

如何使用Informix创建一个临时表,将数据从根表导入并使用筛选条件

如何创建一个递归计数器来查找一个元素有多少父级和子级?

计数时如何为所有时间间隔返回 0 而不是什么都不返回

PostgreSQL - 递归地聚合来自不同列的属性

使用日期和间隔作为键加入 Athena 上的表?

BigQuery Pivot 遗漏行

为数组中的每个元素从表中收集最大整数

存储过程 - 动态 SQL 中不同列值的计数

连续几天购买的客户

多列上的 SQL UNIQUE 约束 - 它们的组合必须是唯一的还是至少其中之一?