如何避免使用while在存储过程中重复相同的记录?

时间:2015-06-24 08:38:03

标签: sql sql-server stored-procedures

我正在编写一个存储过程,需要我按班次动态计算时间。

enter image description here

基本上第一行是固定的,因此之后的行应该能够使用如下的简单代码生成自己。

有人可以帮我这个吗?我的while给出了相同的记录。我附上了一张图片,以便更容易理解。

CREATE TABLE #TimeSlot
(    
         Parameter nvarchar(Max) null,
         DisplayStartTime varchar(32) not null,
         DisplayEndTime nvarchar(50)null,
         CodeEndTime nvarchar(50) null,
         Frequency int null,
         Tolerance int null
)   

INSERT INTO #TimeSlot(Parameter, DisplayStartTime, DisplayEndTime, CodeEndTime, Frequency, Tolerance)
   SELECT DISTINCT 
      Parameter, '23:00:00', 
      LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency)), '23:00:00'), 120), 8))) as DisplayEndTime
      ,LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency) + Tolerance), '23:00:00'), 120), 8))) as CodeEndTime
,Frequency,Tolerance
   FROM
      tableTest

WHILE (@intFlag <=3)
BEGIN
    INSERT INTO #TimeSlot (Parameter, DisplayStartTime, DisplayEndTime, CodeEndTime, Frequency, Tolerance)
       SELECT
          Parameter, DisplayEndTime,
          LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency)), DisplayEndTime), 120), 8))) as DisplayEndTime,
          LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency) + Tolerance), DisplayEndTime), 120), 8))) as CodeEndTime,
          Frequency,
          Tolerance 
       FROM 
          #TimeSlot

    SET @intFlag = @intFlag + 1
End

我的预期结果: 我需要一些可以重复查询而不重复同一参数的DisplayStartTime,DisplayEndTime记录的东西。 enter image description here

1 个答案:

答案 0 :(得分:-1)

你在CTE作为计数表和交叉连接的帮助下实现了它,我做了一个只有3行的简单例子,但你可以在SO或Google周围搜索更完整和更高级的例子。

试试这个:

with cte (n) as (
    select 1 UNION ALL
    select 2 UNION ALL
    select 3 
),
tableTest (
    [Parameter],
    DisplayStartTime,
    DisplayEndTime,
    CodeEndTime,
    Frequency,
    Tolerance
) as (
SELECT DISTINCT 
    Parameter, 
    '23:00:00', 
    LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency)), '23:00:00'), 120), 8))) as DisplayEndTime,
    LTRIM((RIGHT(CONVERT(VARCHAR(100), DATEADD(minute, convert(int, CONVERT(int, Frequency) + Tolerance), '23:00:00'), 120), 8))) as CodeEndTime,
    Frequency,
    Tolerance
FROM tableTest
)
select
    tt.[Parameter],
    DATEADD(MINUTE,Frequency*cte.n,DisplayStartTime) DisplayStartTime,
    DATEADD(MINUTE,Frequency*cte.n,DisplayEndTime) DisplayEndTime,
    DATEADD(MINUTE,(Frequency*cte.n)+ Tolerance,DisplayEndTime) CodeEndTime,
    Frequency,
    Tolerance
from tableTest tt
cross join cte