我有一个要求,我应该将顶行与以逗号分隔的前一行数据库记录进行比较。 例如: 我的表格数据如下所示:
ID Phase Updated By
1 Test1,Test2,Test3 sxmalla
2 Test1,Test2 rkgauta
3 Test1,Test3 sxmalla
我必须显示相位中最新更改的内容以及更新后的内容。逗号分隔数据在前端提交了多个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
答案 0 :(得分: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
这是使用SQLServerCentral中的DelimitedSplit8K
功能进行拆分,但我相信您可以使用现有功能。
<强> SQLFiddle DEMO 强>
答案 1 :(得分: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)