我有时间表数据,需要按日期范围创建报告。我需要为每个人每一天每一行,每种时间类型。如果在给定的日期没有针对该时间类型的条目,我想要空数据。我尝试了左联接,但似乎没有用。交叉联接将提供错误的数据。
我拥有的Person
表格是表格(personID, Name
),TimeLog
表格(TimeLogID, StartDate, EndDate, TimeLogTypeID
)和TimeLogType
表格(TimeLogTypeID, PersonID, Description, DeletedInd
)
我在结果集中所能得到的就是带有数据的行,而不是每个数据的空行 TimeLogType
这是我到目前为止的内容:
DECLARE
@startDate DATE,
@endDate DATE
SET @startDate = '2014-05-01'
SET @endDate = '2014-05-30'
SELECT
CONVERT(DATE, TimeLog.StartDateTime, 101) AS TimeLogDay,
SUM(dbo.fnCalculateHoursAsDecimal(TimeLog.StartDateTime, TimeLog.EndDateTime)) AS Hours,
TimeLog.PersonID,
TimeLog.TimeLogTypeID
INTO #HourTable
FROM
TimeLog
WHERE
TimeLog.StartDateTime BETWEEN @startDate AND @endDate
GROUP BY
CONVERT(DATE, TimeLog.StartDateTime, 101),
TimeLog.TimeLogTypeID,
TimeLog.PersonID
SELECT
TimeLogType.Description,
#HourTable.*
FROM
TimeLogType LEFT JOIN
#HourTable ON TimeLogType.TimeLogTypeID = #HourTable.TimeLogTypeID
WHERE
ISNULL(TimeLogType.DeletedInd, 0) = 0
ORDER BY
PersonID, TimeLogDay, TimeLogType.TimeLogTypeID
数据如下所示:
TimeLogType:
1,可结算
2,不可结算
人:
1,比利
2,汤姆
TimeLog:
1,1,2014-05-01 8点00分00秒,2014-05-01 9时00分00秒,1,0
2,1,2014-05-01 9时00分00秒,2014-05- 01 10:00:00,1,0 3,2,2014-05-01 08:
00
:00,2014-05-01 08:30:00,2,0 4,2,2014-05-01 08: 30:00,2014-05-01 09:00:
00,1,0 5,1,2014-05-02 08:00:00,2014-05-02 09:00:00,2,0
预期输出:(按人,日期,时间日志类型排序)
天,人,账单类型,总工时
2014-05-01,比利,可计费,2.0
2014-05-01,比利,不可计费,空值
2014-05- 02,Billy,Billiable,1.0
2014-05-02,Billy,Non-Billiable,NULL
等...
2014-05-01,Tom,Billiable,0.5
2014-05-01,Tom,Non-Billiable,0.5
等..
阅读戈登的答案后,这就是我的想法。我逐步创建了它,以便可以看到发生了什么。我创建的日期不包含master..spt_values表。我还创建了一个临时人员表,因此我可以只选择具有TimeLogRecord的人员,然后重新使用它为最终选择输入详细信息。让我知道是否有任何方法可以使运行速度更快。
DECLARE
@startDate DATE,
@endDate DATE
SET @startDate = '2014-01-01'
SET @endDate = '2014-01-31'
-- create day rows --
;WITH dates(TimeLogDay) AS
(
SELECT @startDate AS TimeLogDay
UNION ALL
SELECT DATEADD(d, 1, TimeLogDay)
FROM dates
WHERE TimeLogDay < @enddate
)
-- create a type row for each day --
SELECT
dates.TimeLogDay,
tlt.TimeLogTypeID
INTO #TypeDate
FROM
dates CROSS JOIN
(SELECT
TimeLogType.TimeLogTypeID
FROM
TimeLogType
WHERE
ISNULL(TimeLogType.DeletedInd, 0) = 0
) AS TLT
-- create a temp person table for referance later ---
SELECT * INTO #person FROM Person WHERE Person.personID IN
(SELECT Timelog.PersonID FROM TimeLog WHERE TimeLog.StartDateTime BETWEEN @startDate AND @endDate)
-- sum up the log times and tie in the date/type rows --
SELECT
#TypeDate.TimeLogDay,
#TypeDate.TimeLogTypeID,
#person.PersonID,
SUM(dbo.fnCalculateHoursAsDecimal(TimeLog.StartDateTime, TimeLog.EndDateTime)) AS Hours
INTO #Hours
FROM
#person CROSS JOIN
#TypeDate LEFT JOIN
TimeLog ON
TimeLog.PersonID = #person.PersonID AND
TimeLog.TimeLogTypeID = #TypeDate.TimeLogTypeID AND
#TypeDate.TimeLogDay = CONVERT(DATE, TimeLog.StartDateTime, 101)
GROUP BY
#TypeDate.TimeLogDay,
#TypeDate.TimeLogTypeID,
#person.PersonID
-- now tie in the details to complete --
SELECT
#Hours.TimeLogDay,
TimeLogType.Description,
Person.LastName,
Person.FirstName,
#Hours.Hours
FROM
#Hours LEFT JOIN
Person ON #Hours.PersonID = Person.PersonID LEFT JOIN
TimeLogType ON #Hours.TimeLogTypeID = TimeLogType.TimeLogTypeID
ORDER BY
Person.FirstName,
Person.LastName,
#Hours.TimeLogDay,
TimeLogType.SortOrder
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句