从每列的桌面1行中选择

时间:2015-10-16 21:19:00

标签: sql sql-server

我有一个项目表,每个项目都可以有一个或多个工作流程。每个工作流程由一个或多个步骤组成。请参阅下面数据定义的表格:(@ project,@ systemflow,@ step,@ workingflowSteps)。

根据下面显示的数据,我们有2个项目:p1和p2。 @ProjectWorkflow表链接项目和工作流程。 p1分配了2个工作流程,p2只分配了一个工作流程。

工作流程1包括以下步骤:启动,设计批准,完成 工作流程2包括:启动,设计,实施,测试,完成。

随着项目从一个步骤进展到下一个步骤,我们在@ProjectWorkflowSteps表中插入一条记录。 下面表格定义中的注释描述了每个项目所做的步骤。

需要考虑另外一个条件。工作流程可以更改。因此,可以为项目分配工作流程2.它可以在该工作流程中执行一些步骤,用户可以将工作流程更改为工作流程的一半。请参阅下面的@ProjectWorkflowSteps的注释。

现在我想查询所有项目的列表(每个项目一行),其中projectID作为第一列,而步骤列表用逗号分隔第二列,但我只想要每个工作流程的最后一步。所以基本上查询将返回项目和每个项目所在的当前步骤。对于具有多个工作流程(p1)的项目,它将返回每个工作流程的当前步骤,如下所示:

1    approve, implement
2    start

奖金帮助将返回以下结果:

1    approve: 3/4, implement 3/5
2    start: 1/4   

基本上为每个工作流程列表显示当前步骤,到目前为止完成的步骤/工作流程中的步骤总数。

感谢任何帮助。

感谢。

编辑:

感谢Gyromite的回答。我在这里用它来澄清这个问题。

DECLARE @project TABLE (projectID INT PRIMARY KEY, name VARCHAR(50));
INSERT @project
VALUES
(1, 'p1'),
(2, 'p2');


DECLARE @Step TABLE (ID INT PRIMARY KEY, name VARCHAR(50));
INSERT @Step
VALUES
(1, 'start'),
(2, 'finish'),
(3, 'test'),
(4, 'implement'),
(5, 'approve'),
(6, 'design');
DECLARE @Workflow TABLE (ID INT PRIMARY KEY, name VARCHAR(50));
INSERT @Workflow
VALUES
(1, 'workflow1'),
(2, 'worfklow2');

DECLARE @WorkflowSteps TABLE (ID INT PRIMARY KEY, workflowID INT, stepID     INT);
INSERT @WorkflowSteps
VALUES
(1, 1, 1), --workflow1 steps: start, design approve, finish
(2, 1, 6),
(3, 1, 5),
(4, 1, 2),

(5, 2, 1),  --Workflow2: start, design, implement, test, finish
(6, 2, 6),
(7, 2, 4),
(8, 2, 3),
(9, 2, 2);


DECLARE @projectWorkflow TABLE (projectworkflowID INT PRIMARY KEY, projectID INT, workflowID INT);
INSERT @projectWorkflow
VALUES
(1, 1, 1), --proejct 1 has two workflows
(2, 1, 2),
(3, 2, 2);  --project 2 has only one workflow


DECLARE @ProjectWorkflowSteps TABLE (PWSID INT PRIMARY KEY, projectworkflowID INT, projectID INT, workflowID INT, stepID INT);
INSERT @ProjectWorkflowSteps (PWSID, projectWorkflowID, projectID, workflowID, stepID)
VALUES
(1, 1,1,1,1),  --project 1 has 2 workflows assigned to it
(2, 1,1,1,6),  --on workflow 1 it progressed thru 2 steps 
(3, 1,1,1,5),  --and is currently on the third step: approve step (ID=5)

(4, 2,1,2,1),  --project 1 -> second workflow, also progressed 2 steps
(5, 2,1,2,2),  --and is currently on third stepID = 4: 'implement'
(6, 2,1,2,4),  --


