0

我有一个要求,我应该将第一行与以前的数据库记录行进行比较,它们是逗号分隔的。示例:我的表数据如下所示:

      ID   Phase                Updated By
      1    Test1,Test2,Test3    sxmalla
      2    Test1,Test2          rkgauta
      3    Test1,Test3          sxmalla

我必须显示 Phase 中的最新更改以及更新的人员。逗号分隔的数据在前端使用多个 chechbox 提交。用户可以通过同一页面中的多个复选框来更新它们。这里 Test3 是最近的更改,然后在 Test2 下面是最近的更改,第三行是实际的第一个条目。

我需要将结果显示为

      Phase        Updated By
      Test3        sxmalla
      Test2        rkgauta
      Test1,Test3  sxmalla

这是我目前用来比较 2 个逗号分隔行的代码

  ALTER Proc [dbo].[PMT_GetPhasesEditHistory]

  @Project_ID int
  As Begin
  SET NOCOUNT ON 
  Declare @added varchar(1000), @removed varchar(1000),@strN varchar(1000),@strO varchar(1000)
  DECLARE test_cursor CURSOR FOR                                    


  SET @strO=(SELECT TOP 1 P1.Phase from phase P1,Phase P2 where  P1.ID = P2.ID-1 and p1.project_id=@Project_ID order by p1.ID Desc)

  SET @strN =(SELECT TOP 1 P2.Phase from phase P1,Phase P2 
  where  P1.ID = P2.ID-1 and p1.project_id=@Project_ID order by p1.ID Desc)

  If object_id('dbo.#tN') is not null Begin ; drop table dbo.#tN ;End          

  CREATE TABLE dbo.#tN( var varchar(100));  insert into #tN select * from fnSplitStringAsTable(@strN,',')

  If object_id('dbo.#tO') is not null Begin; drop table dbo.#tO ;End          

  CREATE TABLE dbo.#tO (var varchar(100));  insert into #tO select * from fnSplitStringAsTable(@strO,',')

  Declare @i int
  Set @i=1
  Set @added = ''
  While @i != (select COUNT(*)+1 from #tN) 
  Begin
  if not exists(select VAR from #tO where var = (select Top 1 var from #tN where var in ( Select   Top (@i) VAR from #tN where Var in (Select Top (@i) var From #tN order by VAR desc) order by var asc)))
   Begin
   Set @added = @added + (select Top 1 var from #tN where var in ( Select Top (@i) VAR from #tN where Var in (Select Top (@i) var    From #tN order by VAR desc) order by var asc)) + ','
   End
   set @i=@i+1
  End

  If(len(@added) > 1) Begin; set @added = RTRIM(LEFT(@added,Len(@added) - 1)); End
  Select @added as Added

  drop table #tN;Drop table #tO
  End
4

2 回答 2

0

这是一个可能的解决方案:

WITH CTE_Prep AS 
(
    SELECT *, DENSE_RANK() OVER (ORDER BY ID DESC) RN
    FROM phase
    CROSS APPLY dbo.DelimitedSplit8K(Phase,',')
)
,CTE_Result AS 
(
    SELECT ID, STUFF ((SELECT ', ' +Item 
                        FROM CTE_Prep c WHERE Item NOT IN (SELECT Item FROM CTE_Prep c2 WHERE c2.RN + 1 = c.RN)
                        AND c.Id = c3.ID
                        FOR XML PATH('')),1,2,'') AS Phase
    FROM CTE_Prep c3
    GROUP BY ID
)
SELECT r.Phase, p.[Updated By] FROM CTE_Result r
LEFT JOIN phase p ON r.id = p.id

这是使用SQLServerCentralDelimitedSplit8K中的函数进行拆分,但我相信您可以使用现有的。

SQLFiddle 演示

于 2013-09-03T09:08:22.240 回答
0

我将尝试回答标准化问题。

Table PhaseTest 
PhaseID   int
TestID    int  
PK  PhaseID,  TestID
(this PK will enforce no duplicate TestID in a PhaseID  

Table PhaseUser
PhaseID   int PK
UserID    int

Table Test
TestID    int PK
TestName  varchar

Table User 
UserID    int PK
UserName  varchar

这将结果显示在单独的行上(没有逗号)

select PT1.PhaseID, Test.TestName, User.UserName
  from PhaseTest PT1 
  left outer join PhaseTest PT2
    on PT2.PhaseID = PT1.PhaseID + 1 
   and PT2.TestID  = PT1.TestID
  join PhaseUser 
    on PhaseUser.UserID = PT1.UserID 
  join Test 
    on Test.TestID = PT1.UserID
 where PT2.PhaseID is null
 order by PT1.TestID
 union
select PT1.PhaseID, Test.TestName, User.UserName
  from PhaseTest PT1 
  join PhaseUser 
    on PhaseUser.UserID = PT1.UserID 
  join Test 
    on Test.TestID = PT1.UserID
 where PT1.PhaseID = (select max(PhaseID) from PhaseTest)
于 2013-09-03T13:44:33.243 回答