sql - 在 SQL 查询中组合拆分日期范围

标签 sql database ms-access database-design

我正在处理一个需要根据日期范围组合一些数据行的查询。这些行在所有数据值中都是重复的,除了日期范围被拆分。例如表数据可能看起来像

StudentID   StartDate   EndDate     Field1  Field2
1           9/3/2007    10/20/2007  3       True
1           10/21/2007  6/12/2008   3       True
2           10/10/2007  3/20/2008   4       False
3           9/3/2007    11/3/2007   8       True
3           12/15/2007  6/12/2008   8       True

查询结果应该合并了拆分日期范围。查询应该将日期范围组合在一起,间隔只有一天。如果间隔超过一天,则不应合并这些行。没有拆分日期范围的行应该保持不变。结果看起来像

StudentID   StartDate   EndDate     Field1  Field2
1           9/3/2007    6/12/2008   3       True
2           10/10/2007  3/20/2008   4       False
3           9/3/2007    11/3/2007   8       True
3           12/15/2007  6/12/2008   8       True

此查询的 SELECT 语句是什么?

最佳答案

下面的代码应该可以工作。我做了如下几个假设:日期范围没有重叠,任何字段中都没有 NULL 值,给定行的开始日期总是小于结束日期。如果您的数据不符合这些标准,您将需要调整此方法,但它应该为您指明正确的方向。

您可以使用子查询而不是 View ,但这可能很麻烦,所以我使用 View 来使代码更清晰。

CREATE VIEW dbo.StudentStartDates
AS
    SELECT
        S.StudentID,
        S.StartDate,
        S.Field1,
        S.Field2
    FROM
        dbo.Students S
    LEFT OUTER JOIN dbo.Students PREV ON
        PREV.StudentID = S.StudentID AND
        PREV.Field1 = S.Field1 AND
        PREV.Field2 = S.Field2 AND
        PREV.EndDate = DATEADD(dy, -1, S.StartDate)
    WHERE PREV.StudentID IS NULL
GO

CREATE VIEW dbo.StudentEndDates
AS
    SELECT
        S.StudentID,
        S.EndDate,
        S.Field1,
        S.Field2
    FROM
        dbo.Students S
    LEFT OUTER JOIN dbo.Students NEXT ON
        NEXT.StudentID = S.StudentID AND
        NEXT.Field1 = S.Field1 AND
        NEXT.Field2 = S.Field2 AND
        NEXT.StartDate = DATEADD(dy, 1, S.EndDate)
    WHERE NEXT.StudentID IS NULL
GO


SELECT
    SD.StudentID,
    SD.StartDate,
    ED.EndDate,
    SD.Field1,
    SD.Field2
FROM
    dbo.StudentStartDates SD
INNER JOIN dbo.StudentEndDates ED ON
    ED.StudentID = SD.StudentID AND
    ED.Field1 = SD.Field1 AND
    ED.Field2 = SD.Field2 AND
    ED.EndDate > SD.StartDate AND
    NOT EXISTS (SELECT * FROM dbo.StudentEndDates ED2 WHERE ED2.StudentID = SD.StudentID AND ED2.Field1 = SD.Field1 AND ED2.Field2 = SD.Field2 AND ED2.EndDate < ED.EndDate AND ED2.EndDate > SD.StartDate)
GO

关于sql - 在 SQL 查询中组合拆分日期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/140205/

相关文章:

sql - 选择另一个表的最小行

sql - 将随机数据插入到具有外键的表中

mysql - (MS Access MySQL) FROM 带别名的子查询

database - MS Access 中的 2GB 数据库限制是否影响链接表?

ms-access - 我在哪里放置 Access vba 代码以仅在物理打印时触发?

mysql - 如何将select语句的结果合并到不同数据库的其他表

mysql - 在 UPDATE 语句中使用 WHERE 子句

php - 读取数据库内容,转换为字符串

mysql - 在远程服务器上部署 MySQL 数据库

java - 如何为从抽象类继承的两个java类创建数据库