SQL获取日期列表以及无重复日期之前和之后的日期

时间:2010-03-11 17:48:04

标签: sql sql-server sql-server-2005

我需要显示一个日期列表,我在表格中

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

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

  

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 个答案:

答案 0 :(得分:4)

这应该适合你:

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,前一个UNION查询为1。

答案 1 :(得分:1)

虽然您已接受解决方案,但我可以提供此解决方案供参考:

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 :(得分:0)

试过这个并且它有效。请注意我使用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