sql - 如何根据 SQL Server 查询中的日期返回下一个后续记录?
问题描述
作为我的船舶租赁数据库的一部分,我有一个视图,它返回有关我们拥有的船舶及其固定承诺的一系列信息。在我们的系统中,固定装置上的任何船只都将该承诺标记为“实时”,并且该船只在停租日期之后的任何固定装置承诺都将标记为“后续”(实时和后续标记由用户在前端)。
问题
一艘船可以有多个 FollowOn 承诺,因此我需要找到一种方法,在当前 Live 承诺的停租日期之后仅返回标记为 FollowOn 的下一个承诺。
查询(到目前为止)
SELECT
uve.[Id],
uve.[ViewId],
uve.[VesselId],
ve.[Name],
/***********************
#Fixture (Current)
***********************/
CAST((CASE WHEN fix1.[Id] IS NULL THEN 0 ELSE fix1.[Id] END) AS INT) AS [FixtureId],
fix1.[Date],
fix1.[FirmUntil],
fix1.[Charterer],
ch1.[ChartererName],
/***********************
#Fixture (Next)
***********************/
fix2.FollowOn,
fix2.Id AS NextFixtureId,
fix2.[Date] AS NextOnhire,
CAST((CASE WHEN fix2.FollowOn IS NULL THEN 0 ELSE fix2.FollowOn END) AS BIT) AS FollowOn,
fix2.[FirmUntil] AS NextOffhire,
ch2.ChartererName AS NextChartererName,
CAST((CASE WHEN fix1.[Live] IS NULL THEN 0 ELSE fix1.[Live] END) AS BIT) AS Live
FROM UserVessels AS uve
LEFT JOIN Vessel AS ve ON ve.Id = uve.VesselId
LEFT JOIN VesselTypes AS vt ON vt.[Id] = ve.[Type]
LEFT JOIN (SELECT [Id], [Date], [FirmUntil], [PeriodAmount], [PeriodFrequency], [Charterer], [Port], [Live],[FollowOn], [Broker], [WorkRole], [VesselId]
FROM Fixture
WHERE Live = '1' AND FollowOn = '0') AS fix1 ON fix1.[VesselId] = ve.Id
LEFT JOIN (SELECT [Id],[Date],[Live],[FirmUntil],[FollowOn], [Charterer], [Port], [WorkRole], [VesselId]
FROM Fixture AS f2
WHERE f2.[FollowOn] = '1') AS fix2 on fix2.[VesselId] = ve.Id
LEFT JOIN Charterer AS ch1 ON ch1.Id = fix1.Charterer
LEFT JOIN Charterer AS ch2 ON ch2.Id = fix2.Charterer
如您所见,我想要实现的繁重工作发生在我有一个查看 FollowOn 标志的子查询的连接中。这并不理想,因为如果有不止一个带有后续的夹具,那么你会得到很多行。我只需要在“fix1”停租后立即进行下一个后续操作,这样我就可以将每艘船保持为一排,并且想知道如何实现这一目标?
解决方案
因此,如果您有一个关于固定装置的所有后续列表,正如评论中提到的,您可以使用 row_number 窗口函数来获取下一个:
LEFT JOIN (SELECT [Id],[Date],[Live],[FirmUntil],[FollowOn], [Charterer], [Port], [WorkRole], [VesselId], ROW_NUMBER() OVER (PARTITION BY VesselId ORDER BY Date) [RNum]
FROM Fixture AS f2
WHERE f2.[FollowOn] = '1') AS fix2 on fix2.[VesselId] = ve.Id AND fix2.RNum = 1
但是外部应用可能会更快。你需要测试它。
推荐阅读
- c# - Unity - 组件类型和实例的混淆
- powershell - 防止学生离开 EducationClass 团队?
- php - MySQL 中不允许在递归公用表表达式中使用 LIMIT
- python - Flask: ImportError: No module named folder.file
- python - 循环中的 Lambda 存储在列表中,仅打印最后一个循环的评估值,而不是所有循环迭代的不同值
- terraform - Terragrunt 自动应用
- javascript - 我想生成直到 3 的随机数,但我不想重复它们。我怎样才能让它工作?
- python - 为什么当我在下面的代码中调用 del 函数时,对象没有被删除和重新实例化?
- hadoop - 如何在 oozie 协调器的输入事件中获取每月的第一天?
- node.js - 无法在反应中显示网络摄像头流