【问题标题】:How to create a specific SQL Server stored procedure? [closed]如何创建特定的 SQL Server 存储过程? [关闭]
【发布时间】:2021-04-27 22:58:34
【问题描述】:

我有一个CONTRACTOR_SCHEDULER 表。 “时间表”栏中的字母表示工作时间(m - 8:00-20:00,n - 20:00-8:00(第二天),d - 8:00-8:00(第二天),h-休假)。 (Name, Begin_date) 是独一无二的。

Name Schedule Begin_date End_date
John nhmh 2019-01-01 2019-01-08
John nnh 2019-01-09 2019-01-25
Kate dh 2019-01-01 2019-01-07
Kate mnhdh 2019-01-08 2019-01-14
Mike nh 2019-01-01 2019-02-01
Mike mh 2019-02-02 2019-12-31

我需要一个 SQL Server 存储过程,它使用 CONTRACTOR_SCHEDULER 行创建新表 CONTRACTOR_WORK_DAY 的工作日(表中不显示休息日)。

例子:

第一行 - 约翰有时间表 nhm。第一个字母是 n 所以 begin_date - 2019-01-01 20:00,End_date - 2019-01-02 08:00。下一个字母是 h,请跳过它作为休息日。最后一个字母是 m 所以 begin_date - 2019-01-03 08:00,End_date - 2019-01-03 20:00。重复计划直到 2019-01-08 - 第一个表中的 end_date。

CONTRACTOR_SCHEDULER 第一行的表是:

Name Begin_date End_date
John 2019-01-01 20:00 2019-01-02 08:00
John 2019-01-03 08:00 2019-01-03 20:00
John 2019-01-05 20:00 2019-01-06 08:00
John 2019-01-08 08:00 2019-01-08 20:00

我在 python 中使用了一些循环调度字符串等,但无法弄清楚如何在 SQL Server 的 T-SQL 中执行此操作。

【问题讨论】:

  • 您应该用四个位列 m、n、d 和 h 替换您的“Schedule”列。
  • @NicholasHunter - 有 5 个角色的凯特呢?还是恼人的 BobbyTables 可能有 21 个字符的时间表?
  • 根据问题指南,请展示您尝试过的内容并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。请注意,SO 不是代码编写服务。如果您不知道从哪里开始,那么是时候访问教程和其他资源了。该站点用于解决您在尝试解决问题时遇到的特定技术问题。但它不是“我需要这个过程,请写它”。
  • OK,为班次单独的表,外键进入调度表。您当前的设计将是一个 PITA。

标签: sql sql-server tsql


【解决方案1】:

另一种选择。

不确定我是否同意所期望结果的最后记录。我有2019-01-07,而你有2019-01-08

示例或dbFiddle

Select A.[Name]
      ,[Begin_Date] = convert(datetime,left(dateadd(DAY,N       ,[Begin_date]),10)+' '+BegTime)
      ,[End_Date]   = convert(datetime,left(dateadd(DAY,N+NxtDay,[Begin_date]),10)+' '+EndTime)
 From  YourTable A
 Cross Apply ( values ( left(replicate(Schedule,10),datediff(DAY,Begin_Date,End_Date)) ) )B(S)
 Cross Apply ( 
               Select N=N-1
                     ,Subs=substring(B.S,N,1)
                 From (  Select Top (len(S)+1) N=Row_Number() Over (Order By (Select Null)) From  master..spt_values n1 ) B1
             ) C
 Join ( values ('m','08:00','20:00',0)
              ,('n','20:00','08:00',1)
              ,('d','08:00','08:00',1)
      ) D(SchdCd,BegTime,EndTime,NxtDay) on Subs=SchdCd
 Order By [Begin_Date]

结果

Name    Begin_Date                  End_Date
John    2019-01-01 20:00:00.000     2019-01-02 08:00:00.000
John    2019-01-03 08:00:00.000     2019-01-03 20:00:00.000
John    2019-01-05 20:00:00.000     2019-01-06 08:00:00.000
John    2019-01-07 08:00:00.000     2019-01-07 20:00:00.000

【讨论】:

    【解决方案2】:
    WITH
      numbers AS
    (
      -- Generate a table of values (from 0 upwards)
      -- Must be at least as long as the longest schedule string
      SELECT
        ROW_NUMBER() OVER (ORDER BY sv.number) - 1   AS id
      FROM
        master..spt_values  sv
    ),
      pivotted AS
    (
      -- Create one row for each day in the date range
      -- Extract the relevant character from the schedule for each day
      SELECT
        c.*,
        n.id  AS date_offset,
        SUBSTRING(c.schedule, (n.id % LEN(c.schedule)) + 1, 1)  AS schedule_char
      FROM
        CONTRACTOR_SHERULER   c
      INNER JOIN
        numbers               n
          ON n.id <= DATEDIFF(DAY, c.begin_date, c.end_date)
    )
    -- Add a number of days to the begin_date
    -- Then add a number of hours based on the current character from the schedule
    SELECT
      pivotted.*,
      DATEADD(
        HOUR,
        CASE pivotted.schedule_char WHEN 'm' THEN 8
                                    WHEN 'n' THEN 20
                                    WHEN 'd' THEN 8  END,
        DATEADD(DAY, date_offset, pivotted.begin_date)
      )
        AS begin_datetime,
      DATEADD(
        HOUR,
        CASE pivotted.schedule_char WHEN 'm' THEN 20
                                    WHEN 'n' THEN 32
                                    WHEN 'd' THEN 32  END,
        DATEADD(DAY, date_offset, pivotted.begin_date)
      )
        AS end_datetime
    FROM
      pivotted
    WHERE
      pivotted.schedule_char <> 'h'
    

    演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=f6c52e6718329f2ae013dc93edad5d78

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 2013-05-02
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-04
      相关资源
      最近更新 更多