我有一张包含客户ID,名称房间号码,开始日期和结束日期的表格。我想在开始日期和结束日期之间创建一个日期列表(每日细分),但希望它看起来像我在excel中通过以下链接模拟的tbale:
我用过
Logic ColumN中的 =IF(TEXT(D2,"DD/MM/YYYY")=TEXT(E2,"DD/MM/YYYY"),"Same",IF(F2=DATE(YEAR(D2),MONTH(D2),DAY(D2)),"Start",IF(F2=DATE(YEAR(E2),MONTH(E2),DAY(E2)),"End","Between")))
公式
我曾尝试将以下一点SQL插入到我的查询中,但似乎不能让它做我想做的事情:
declare @fromdate dateTIME
set @fromdate= '1/1/2017'(Wanted to used Column Startdate)
declare @todate dateTIME = getdate()-1(Wanted used Column Enddate)
;with CTE AS
(SELECT @fromdate AS RESULT
UNION ALL
SELECT RESULT + 1 FROM CTE WHERE RESULT<=@todate
)
SELECT Result,1 as Count FROM CTE OPTION(MAXRECURSION 0)
感谢任何帮助。
答案 0 :(得分:0)
目前还不完全清楚查询中的内容是什么。如果它需要每天获取行,最简单的方法是在数据库中准备好日期表。您可以在视图中引用此日期表。请参阅下面我在多个项目中使用的示例。
CREATE PROCEDURE [dbo].[FillDateTable](@StartDate DATE, @EndDate DATE) AS
BEGIN
TRUNCATE TABLE dbo.DateTable;
WITH CTERecursive AS (
SELECT @StartDate AS 'CalendarDate'
UNION ALL
SELECT DATEADD(DAY,1,CalendarDate) AS 'CalendarDate'
FROM CTERecursive
WHERE DATEADD(DAY,1,CalendarDate)<=@EndDate
), TotalCalendar AS (
SELECT CalendarDate
, DAY(CalendarDate) AS 'Day'
, MONTH(CalendarDate) AS 'Month'
, YEAR(CalendarDate) AS 'Year'
, DATEADD(DAY,-DATEPART(WEEKDAY,CalendarDate)+1,CalendarDate) AS 'FirstDayOfWeek'
, DATEADD(DAY,6,DATEADD(DAY,-DATEPART(WEEKDAY,CalendarDate)+1,CalendarDate)) AS 'LastDayOfWeek'
FROM CTERecursive
)
INSERT INTO dbo.DateTable ([CalendarDate], [Day], [Month], [Year], [FirstDayOfWeek], [LastDayOfWeek], [NewWeek])
SELECT *
, NewWeek=CASE WHEN CalendarDate=FirstDayOfWeek THEN 1 ELSE 0 END
FROM TotalCalendar
OPTION (MAXRECURSION 0)
END
此外,在您的CTE中使用DATEADD而不是+1是明智的。
DECLARE @fromdate DATE
SET @fromdate=CONVERT(DATE,'20170101',112)
DECLARE @todate DATE=GETDATE()-1
;
WITH CTE AS
(SELECT @fromdate AS RESULT
UNION ALL
SELECT DATEADD(DAY,1,RESULT) FROM CTE WHERE RESULT<=@todate
)
SELECT [DateInclusive]=RESULT
,1 as Count FROM CTE OPTION(MAXRECURSION 0)
更新:我假设您有一张表,其中包含Id,Room,Name,Start和Enddate。您的查询可以按如下方式构建,产生类似于Excel模型的概述:
DECLARE @Bookings TABLE ([Id] VARCHAR(30), [Room] INT, [Name] VARCHAR(255), [Startdate] DATE, [Enddate] DATE)
INSERT INTO @Bookings VALUES ('V123789',8,'H. Brown','20170201','20170315'),('V555589',1,'J. Frost','20170205','20170420');
WITH CTE AS
(SELECT Id, [Startdate] AS InclusiveDate FROM @Bookings
UNION ALL
SELECT Id, DATEADD(DAY,1,InclusiveDate) FROM CTE WHERE InclusiveDate < (SELECT Enddate FROM @Bookings WHERE Id=CTE.Id)
)
SELECT B.[Id], B.[Room], B.[Name], B.[Startdate], B.[Enddate], CTE.[InclusiveDate]
, CASE WHEN CTE.[InclusiveDate]=B.[Startdate] THEN 'Start'
WHEN CTE.[InclusiveDate]=B.[Enddate] THEN 'End'
WHEN CTE.[InclusiveDate]>B.[Startdate] AND CTE.[InclusiveDate]<B.[Enddate] THEN 'Between' END AS Logic
FROM CTE
JOIN @Bookings B on B.Id=CTE.[Id]
ORDER BY B.[Id], CTE.[InclusiveDate] ASC
OPTION(MAXRECURSION 0)