Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 比较逗号分隔的行_Sql_Sql Server_Tsql_Sql Server 2000 - Fatal编程技术网

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)