(7, 3,2,2,1), --project 2 was assigned workflowID 2 for the first two steps. 
(8, 3,2,2,2), -- then it was changed to workflowID = 1
(9, 3,2,1,1); -- PWID is still 3 here, but workflowID is changed from 2 -> 1

编辑2: 以下查询给出了我想要的内容,但我想知道它是否可以以更有效的方式执行。

    SELECT p.projectID,
Stuff ((SELECT ',  ' + s.name 
           FROM   (SELECT * 
                   FROM   @projectWorkflow) pw 
                  LEFT OUTER JOIN (SELECT * 
                                   FROM   (SELECT projectworkflowID, 
                                  pwsID, 
                                  stepID, 
                       Row_number() OVER(partition BY ProjectworkflowID 
                                      ORDER BY pwsid DESC) rn 
                                           FROM   @ProjectWorkflowSteps 
                                           WHERE  projectID = p.projectID) 
                                          ppp 
                                   WHERE  rn = 1) pws 
                               ON pw.projectworkflowID = pws.projectworkflowid 
                  INNER JOIN @step s 
                          ON s.ID = pws.stepID
           FOR xml path('')), 1, 1, '') [Steps]
FROM   @project p 
GROUP  BY p.projectID

1 个答案:

答案 0 :(得分:1)

希望这可以帮助您获得所需的结果。

DECLARE @ProjectStatus TABLE (PWID INT, projectID INT, workflowID INT, stepID INT);
INSERT @ProjectStatus (PWID, projectID, workflowID, stepID)
    VALUES
    (1,1,1,1),
    (1,1,1,2),
    (1,1,1,3),
    (2,1,2,1),
    (2,1,2,2),
    (2,1,2,4),
    (3,2,2,1),
    (3,2,2,2),
    (3,2,1,1);
DECLARE @Step TABLE (ID INT PRIMARY KEY, name VARCHAR(50));
INSERT @Step
    VALUES
    (1, 'start'),
    (2, 'design'),
    (3, 'approve'),
    (4, 'implement');
SELECT PS1.projectID
    ,stuff( -- using Stuff to remove the leading comma in the concatenated string.
        (   SELECT ', ' + St.name
            FROM
            (   SELECT PS2.projectID, PS2.workflowID, MAX(PS2.stepID) AS stepID
                FROM @ProjectStatus AS PS2
                GROUP BY PS2.projectID, PS2.workflowID
            ) AS PSWorkflowStep
            INNER JOIN @Step AS St ON St.ID = PSWorkflowStep.stepID
            WHERE PSWorkflowStep.projectID = PS1.projectID
            ORDER BY PSWorkflowStep.workflowID
            for xml path('') -- For XML PATH is the method I'm using for concatenating multiple rows into one.
            -- This next line translates the XML back to text (to avoid issues with special characters @,&,<,>) but it is expensive in CPU.  You may remove it if you don't need it.
            , root('XMLVal'), type).value('/XMLVal[1]','varchar(max)'
        )
    , 1, 2, '') AS workflowSteps
FROM @ProjectStatus AS PS1
GROUP BY PS1.projectID
ORDER BY PS1.projectID

返回的结果如下:

projectID   workflowSteps
1   approve, implement
2   start, design

说明中有一些部分我不明白,所以我做了几个假设。看起来您的第一个样本表中可能存在错误,其中步骤ID为1,并且#34; start&#34;和&#34;设计&#34;,所以我假设步骤ID 1应该是&#34;开始&#34;。此外,我还没有看到您所谈论的段落的相关性&#34;工作流程可以更改,&#34;所以我离开了我的榜样。最后,关于你的奖金帮助结果,我从你的模型中看不出如何判断哪个是给定工作流程的当前步骤,所以我没有尝试这个部分。

将来,如果您可以请包含T-SQL脚本来重新创建您的示例(表格和数据),这将使某人更容易帮助您编写查询。