如何获取SQL Server中两个日期之间的月份和年份列表

时间:2016-09-30 01:23:40

标签: sql-server date

我必须在我的日期之间获得月份和年份的列表。目前,它仅返回具有与之关联的数据的日期的月份和年份。

例如我的日期介于:'8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016'

之间

仅打印出:2016年5月,2016年6月,2016年7月,2016年8月,2016年9月,

我希望它能打印出所有月份和年份。这是我的SQL查询:

select d.id_base as case_id, 
    c.C_LAST_ACTION AS Docketed,
    c.C_CASE_TYPE AS caseType,
    ct.C_NAME As caseName, 
    ct.C_DESCRIPTION AS caseNameDescription,
   case when d.c_mod_decision_id is not null then '' else  DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date)  end as display
from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id 
where cast(d.c_issue_date AS date) BETWEEN '8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016') 

3 个答案:

答案 0 :(得分:1)

首先,创建一个numbers table

CREATE TABLE Numbers(N INT)

insert into Numbers(N)
select top 1000000 row_number() over(order by t1.number) as N
from   master..spt_values t1 
       cross join master..spt_values t2

然后使用DATEADD列出所需值之间的日期,例如

declare @iniDate as date     
set @iniDate='20150801'  

select dateadd(MONTH,N,@iniDate) dates
from Numbers 
where N<15 order by N

这些返回日期从@iniDate到15个月后

编辑:试试这个,我现在没有sql

select datename(mm, dateadd(MONTH,N,@iniDate))+datename(yyyy ,dateadd(MONTH,N,@iniDate)) display
from ( select top 15row_number() over(order by t1.number) as N
from   master..spt_values t1 
       cross join master..spt_values t2) numbers right join (

    select d.id_base as case_id, 
        c.C_LAST_ACTION AS Docketed,
        c.C_CASE_TYPE AS caseType,
        ct.C_NAME As caseName, 
        ct.C_DESCRIPTION AS caseNameDescription,
       case when d.c_mod_decision_id is not null then '' else  DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date)  end as display
    from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id 
    where cast(d.c_issue_date AS date) BETWEEN '8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016') 
    sql-server
    ) qq
on datename(mm, dateadd(MONTH,N,@iniDate))+datename(yyyy ,dateadd(MONTH,N,@iniDate)) = qq.display

where N<15 order by N

答案 1 :(得分:0)

你需要在表之间加入主键,我没有看到带有该语法的between语句。所以我建议尝试以下方法:

SELECT d.id_base as case_id, c.C_LAST_ACTION AS 'Docketed',c.C_CASE_TYPE AScaseType,ct.C_NAME As 'caseName', ct.C_DESCRIPTION AS 'caseNameDescription'
,CASE 
WHEN d.c_mod_decision_id is not null THEN '' AS 'null_val'
ELSE  CONCAT(YEAR(d.c_issue_dateDATENAME), MONTH(d.c_issue_date))
END AS 'display'

FROM t_case_decision d INNER JOIN T_CASE_INPUT c on c.id = d.id_base 
INNER JOIN T_CASE_TYPE ct on c.id = ct.id 

WHERE CONVERT(DATE,d.c_issue_date) BETWEEN '08/01/2015' 
AND '08/01/2016';

我希望这有助于或指出正确的方向:)

答案 2 :(得分:0)

如果我理解您要完成的任务,那么递归CTE可能会有所帮助。以下是您可以做的快速示例。 CTE将扩展为日期列表,您可以将其用作查询的基础。

可能需要调整TargetData CTE的内容,因为我没有全面了解您的数据结构。

DECLARE @startDate DATE = '1/1/2015';
DECLARE @endDate DATE = '7/31/2016';

-- Recursive CTE to generate a list of months within the date range:
WITH Months AS (
    SELECT CONVERT(DATE, DATEADD(D, -(DAY(@startDate)) + 1, @startDate)) [MonthDate]

    UNION ALL

    SELECT DATEADD(M, 1, MonthDate)
    FROM Months
    WHERE MonthDate <= DATEADD(M, -1, @endDate)
),
TargetData AS (
    -- This is a slightly modified version of the original query:
    select
        d.id_base as case_id, 
        c.C_LAST_ACTION AS Docketed,
        c.C_CASE_TYPE AS caseType,
        ct.C_NAME As caseName, 
        ct.C_DESCRIPTION AS caseNameDescription,
        case when d.c_mod_decision_id is not null then '' else  DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date)  end as display,
        -- Return the "MonthDate" so that it can be left joined to the Months table:
        DATEADD(D, -(DAY(d.c_issue_date)) + 1, d.c_issue_date) [MonthDate]
    from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id 
    where cast(d.c_issue_date AS date) BETWEEN @startDate AND @endDate
)
SELECT
    m.MonthDate,
    DATENAME(mm, m.MonthDate) + DATENAME(yyyy, m.MonthDate),
    td.*
FROM Months m
    LEFT JOIN TargetData td ON td.MonthDate = m.MonthDate;