在下面的查询中需要添加其他时间

时间:2018-09-15 12:33:49

标签: sql sql-server

我从此论坛的一位专家那里获得了以下代码(工作正常)。因此,我想做的是进一步修改此查询,以相同的方式获取日期,但适用于所有任务。数据库中有一个名为“ TASK”的表,每个task_id都有一个clndr_id和proj_id。所需的输出将是(proj_id,task_id,clndr_id,date_Value),所以我认为我们需要添加另一个WHILE来获取TASK表中所有任务的所有日期。我希望@CurseStacker或其他任何人都可以帮助:) ..谢谢。

ALTER FUNCTION [dbo].[GetProjectDates] 
(   
     @project_name  varchar(50)
)
RETURNS @temp_tb TABLE([proj_id] int, [clndr_id] int , [date_value] date)
AS
BEGIN 
    -- Add the SELECT statement with parameter references here
    DECLARE @project_id int
    DECLARE @clndr_id   int
    DECLARE @walker     int             =   0
    DECLARE @holder     varchar(MAX)
    DECLARE @date       date
    DECLARE @data       varchar(MAX)

    SELECT @project_id = [p].[proj_id]
          ,@clndr_id = [p].[clndr_id]
          ,@holder = [c].[clndr_data]
    FROM [PMDB].[dbo].[PROJECT] AS [p]
    INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [p].[clndr_id] = [c].[clndr_id]
    WHERE [p].[proj_short_name] = @project_name

    WHILE @walker <> LEN(@holder) + 1
    BEGIN
        IF SUBSTRING(@holder, @walker, 2) = 'd|'
        BEGIN
            SET @data = SUBSTRING(@holder, @walker, 10)
            IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()'
            BEGIN
                SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900')
                INSERT INTO @temp_tb VALUES (@project_id, @clndr_id, @date)
            END
        END
        SET @walker = @walker + 1
    END

    RETURN
END

GO

因此,“ TASK”表包括(proj_id,task_id,clndr_id),并且从“ Calendar”表中,我们可以通过链接到任务表中的proj_id获得clndr_data(上面的代码获取了clndr_data中“ d |”和“ )()'仅适用于一个clndr_id,它可以正常工作'现在我需要执行同样的操作,但是需要多个日历;

proj_id task_id clndr_id    clndr_data
4917    310449  7143    (0||CalendarData()(.....
4917    310450  7144    (0||CalendarData()(.....
4917    310451  7149    (0||CalendarData()(.....

所需结果(假设clndr_id 7143在'd |'和')()'之间只有2个日期,clndr_id 7144有3个日期,而cldnr_id 7149有2个日期)只是一个假设

proj_id  task_id clndr_id      date 
4917    310449   7143        2018-09-24
4917    310449   7143       2018-09-25
4917    310450   7144       2018-09-26
4917    310450   7144       2018-10-01
4917    310450   7144       2018-10-02
4917    310451   7149      2018-10-03
4917    310451   7149       2018-10-04

1 个答案:

答案 0 :(得分:0)

尝试如下操作:

ALTER FUNCTION [dbo].[GetProjectDates] 
(   
     @project_name  varchar(50)
)
RETURNS @temp_tb TABLE([proj_id] int, [task_id] int, [clndr_id] int , [date_value] date)
AS
BEGIN 
    -- Add the SELECT statement with parameter references here
    DECLARE @project_id int
    DECLARE @task_id   int
    DECLARE @clndr_id   int
    DECLARE @walker     int             =   0
    DECLARE @holder     varchar(MAX) = ''
    DECLARE @date       date
    DECLARE @data       varchar(MAX)

    declare @tab table (project_id int, task_id int, clndr_id int, holder varchar(max))

    insert into @tab
    SELECT [T].[proj_id] as project_id
          ,[T].[task_id] as task_id
          ,[c].[clndr_id] as clndr_id
          ,[c].[clndr_data] as holder
    FROM [PMDB].[dbo].[TASK] as [T]
    INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [T].[clndr_id] = [c].[clndr_id] and [T].[Proj_id] = [c].[proj_id] 
    WHERE [T].[proj_id] = (select proj_id FROM [PMDB].[dbo].[PROJECT] where [proj_short_name] = @project_name)

    declare @cur_task int, @cur_clndr int
    set @cur_task = (select top 1 task_id from @tab)
    set @cur_clndr = (select top 1 clndr_id from @tab where task_id = @task_id)
    set @holder = (select top 1 holder from @tab where task_id = @task_id)

    while ((select count(1) from @tab) > 0)
    begin
        print 'Current loop running for Task_Id' + convert(varchar(10), @cur_task)
        WHILE @walker <> LEN(@holder) + 1
        BEGIN
            IF SUBSTRING(@holder, @walker, 2) = 'd|'
            BEGIN
                SET @data = SUBSTRING(@holder, @walker, 10)
                IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()'
                BEGIN
                    SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900')
                    INSERT INTO @temp_tb VALUES (@project_id, @task_id, @clndr_id, @date)
                END
            END
            SET @walker = @walker + 1
        END

        delete @tab where task_id = @cur_task

        set @cur_task = (select top 1 task_id from @tab)
        set @cur_clndr = (select top 1 clndr_id from @tab where task_id = @task_id)
        set @holder = (select top 1 holder from @tab where task_id = @task_id)

        set @walker = 0
    end

    RETURN
END