Sql 比较逗号分隔的行
我有一个要求,在这里,我应该将最上面的一行与以前的数据库记录行进行比较,这些记录行是逗号分隔的。 例子: 我的表数据如下所示:Sql 比较逗号分隔的行,sql,sql-server,tsql,sql-server-2000,Sql,Sql Server,Tsql,Sql Server 2000,我有一个要求,在这里,我应该将最上面的一行与以前的数据库记录行进行比较,这些记录行是逗号分隔的。 例子: 我的表数据如下所示: ID Phase Updated By 1 Test1,Test2,Test3 sxmalla 2 Test1,Test2 rkgauta 3 Test1,Test3 sxmalla 我必须显示一些最新的阶段变化和谁更新了。逗号
ID Phase Updated By
1 Test1,Test2,Test3 sxmalla
2 Test1,Test2 rkgauta
3 Test1,Test3 sxmalla
我必须显示一些最新的阶段变化和谁更新了。逗号分隔的数据在前端用多个复选框提交。用户可以通过同一页面中的多个复选框进行更新。
这里Test3是最新的更改,下面Test2是最新的更改,第三行是实际的第一个条目
我需要将结果显示为
Phase Updated By
Test3 sxmalla
Test2 rkgauta
Test1,Test3 sxmalla
下面是我目前用来比较两个逗号分隔行的代码
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
以下是一个可能的解决方案:
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
这是使用中的DelimitedSplit8K
函数进行拆分,但我相信您可以使用现有的
我将尝试回答规范化问题
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
这将在单独的行上显示结果(无逗号)
请先考虑规范化数据。将逗号分隔的数据拆分为实列,可能还有一个表。通常,您需要将最后一行(3)与前一行(2)进行比较,并提取第(2)行中未添加的“新”内容。然后比较第(2)行和第(1)行,并再次检查第(1)行中添加了什么“新”?这就是你想要的吗?@gotqn-请给我们一个在RDBMS中存储逗号分隔字符串的实际例子,它“非常实用”@gotqn:存储逗号分隔的值实际上可能会减少行数,但我非常怀疑它是否会提高性能。但我很高兴被证明是错的。因此,如果您有一个完整的示例,实际表明使用逗号分隔的值可以提高性能(而不牺牲数据完整性),请向我们展示。@gotqn该表中不会有1500万行,您将有另一个包含1500万行的表,只有在需要时才能访问该表。虽然可能存在CSV有用的情况,但您的示例没有显示它。我使用的是sql 2000生产。我认为这对sql 2000不起作用:-(不,不会。您应该在一开始就提到“小”东西:)是的,我应该有,我们可以为@Nanad Zivkovic提供其他解决方案吗
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)