我有一个SQL语句,如果每个小时都需要我的SUMmations(SQL Server 2008),它可以很好地工作。 DATEPART(HOUR, DATE_TIME)
为我做了所有精彩的工作。
SELECT SUM(case STATION_ID when 'S-WELDCHK' then 1 else 0 end) as WELDCHK
,SUM(case STATION_ID when 'S-GLUING-OUT-OK' then 1 else 0 end) as GLUING
,SUM(case STATION_ID when 'S-GLUING-OUT-NOK' then 1 else 0 end) as 'GLUING-NOK'
,SUM(case STATION_ID when 'S-ULTRAWELD-OUT-OK' then 1 else 0 end) as ULTRAWELD
,SUM(case STATION_ID when 'S-ULTRAWELD-OUT-NOK' then 1 else 0 end) as 'ULTRAWELD-NOK'
,SUM(case STATION_ID when 'S-BOLTFAST-OUT-OK' then 1 else 0 end) as BOLTFAST
,SUM(case STATION_ID when 'S-BOLTFAST-OUT-NOK' then 1 else 0 end) as 'BOLTFAST-NOK'
,SUM(case STATION_ID when 'S-MAPVISION-OUT-OK' then 1 else 0 end) as MAPVISION
,SUM(case STATION_ID when 'S-MAPVISION-OUT-NOK' then 1 else 0 end) as 'MAPVISION-NOK'
,SUM(case STATION_ID when 'S-CHECKFIX-OUT-OK' then 1 else 0 end) as CHECKFIX
,SUM(case STATION_ID when 'S-CHECKFIX-OUT-NOK' then 1 else 0 end) as 'CHECKFIX-NOK'
,SUM(case STATION_ID when 'S-EJOT-OUT-OK' then 1 else 0 end) as EJOT
,SUM(case STATION_ID when 'S-EJOT-OUT-NOK' then 1 else 0 end) as 'EJOT-NOK'
FROM [dbFactory].[dbo].[Events]
where (DATEPART(yy,DATE_TIME) = 2014
AND DATEPART(mm,DATE_TIME) = 2
AND DATEPART(dd,DATE_TIME)= 5)
GROUP BY
DATEPART(HOUR, DATE_TIME)
with rollup
我真正想要的是我在临时表中有不规则时间段的SUMS(为简洁而截断)
Start Finish
06:00:00.000 06:30:00.000
06:30:00.000 07:30:00.000
07:30:00.000 08:30:00.000
08:30:00.000 09:30:00.000
09:30:00.000 10:00:00.000
10:00:00.000 10:30:00.000
10:30:00.000 11:30:00.000
11:30:00.000 12:30:00.000
12:30:00.000 13:30:00.000
13:30:00.000 14:00:00.000
网站上的任何建议或我应该阅读的内容以解决此问题。应该有一个工具来汇总用户定义的函数,也许我可以通过START和FINISH期间以及事务的DATE_TIME
。
答案 0 :(得分:1)
使用between
inner join Periods on events.DATE_TIME between Periods.Start and Periods.End
并按期间表中的字段分组
group by Periods.Start
NB。如果时间段恰好在两个时期之间的边界上,您需要决定会发生什么。您可能需要调整期间,或使用>加入和< =
您可能还想查看PIVOT
而不是使用SUM(CASE...
构造。
答案 1 :(得分:0)
这就是我获得工作解决方案的方式。它不漂亮或高效。这是目前每24小时运行一次的报告的一部分。
获取数据的存储过程
USE [dbFactory]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Create date: 20140225
-- Description: Used by a report to extract SUM values for various Factory stations
-- =============================================
ALTER PROCEDURE [dbo].[spRptFetchStationActivitySummationsWithGroupBy]
@Day DATETIME
AS
BEGIN
SET NOCOUNT ON;
DECLARE @START DATETIME;
DECLARE @FINISH DATETIME;
if @Day IS NULL
BEGIN
SET @DAY = GETDATE();
END
-- Subtract a day from the day passed in and set its time to 6am
DECLARE @ActualDay DATETIME = DATEADD(day,-1,DATEADD(HOUR,6,DATEADD(dd, 0, DATEDIFF(dd, 0, @DAY))));
DECLARE @dtTwentyFoursHoursLater DATETIME = DATEADD(HOUR,24,@ActualDay);
-- If a transaction time is exactly on 6:00 am we want to avoid counting it twice.
-- There are granularity issues on milliseconds
SET @dtTwentyFoursHoursLater = DATEADD(millisecond,-2,@dtTwentyFoursHoursLater);
-- SELECT @ActualDay,@dtTwentyFoursHoursLater
CREATE TABLE #LocalEvents(
[SERIAL_NUMBER] [nchar](20) NOT NULL,
[DATE_TIME] [datetime] NOT NULL,
[STATION_ID] [nchar](20) NOT NULL,
[SUCCESS] [char](1) NOT NULL,
[OVERRIDDEN] [char](1) NOT NULL,
[USER_NAME] [nchar](30) NOT NULL,
[EVENT_ID] [smallint] NOT NULL,
[EXTRA_INFO] [nchar](30) NOT NULL);
-- Stuff in the dummy entries which have one entry for each time frame from for the GROUP BY
INSERT INTO #LocalEvents([SERIAL_NUMBER],
[DATE_TIME],
[STATION_ID],
[SUCCESS],
[OVERRIDDEN],
[USER_NAME],
[EVENT_ID],
[EXTRA_INFO]
)
SELECT [SERIAL_NUMBER],
[DATE_TIME],
[STATION_ID],
[SUCCESS],
[OVERRIDDEN],
[USER_NAME],
[EVENT_ID],
[EXTRA_INFO]
FROM dbCCB.dbo.Events;
-- Stuff in the real events of the past 24 hours
INSERT INTO #LocalEvents([SERIAL_NUMBER],
[DATE_TIME],
[STATION_ID],
[SUCCESS],
[OVERRIDDEN],
[USER_NAME],
[EVENT_ID],
[EXTRA_INFO]
)
SELECT [SERIAL_NUMBER],
[DATE_TIME],
[STATION_ID],
[SUCCESS],
[OVERRIDDEN],
[USER_NAME],
[EVENT_ID],
[EXTRA_INFO]
FROM dbFactory.dbo.Events
WHERE DATE_TIME BETWEEN @ActualDay AND @dtTwentyFoursHoursLater;
-- The UDF returns the first two chars to show the order as is 01 to 30 for the time periods.
-- We chop them off (SUBSTRING) to provide the client with the start and end times of the time period.
SELECT SUBSTRING(dbo.fnReturnGroupWhenBetweenTimes( CONVERT(TIME,DATE_TIME)),4,200) as [Time]
,SUM(case STATION_ID when 'S-WELDCHK' then 1 else 0 end) as WELDCHK
,SUM(case STATION_ID when 'S-GLUING-OUT-OK' then 1 else 0 end) as GLUING
,SUM(case STATION_ID when 'S-GLUING-OUT-NOK' then 1 else 0 end) as 'GLUING-NOK'
,SUM(case STATION_ID when 'S-ULTRAWELD-OUT-OK' then 1 else 0 end) as ULTRAWELD
,SUM(case STATION_ID when 'S-ULTRAWELD-OUT-NOK' then 1 else 0 end) as 'ULTRAWELD-NOK'
,SUM(case STATION_ID when 'S-BOLTFAST-OUT-OK' then 1 else 0 end) as BOLTFAST
,SUM(case STATION_ID when 'S-BOLTFAST-OUT-NOK' then 1 else 0 end) as 'BOLTFAST-NOK'
,SUM(case STATION_ID when 'S-MAPVISION-OUT-OK' then 1 else 0 end) as MAPVISION
,SUM(case STATION_ID when 'S-MAPVISION-OUT-NOK' then 1 else 0 end) as 'MAPVISION-NOK'
,SUM(case STATION_ID when 'S-CHECKFIX-OUT-OK' then 1 else 0 end) as CHECKFIX
,SUM(case STATION_ID when 'S-CHECKFIX-OUT-NOK' then 1 else 0 end) as 'CHECKFIX-NOK'
,SUM(case STATION_ID when 'S-EJOT-OUT-OK' then 1 else 0 end) as EJOT
,SUM(case STATION_ID when 'S-EJOT-OUT-NOK' then 1 else 0 end) as 'EJOT-NOK'
/*,SUM(case STATION_ID when 'S-GENERIC' then 1 else 0 end) as 'GENERIC'*/
FROM #LocalEvents
GROUP BY dbo.fnReturnGroupWhenBetweenTimes(CONVERT(TIME,DATE_TIME))
WITH ROLLUP
DROP TABLE #LocalEvents;
END
将事件过滤为不规则变化的UDF。
USE [dbFactory]
GO
/****** Object: UserDefinedFunction [dbo].[fnReturnGroupWhenBetweenTimes] Script Date: 03/14/2014 12:44:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Create date: 20140226
-- Description: Returns a 1 if Date's TIME is between two dates
-- =============================================
ALTER FUNCTION [dbo].[fnReturnGroupWhenBetweenTimes]
(
-- Add the parameters for the function here
@TestTime TIME
)
RETURNS VARCHAR(20)
AS
BEGIN
-- Declare the return variable here
DECLARE @Result VARCHAR(20)
-- Add the T-SQL statements to compute the return value here
SELECT @Result =
case
when @TestTime between CONVERT(TIME,'06:00',14) and CONVERT(TIME,'06:30',14) then '01 06:00 06:30'
when @TestTime between CONVERT(TIME,'06:30',14) and CONVERT(TIME,'07:30',14) then '02 06:30 07:30'
when @TestTime between CONVERT(TIME,'07:30',14) and CONVERT(TIME,'08:30',14) then '03 07:30 08:30'
when @TestTime between CONVERT(TIME,'08:30',14) and CONVERT(TIME,'09:30',14) then '04 08:30 09:30'
when @TestTime between CONVERT(TIME,'09:30',14) and CONVERT(TIME,'10:00',14) then '05 09:30 10:00'
when @TestTime between CONVERT(TIME,'10:00',14) and CONVERT(TIME,'10:30',14) then '06 10:00 10:30'
when @TestTime between CONVERT(TIME,'10:30',14) and CONVERT(TIME,'11:30',14) then '07 10:30 11:30'
when @TestTime between CONVERT(TIME,'11:30',14) and CONVERT(TIME,'12:30',14) then '08 11:30 12:30'
when @TestTime between CONVERT(TIME,'12:30',14) and CONVERT(TIME,'13:30',14) then '09 12:30 13:30'
when @TestTime between CONVERT(TIME,'13:30',14) and CONVERT(TIME,'14:00',14) then '10 13:30 14:00'
when @TestTime between CONVERT(TIME,'14:00',14) and CONVERT(TIME,'14:30',14) then '11 14:00 14:30'
when @TestTime between CONVERT(TIME,'14:30',14) and CONVERT(TIME,'15:30',14) then '12 14:30 15:30'
when @TestTime between CONVERT(TIME,'15:30',14) and CONVERT(TIME,'16:30',14) then '13 15:30 16:30'
when @TestTime between CONVERT(TIME,'16:30',14) and CONVERT(TIME,'17:30',14) then '14 16:30 17:30'
when @TestTime between CONVERT(TIME,'17:30',14) and CONVERT(TIME,'18:00',14) then '15 17:30 18:00'
when @TestTime between CONVERT(TIME,'18:00',14) and CONVERT(TIME,'18:30',14) then '16 18:00 18:30'
when @TestTime between CONVERT(TIME,'18:30',14) and CONVERT(TIME,'19:30',14) then '17 18:30 19:30'
when @TestTime between CONVERT(TIME,'19:30',14) and CONVERT(TIME,'20:30',14) then '18 19:30 20:30'
when @TestTime between CONVERT(TIME,'20:30',14) and CONVERT(TIME,'21:30',14) then '19 20:30 21:30'
when @TestTime between CONVERT(TIME,'21:30',14) and CONVERT(TIME,'22:00',14) then '20 21:30 22:00'
when @TestTime between CONVERT(TIME,'22:00',14) and CONVERT(TIME,'22:30',14) then '21 22:00 22:30'
when @TestTime between CONVERT(TIME,'22:30',14) and CONVERT(TIME,'23:30',14) then '22 22:30 23:30'
when @TestTime between CONVERT(TIME,'23:30',14) and CONVERT(TIME,'23:59:59.998',14) then '23 23:30 00:30'
when @TestTime between CONVERT(TIME,'00:00',14) and CONVERT(TIME,'00:30',14) then '23 23:30 00:30'
when @TestTime between CONVERT(TIME,'00:30',14) and CONVERT(TIME,'01:30',14) then '24 00:30 01:30'
when @TestTime between CONVERT(TIME,'01:30',14) and CONVERT(TIME,'02:00',14) then '25 01:30 02:00'
when @TestTime between CONVERT(TIME,'02:00',14) and CONVERT(TIME,'02:30',14) then '26 02:00 02:30'
when @TestTime between CONVERT(TIME,'02:30',14) and CONVERT(TIME,'03:30',14) then '27 02:30 03:30'
when @TestTime between CONVERT(TIME,'03:30',14) and CONVERT(TIME,'04:30',14) then '28 03:30 04:30'
when @TestTime between CONVERT(TIME,'04:30',14) and CONVERT(TIME,'05:30',14) then '29 04:30 05:30'
when @TestTime between CONVERT(TIME,'05:30',14) and CONVERT(TIME,'06:00',14) then '30 05:30 06:00'
else 'UnKnown'
end
-- Return the result of the function
RETURN @Result
END
虚拟事件文件的内容减去几列重复数据
SERIAL_NUMBER DATE_TIME
DUMMY-SERIAL 2014-03-14 00:00:00.000
DUMMY-SERIAL 2014-03-14 01:00:00.000
DUMMY-SERIAL 2014-03-14 01:45:00.000
DUMMY-SERIAL 2014-03-14 02:15:00.000
DUMMY-SERIAL 2014-03-14 03:00:00.000
DUMMY-SERIAL 2014-03-14 04:00:00.000
DUMMY-SERIAL 2014-03-14 05:00:00.000
DUMMY-SERIAL 2014-03-14 05:45:00.000
DUMMY-SERIAL 2014-03-14 06:15:00.000
DUMMY-SERIAL 2014-03-14 07:00:00.000
DUMMY-SERIAL 2014-03-14 08:00:00.000
DUMMY-SERIAL 2014-03-14 09:00:00.000
DUMMY-SERIAL 2014-03-14 09:45:00.000
DUMMY-SERIAL 2014-03-14 10:15:00.000
DUMMY-SERIAL 2014-03-14 11:00:00.000
DUMMY-SERIAL 2014-03-14 12:00:00.000
DUMMY-SERIAL 2014-03-14 13:00:00.000
DUMMY-SERIAL 2014-03-14 13:45:00.000
DUMMY-SERIAL 2014-03-14 14:15:00.000
DUMMY-SERIAL 2014-03-14 15:00:00.000
DUMMY-SERIAL 2014-03-14 16:00:00.000
DUMMY-SERIAL 2014-03-14 17:00:00.000
DUMMY-SERIAL 2014-03-14 17:45:00.000
DUMMY-SERIAL 2014-03-14 18:15:00.000
DUMMY-SERIAL 2014-03-14 19:00:00.000
DUMMY-SERIAL 2014-03-14 20:00:00.000
DUMMY-SERIAL 2014-03-14 21:00:00.000
DUMMY-SERIAL 2014-03-14 21:45:00.000
DUMMY-SERIAL 2014-03-14 22:15:00.000
DUMMY-SERIAL 2014-03-14 23:00:00.000
感谢StackOverflow上的很多人提供的所有帮助。我读了很多问题和答案。 我现在必须在我的小组中了解FIRST_VALUE和LAST_VALUE,但要在2008年而不是2012年开始工作。它永远不会结束。