使用以下数据:
Item Record StatType statStart statEnd
Plow 8860 Operational 2017-08-29 16:59:48.907 2017-11-06 15:35:15.290
Plow 8859 Inspection 2017-08-29 16:56:59.460 2017-08-29 16:58:48.907
Plow 8830 Operational 2017-08-23 18:38:45.530 2017-08-29 16:55:59.460
Plow 8730 Inspection 2017-07-31 15:34:10.387 2017-08-23 18:37:45.530
Plow 8625 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387
Plow 8615 Inspection 2017-07-17 09:22:58.127 2017-07-17 11:21:00.000
Plow 8406 Operational 2017-06-05 14:42:32.837 2017-07-17 09:21:58.127
Plow 8399 Inspection 2017-06-02 17:02:55.107 2017-06-05 14:41:32.837
Plow 8332 Operational 2017-05-23 09:30:37.707 2017-06-02 17:01:55.107
我需要在@startDate和@endDate之间每天中午找到犁的StatType。您会注意到记录#8615的statStart为9:22 am,statEnd为11:21 am。此记录不应作为结果集的一部分返回。此外,由于statType在记录8406和&之间不会改变。 8625由于省略了8615,我需要提前执行状态以准确计算DATEDIFF(或StatusDays)。
我尝试了很多不同的方法,包括LAG / LEAD和CTE的组合,但是,因为一条记录8615不符合中午标准,它会及时创建一个“GAP”,对我的SSRS图表产生负面影响。 8406在9:21结束,但8625直到11:22才开始。
我希望有人可以帮我创建我的查询部分,这样我就可以在两个日期参数之间的中午获取状态。
谢谢!
更新:使用Sam cd的解决方案,我得到以下结果(如下)。请注意,当加入CTE建议的日期时,结果集省略了记录8615,记录8406的statEnd比记录8625的statStart小1.5小时。这1.5小时的差距是记录8615通常的位置。这个差距在我的SSRS条形图中引起了一个问题,因为我需要操作的状态流过差距,并且StatusDays一直读到'56'(42 + 14)直到记录8730.
更新结果集:
Item Record statusDate statType statStart statEnd StatusDays
Plow 8406 2017-07-15 12:00:00.000 Operational 2017-06-05 14:42:32.837 2017-07-17 09:21:58.127 42
Plow 8406 2017-07-16 12:00:00.000 Operational 2017-06-05 14:42:32.837 2017-07-17 09:21:58.127 42
Plow 8625 2017-07-17 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-18 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-19 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-20 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-21 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-22 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-23 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-24 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-25 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-26 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-27 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-28 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-29 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-30 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-31 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8730 2017-08-01 12:00:00.000 Inspection 2017-07-31 15:34:10.387 2017-08-23 18:37:45.530 23
Plow 8730 2017-08-02 12:00:00.000 Inspection 2017-07-31 15:34:10.387 2017-08-23 18:37:45.530 23
更新2 :我的查询(我不知道这是否会有所帮助..)
DECLARE @StartDate datetime = '07/15/2017'
DECLARE @EndDate datetime = '07/31/2017'
DECLARE @item varchar (10) = 'Plow'
;WITH CTE_Data AS
(
SELECT
item
,record
,statType
,statStart
,CASE WHEN DATEADD(minute, - 1, LEAD(t1.statStart) OVER (PARTITION BY t1.item ORDER BY t1.statStart)) IS NULL THEN GETDATE()
ELSE DATEADD(minute, - 1, LEAD(t1.statStart) OVER (PARTITION BY t1.item ORDER BY t1.statStart)) END as statEnd
FROM table1 t1
INNER JOIN table2 t2 ON t1.record = t2.record
AND t1.active = 'Y'
AND t1.item = @item
),
cte_Dates AS
(
select dateadd(hour,12,@startDate) AS StatusDate
union ALL
select dateadd(day,1,StatusDate)
from cte_Dates
where StatusDate < dateadd(day,1,@endDate)
) ,
CTE_Sample as
(
SELECT
cted.statusdate
,Item
,Record
,StatType
,statStart
,statEnd
,CASE
WHEN DATEDIFF(day, statStart, statEnd) IS NULL
THEN DATEDIFF(day, statStart, GETDATE())
WHEN DATEDIFF(day, statStart, statEnd) = 0
THEN 1 ELSE DATEDIFF(day, statStart, statEnd)
END as StatusDays
FROM CTE_Data
LEFT OUTER JOIN cte_Dates cted ON cted.statusDate >= statStart AND cted.statusDate <= statEnd
WHERE cted.statusdate between @StartDate and @EndDate
)
SELECT Item, Record, statusDate, statType, statStart, statEnd, StatusDays FROM CTE_Sample
WHERE statusdate between @StartDate and @EndDate
如您所见,我使用LEAD函数“创建”statEnd,当我将其加入CTE_Dates时,会添加StatusDate列并为日期范围的每一天创建一条记录 - 但差距仍然存在在8406和840之间8625。
Item Record statusDate statType statStart statEnd StatusDays
Plow 8406 2017-07-15 12:00:00.000 Operational 2017-06-05 14:42:32.837 2017-07-17 09:21:58.127 42
Plow 8406 2017-07-16 12:00:00.000 Operational 2017-06-05 14:42:32.837 2017-07-17 09:21:58.127 42
Plow 8625 2017-07-17 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-18 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-19 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-20 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-21 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-22 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-23 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-24 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-25 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-26 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-27 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-28 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-29 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
Plow 8625 2017-07-30 12:00:00.000 Operational 2017-07-17 11:22:00.000 2017-07-31 15:33:10.387 14
答案 0 :(得分:0)
使用递归CTE创建日期表:
声明@startDate datetime ='2017-11-01' ,@ enddate datetime ='2017-11-30'
public function(MyExampleRequest $request)
然后加入您的表格以获取状态
;with dts as (
select dateadd(hour,12,@startDate) noon
union ALL
select dateadd(day,1,noon)
from dts
where noon < dateadd(day,1,@endDate)
)
答案 1 :(得分:0)
我认为您正在尝试做类似下面的事情。我使用CTE ...在其中我添加一个索引号(ROW_NUMBER)并按statStart对行进行排序。我在WHERE子句中排除了非中午值。要消除“差距”,您可以选择下一个ROW_NUMBER的startstat。我没有使用原始的终结时间值。
DECLARE @temp TABLE (Item varchar(100), Record int, StatType varchar(100), statStart datetime, statEnd datetime)
INSERT INTO @temp VALUES
('Plow', 8860, 'Operational', '2017-08-29 16:59:48.907', '2017-11-06 15:35:15.290')
,('Plow', 8859, 'Inspection', '2017-08-29 16:56:59.460', '2017-08-29 16:58:48.907')
,('Plow', 8830, 'Operational', '2017-08-23 18:38:45.530', '2017-08-29 16:55:59.460')
,('Plow', 8730, 'Inspection', '2017-07-31 15:34:10.387', '2017-08-23 18:37:45.530')
,('Plow', 8625, 'Operational', '2017-07-17 11:22:00.000', '2017-07-31 15:33:10.387')
,('Plow', 8615, 'Inspection', '2017-07-17 09:22:58.127', '2017-07-17 11:21:00.000')
,('Plow', 8406, 'Operational', '2017-06-05 14:42:32.837', '2017-07-17 09:21:58.127')
,('Plow', 8399, 'Inspection', '2017-06-02 17:02:55.107', '2017-06-05 14:41:32.837')
,('Plow', 8332, 'Operational', '2017-05-23 09:30:37.707', '2017-06-02 17:01:55.107')
DECLARE @startDate datetime = '2017-07-15 12:00:00'
,@endDate datetime = '2017-08-03 12:00:00';
WITH cte AS
(
SELECT ROW_NUMBER() OVER(ORDER BY statStart) [idval]
,T.*
FROM @temp T --your tablename
WHERE (CAST(statStart as time) < '12:00:00' AND CAST(statEnd as time) > '12:00:00'
OR
DATEDIFF(HOUR, statStart, statEnd) >= 24
)
)
,
cte2 AS
(
SELECT @startDate as dateval
UNION ALL
SELECT DATEADD(DAY, 1, dateval)
FROM cte2
WHERE dateval < @endDate
)
SELECT C2.dateval, dT.Item, dT.Record, dT.StatType, dT.statStart, dT.StatEnd
,DATEDIFF(DAY, statStart, StatEnd) [StatusDays]
FROM (
SELECT C.idval, C.Item, C.Record, C.StatType, C.statStart --, C.statEnd --this has the 'gap'
,COALESCE((SELECT MAX(C2.statStart) FROM cte C2 WHERE C2.idval > C.idval AND C2.StatType = C.StatType), C.statEnd) AS [StatEnd]
FROM cte C
) AS dT
INNER JOIN cte2 C2 ON C2.dateval between dT.statStart AND dT.[StatEnd]