【问题标题】:Get months between two dates in TSQL获取SQL中两个日期之间的月份
【发布时间】:2015-01-13 20:18:29
【问题描述】:

我有一个返回以下内容的函数:

Title     Start          End
Task A    2015-01-02     2015-03-31
Task B    2015-02-12     2015-04-01
Task C    2014-11-01     2015-02-05
....

我想为每个月返回一列,如果它在开始和结束期间内返回 1,否则返回 0

 Title     Start          End          Jan   Feb  Mar  Apr  May  Jun  ....
 Task A    2015-01-02     2015-03-31    1     1    1    0    0    0
 Task B    2015-02-12     2015-04-01    0     1    1    1    0    0 
 Task C    2014-11-01     2015-02-05    1     1    0    0    0    0
 ....

有人知道怎么做吗?

【问题讨论】:

  • 你问的是所谓的 PIVOT 表。如果你稍微看一下,你就会找到答案。或者至少如何开始解决您的问题,然后如果您仍然无法发布您尝试过的查询,我们将帮助您解决它
  • 开始日期和结束日期是否可以在不同年份,或者您是否将查询限制为一年?
  • 这不是数据透视表。我没有诸如 Jan、Feb 等数据可供参考。只需根据开始和结束日期创建列
  • 当您创建月度数据时,您将拥有这些行进行透视。你必须做这一步,但如果你想把这些行变成列,你就必须旋转,别无他法。
  • 日期在一年内(本例中为 2015 年)。可以假设一月,二月...列是固定的

标签: sql sql-server tsql date datetime


【解决方案1】:

您可以使用基本的case 语句来做到这一点:

select title, start, end,
       (case when 1 between month(start) and month(end) then 1 else 0 end) as jan,
       (case when 2 between month(start) and month(end) then 1 else 0 end) as feb,
       . . .
       (case when 12 between month(start) and month(end) then 1 else 0 end) as dec
from table t;

注意:我将您的列名保留在查询中,即使有些是保留字并且应该转义(如果那是列的真实名称)。

另请注意,在您的示例数据中,第一个表和第二个表之间的日期会发生变化。

【讨论】:

    【解决方案2】:

    如果您只想检查 1 个日期,这将起作用。您应该能够调整此示例以满足您的需求。

    SELECT c.CreateDateUTC, DATEPART(MONTH, c.CreateDateUTC) 'MONTH',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 1 THEN 1 
        END 'JAN',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 2 THEN 1 
        END 'FEB',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 3 THEN 1 
        END 'MAR',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 4 THEN 1 
        END 'APR',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 5 THEN 1 
        END 'MAY',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 6 THEN 1 
        END 'JUN',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 7 THEN 1 
        END 'JUL',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 8 THEN 1 
        END 'AUG',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 9 THEN 1 
        END 'SEP',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 10 THEN 1 
        END 'OCT',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 11 THEN 1 
        END 'NOV',
        CASE DATEPART(MONTH, c.CreateDateUTC)
        WHEN 12 THEN 1 
        END 'DEC'   
    FROM dbo.Code c
    

    结果:

    【讨论】:

      【解决方案3】:

      要扩展,请确保检查 null,并且您可以使用 ISNULL(StartDate,GetDate()) 如果符合您的范围需求,它将在今天为您提供。

      select *, 
          case when StartDate is not null and EndDate is not null and 1 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jan,
          case when StartDate is not null and EndDate is not null and 2 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Feb,
          case when StartDate is not null and EndDate is not null and 3 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Mar,
          case when StartDate is not null and EndDate is not null and 4 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Apr,
          case when StartDate is not null and EndDate is not null and 5 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end May,
          case when StartDate is not null and EndDate is not null and 6 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jun,
          case when StartDate is not null and EndDate is not null and 7 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jul,
          case when StartDate is not null and EndDate is not null and 8 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Aug,
          case when StartDate is not null and EndDate is not null and 9 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Sep,
          case when StartDate is not null and EndDate is not null and 10 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Oct,
          case when StartDate is not null and EndDate is not null and 11 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Nov,
          case when StartDate is not null and EndDate is not null and 12 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Dec
      from Foo  
      

      【讨论】:

      • IS NOT NULL 检查在这里是多余的。当值为 NULL 时,它们不会被评估为介于日期之间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 2013-10-17
      • 1970-01-01
      相关资源
      最近更新 更多