【问题标题】:How to use a While Loop in where clause如何在 where 子句中使用 While 循环
【发布时间】:2015-08-31 12:56:31
【问题描述】:

我有一个如下表,其中包含截至今天的 EntryTime 列中的条目。

表 1

PersonID|StartTime|EndTime|EntryTime
1       |10:00    |12:00  |2014-01-01
1       |10:00    |12:00  |2014-01-02
1       |10:00    |12:00  |2015-01-03
...

和一个合同表:

表2

PersonID|ContractID| ContractStart| ContractType|Hours
1       |1         |2014-01-01    |Student      |8
1       |2         |2015-01-01    |Trainee      |40
1       |3         |2015-03-01    |Student      |20
1       |4         |2015-05-01    |Student      |12

现在我想使用下面提到的结果表来计算当前contractType 的时间(datediff(minute, StartTime, Endtime))contracttype 必须从最后一个开始连续。所以在这个例子中,合同 3+4 的所有条目都是相关的。

我的想法是使用loop 来选择相关合同。

WHILE (Select ContractType from Table2) = 'Student'
Begin
Select ContractStart from Table2
Order By ContractStart
End

不幸的是,循环还没有工作,如果我不知道如何在 where 子句中实现它。

我想要得到的结果表是 subsetTable1,所有条目都从 2015-03-01 开始

【问题讨论】:

  • 不要为此使用循环。准备好sqlfiddle.com,你可能会得到基于集合的解决方案。共享样本数据所需的输出。
  • 与您的问题无关,但是您在 table1 中的记录是否可能跨越一个日历日?
  • 不,这是不可能的。例如。如果你通宵工作,你必须做两个条目。只要我从 table2 中获得正确的日期,我就可以很容易地过滤表。
  • 能否请您发布所需输出的示例。

标签: sql tsql


【解决方案1】:

如果没有示例,很难知道您想要什么,但这是一种尝试。还要对你的类型做出很多猜测。

注意:Avoid while 循环游标,坚持设置逻辑 =)

declare @Table1 as table
(
    PersonID int
    ,StartTime datetime
    ,EndTime datetime
    ,EntryTime date
)

insert into @Table1
values
 (1       ,'10:00', '12:00', '2014-01-01')
,(1       ,'10:00', '12:00', '2014-01-02')
,(1       ,'10:00', '12:00', '2015-01-03')
,(2       ,'10:00', '12:00', '2015-01-03')
,(2       ,'10:00', '12:00', '2015-01-04')
,(3       ,'10:00', '12:00', '2015-01-03')
,(3       ,'10:00', '12:00', '2015-01-05')


declare @Table2 as table
(
    PersonID int
    ,ContractID int
    ,ContractStart date
    ,ContractType varchar(10)
    ,[Hours] float
)
insert into @Table2
values
 (1       ,1         ,'2014-01-01',    'Student',      8)
,(1       ,2         ,'2015-01-01',    'Trainee',      40)
,(1       ,3         ,'2015-03-01',    'Student',      20)
,(1       ,4         ,'2015-05-01',    'Student',      12)
,(2       ,1         ,'2014-01-01',    'Student',      8)
,(2       ,2         ,'2015-01-01',    'Trainee',      40)
,(2       ,3         ,'2015-03-01',    'Student',      20)
,(2       ,4         ,'2015-05-01',    'Student',      12)
,(3       ,1         ,'2014-01-01',    'Student',      8)
,(3       ,2         ,'2015-01-01',    'Trainee',      40)
,(3       ,3         ,'2015-03-01',    'Student',      20)
,(3       ,4         ,'2015-05-01',    'Student',      12)

--Current contrat (for PersonId = 1)
declare @CurrentType varchar(10) =
(select top 1 ContractType from @Table2 where PersonID = 1 order by ContractStart desc)

--Last different type start (for PersonId = 1)
declare @LastDiff date = 
(select top 1 ContractStart from @Table2 where PersonID = 1 and @CurrentType != ContractType order by ContractStart desc)

--Current type span (for PersonId = 1)
select datediff(minute, min(StartTime + cast(EntryTime as datetime)), max(EndTime + cast(EntryTime as datetime))) as [PesonId = 1 TimeSpan]
from @Table1
where PersonID = 1
and EntryTime > @LastDiff


-- Puting everything togheter
select t1.PersonId, datediff(minute, min(t1.StartTime + cast(t1.EntryTime as datetime)), max(t1.EndTime + cast(t1.EntryTime as datetime))) as TimeSpan
from @Table1 t1
where t1.EntryTime >
 (
    select top 1 t2.ContractStart
    from @Table2 t2
    where t2.PersonID = t1.PersonID
    and t2.ContractType != 
    (
       select top 1 t2b.ContractType from @Table2 t2b where t2b.PersonID = t2.PersonID order by t2b.ContractStart desc
    )
    order by t2.ContractStart desc
 )
group by t1.PersonId

sn-p 是不言自明的,它给了我:

PersonId TimeSpan
-------- --------
       1    120
       2    1560
       3    3000

注意,我添加了一些数据以制作更好的测试示例

【讨论】:

    【解决方案2】:

    试试这个:

    Select Table1.PersonID, ContractID, datediff(minute, StartTime, Endtime) diff
        from Table2 INNER JOIN Table1 on Table2.PersonID = Table1.PersonID
        WHERE ContractType LIKE 'Student'
        GROUP BY Table1.PersonID, ContractID
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-10
      相关资源
      最近更新 更多