我必须在我的日期之间获得月份和年份的列表。目前,它仅返回具有与之关联的数据的日期的月份和年份。
例如我的日期介于:'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')
答案 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;