SQL计数不同的时间,相差30分钟
我试图找到一个SQL查询,它将计算至少30分钟不同的不同开始时间的数量 我有一些员工在一周内至少三次不同的时间开始工作时会获得积分,其中开始时间与其他开始时间至少不同30分钟。 例如:SQL计数不同的时间,相差30分钟,sql,datetime,time,count,distinct,Sql,Datetime,Time,Count,Distinct,我试图找到一个SQL查询,它将计算至少30分钟不同的不同开始时间的数量 我有一些员工在一周内至少三次不同的时间开始工作时会获得积分,其中开始时间与其他开始时间至少不同30分钟。 例如: select count(distinct (CONVERT(VARCHAR(10), starttime, 108))), employeecode from schedule where CONVERT(VARCHAR(10), starttime, 108) >= (select min(CONV
select count(distinct (CONVERT(VARCHAR(10), starttime, 108))), employeecode
from schedule
where CONVERT(VARCHAR(10), starttime, 108) >=
(select min(CONVERT(VARCHAR(10), dateadd (mi, 30, s2.starttime), 108)) from schedule s2)
group by starttime, employeecode
我希望得到一个结果与员工代码和不同的数字和不同的开始时间。例如,员工代码=9999,不同的开始时间=4
我一直在摸索这一点,但还没有得到一些工作
有人能告诉我哪里出了问题,或者一个合适的解决方案可以帮助我吗?
提前感谢您的帮助:)[更新:根据海报在对该答案的评论中对问题的澄清,我用该答案解决的问题显然不是海报试图解决的问题。我留下答案是为了展示其他问题的解决方案,而不是删除澄清问题陈述的评论] 将问题分为两部分:确定“唯一”(30分钟内)开始,然后计数。第一部分是我认为您遇到问题的部分。以下是一种方法:
SELECT employeecode, starttime FROM schedule S1
WHERE NOT EXISTS (SELECT * FROM schedule S2
WHERE S2.employeecode = S1.employeecode AND
S2.starttime > DATEADD(mi, -29, S1.starttime)
请注意:
- 我从原始查询中复制了日期数学逻辑,而不是查找语法
- 我想starttime是DATETIME
- 我用了29分钟,这样,如果开始时间相隔30分钟或更长时间,他们就可以得到奖金(如你的问题陈述中所述)。实际上,你应该用秒和减法(29*60)+59来计算日期。我的版本比你的问题陈述中指定的对员工更慷慨
- 您可以将此查询封装在视图或内部查询中,并执行以下操作(假设它是视图): 从“唯一开始”视图中选择employeecode,count() 其中开始时间介于(期初)和(期末)之间 按COUNT()>=3的员工代码分组
- notexists技术可能很慢,因此最好将查询限制在您感兴趣的时间段内
从SQL的角度来看,这个问题是它试图基于前一行创建数据,这意味着使用游标循环时间并将内容存储在变量中。我假设您的数据库产品是基于OP的SQL Server,但您没有提到版本。如果您使用SQL Server 2005及更高版本您可以尝试以下操作:
With StartTimes As
(
Select StartDateTime
, Row_Number() Over( Order By StartDateTime ) As Seq
, DatePart(hh, StartDateTime) * 60 + DatePart(mi, StartDateTime) As Minutes
From Schedule
)
Select *
From StartTimes As S1
Where Exists(
Select 1
From StartTimes As S2
Where S1.Seq <> 1
And Abs(S2.Minutes - S1.Minutes) >= 30
)
,起始时间为
(
选择StartDateTime
,行号()在(按开始日期时间排序)上方,如下所示
,DatePart(hh,StartDateTime)*60+日期部分(mi,StartDateTime)作为分钟
按计划
)
挑选*
从StartTimes开始为S1
哪里有(
选择1
从StartTimes到S2
式中S1.序号1
和Abs(S2.5分钟-S1.5分钟)>=30
)
使用Chris提到的时间段(不要与时间强盗混淆):
CREATE TABLE Start_Periods
(
begin_time TIME NOT NULL,
end_time TIME NOT NULL,
time_period TINYINT NOT NULL
CONSTRAINT PK_Start_Periods PRIMARY KEY CLUSTERED (begin_time),
CONSTRAINT CK_Start_Periods_begin_before_end CHECK (begin_time < end_time OR end_time = '00:00:00.000')
)
INSERT INTO Start_Periods (begin_time, end_time, time_period)
SELECT '00:00:00.000', '00:15:00.000', 1 UNION ALL
SELECT '00:15:00.000', '00:45:00.000', 2 UNION ALL
SELECT '00:45:00.000', '01:15:00.000', 3 UNION ALL
SELECT '01:15:00.000', '01:45:00.000', 4 UNION ALL
SELECT '01:45:00.000', '02:15:00.000', 5 UNION ALL
SELECT '02:15:00.000', '02:45:00.000', 6 UNION ALL
SELECT '02:45:00.000', '03:15:00.000', 7 UNION ALL
SELECT '03:15:00.000', '03:45:00.000', 8 UNION ALL
--...
SELECT '23:15:00.000', '23:45:00.000', 48 UNION ALL
SELECT '23:45:00.000', '00:00:00.000', 1
CREATE TABLE Start\u Periods
(
开始时间时间不为空,
结束时间时间不为空,
时间段TINYINT不为空
约束主键开始时间主键聚集(开始时间),
约束检查结束检查之前的开始时间(开始时间<结束时间或结束时间='00:00:00.000')
)
插入开始时段(开始时段、结束时段、时段)
选择“00:00:00.000”、“00:15:00.000”,1个联合所有
选择'00:15:00.000','00:45:00.000',2个UNION ALL
选择'00:45:00.000','01:15:00.000',3个UNION ALL
选择'01:15:00.000','01:45:00.000',4个UNION ALL
选择“01:45:00.000”、“02:15:00.000”和“全部5”
选择'02:15:00.000','02:45:00.000',6全部
选择'02:45:00.000','03:15:00.000',7联合所有
选择“03:15:00.000”、“03:45:00.000”和“8全部”
--...
选择“23:15:00.000”、“23:45:00.000”和“48联合所有”
选择“23:45:00.000”、“00:00:00.000”,1
然后,您的查询变成:
SELECT
SCH.employee_code,
COUNT(DISTINCT SP.time_period) AS different_time_starts
FROM
Schedule SCH
INNER JOIN Start_Periods SP ON
SP.begin_time <= SCH.start_time AND
SP.end_time > SCH.start_time
GROUP BY
SCH.employee_code
选择
SCH.employee_代码,
当不同的时间开始时计数(不同的SP时间段)
从…起
附表SCH
内部联接开始\u周期SP打开
SP.开始时间SCH.开始时间
分组
SCH.employee_代码
只是给你一个想法:
- 构建SQL只需一周