我有两个变量start
和end
,其中包含日期值,例如2018-05-01
和2019-02-28
。我想创建一个包含每个月之间的表。结果表应如下所示。
Month Year
5 2018
6 2018
7 2018
8 2018
9 2018
10 2018
11 2018
12 2018
01 2019
02 2019
如何实现?
答案 0 :(得分:1)
这是我在MS-SQL中使用的表函数
func readerDidCancel(_ reader: QRCodeReaderViewController) {
dismiss(animated: true, completion: nil)
present(ClockInOrOutViewController(), animated: true, completion: nil)
}
然后调用这样的内容:
CREATE FUNCTION [dbo].[GetSequencedMonthSplit](@StartDate DATETIME, @EndDate DATETIME)
RETURNS @Results TABLE
(
ID INT IDENTITY(1,1)
, YearValue INT
, MonthValue INT
, MonthName NVARCHAR(50)
)
AS
BEGIN
IF @StartDate IS NULL OR @EndDate IS NULL
BEGIN
/*GET THE CURRENT CALENDAR YEAR*/
SELECT
@StartDate = DATEFROMPARTS(year(getdate()),1,1)
,@EndDate = DATEFROMPARTS(year(getdate()),12,31)
END
WHILE @StartDate < @EndDate
BEGIN
INSERT INTO @Results (YearValue, MonthValue, MonthName)
SELECT
DATEPART(year, @StartDate)
, DATEPART(month, @StartDate)
, DATENAME(month,@StartDate)
SET @StartDate = DATEADD(month, 1, @StartDate)
END
RETURN
END
应为您提供所需的东西。
答案 1 :(得分:0)
您的评论中的Jeroen Mostert的解决方案是最好的选择。 David的解决方案将为您提供所需的东西,但他的功能是您想要的Multi-statement
内联表值函数和inline
表值函数for the reasons outlined here。即使只处理少量的行,多语句也会使使用调用它们的查询的性能恶化。
要创建inline
表值函数(iTVF),您只需了解tally tables的工作方式。这样做会改变您的职业。您要查找的iTVF版本如下所示:
CREATE FUNCTION dbo.MonthYearRange (@startdate DATE, @enddate DATE)
RETURNS TABLE WITH SCHEMABINDING AS RETURN
WITH L1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) x(N)),
iTally(N) AS
( SELECT 0 UNION ALL
SELECT TOP (DATEDIFF(MONTH,@startdate,@enddate)) ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM L1 a CROSS JOIN L1 b CROSS JOIN L1 c)
SELECT [Month] = MONTH(d.dt),
[Year] = YEAR(d.dt)
FROM iTally i
CROSS APPLY (VALUES (DATEADD(MONTH,i.N,@startdate))) d(dt);
此查询:
DECLARE @startdate DATE = '2018-05-01',
@enddate DATE = '2019-02-28';
返回:
Month Year
----------- -----------
5 2018
6 2018
7 2018
8 2018
9 2018
10 2018
11 2018
12 2018
1 2019
2 2019