代码之家  ›  专栏  ›  技术社区  ›  Nathan Koop

SQL以获取日期列表以及前后的天数(不重复)

  •  3
  • Nathan Koop  · 技术社区  · 14 年前

    我需要显示一个日期列表,我有一个表

    SELECT mydate AS MyDate, 1 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;
    

    2010年1月1日-1
    2010年1月2日-1
    2010年1月10日-1

    没问题。但是,我现在需要用不同的日期类型显示之前的日期和之后的日期。

    2009年12月31日-2
    2010年1月1日-1
    2010年1月2日-1
    2010年1月3日-2日
    2010年1月9日-2
    2010年1月10日-1
    2010年1月11日-2

    我想我需要一个工会

    SELECT MyDate, DateType
    FROM (
        SELECT mydate - 1 AS MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    
        UNION
    
        SELECT mydate + 1 AS MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    
        UNION
    
        SELECT mydate AS MyDate, 1 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    ) AS myCombinedDateTable
    

    但这包括原始日期的副本。

    2009年12月31日-2
    2010年1月1日-2日
    2010年1月1日-1
    2010年1月2日-2日
    2010年1月2日-1
    2010年1月3日-2日
    2010年1月9日-2
    2010年1月10日-1
    2010年1月11日-2

    如何才能最好地删除这些副本?我正在考虑一张临时桌子,但不确定这是否是最好的方法。

    在我看来,当我三次运行同一个查询时,它可能会带来性能问题。

    处理此请求的最佳方法是什么?

    3 回复  |  直到 14 年前
        1
  •  1
  •   Nathan Koop    14 年前

    虽然你已经接受了这个方案,但我还是给你这个方案作为参考:

    SELECT MyDate, Min(DateType)
    From
    (
      SELECT MyDate + T1.RecordType AS MyDate, T1.DateType
      FROM
      (
        Select 1 AS RecordType, 2 AS DateType
        Union ALL
        Select 0 AS RecordType, 1 AS DateType
        Union ALL
        Select -1 AS RecordType, 2 AS DateType
      ) AS T1
      CROSS JOIN myTable
      Where myTable.fkId = @MyFkId
    ) AS CombinedTable
    Group By MyDate
    

    这个解决方案的优点是,mytable只被查询一次,当前的情况是我们对fkid有一个过滤器,所以现在性能不重要,但是如果我们必须评估复杂的查询,那么这个技术对于union可以很好地工作。

        2
  •  4
  •   D'Arcy Rittich    14 年前

    这应该对你有用:

    SELECT MyDate, min(DateType) as DateType
    FROM (
        SELECT mydate - 1 AS MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    
        UNION
    
        SELECT mydate + 1 AS MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    
        UNION ALL
    
        SELECT mydate AS MyDate, 1 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId;
    ) AS myCombinedDateTable
    group by MyDate
    

    注:我换了第二个 UNION UNION ALL 为了获得更好的性能;最后一个子查询与前两个子查询永远不会有重复项,因为 DateType 前两个总是2,后两个总是1 联合 ED查询。

        3
  •  0
  •   CResults    14 年前

    试过了,就成功了。请注意,我使用dateadd使它与本地的sql副本(sql2008)一起工作。

    SELECT MyDate, Min(DateType)
    FROM (
        SELECT DATEADD(DAY,-1,mydate) AS MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId
    
        UNION
    
        SELECT DATEADD(DAY,1,mydate) as MyDate, 2 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId
    
        UNION
    
        SELECT mydate AS MyDate, 1 AS DateType
        FROM myTable
        WHERE myTable.fkId = @MyFkId
    ) AS myCombinedDateTable
    group by Mydate