问一个SQL查询的问题.有这样一个表,表结构这样的.
序号   更改前    更改后
1       A         B
2       J         K
3       Q         D
4       B         A
5       K         F
6       F         J
现在想查出循环更改的情况,就是改来改去又改回来了,如上例应该结果如:
1       A         B
4       B         A
2       J         K
5       K         F
6       F         J
这样的查询语句应该怎么写?

解决方案 »

  1.   

    --> 测试数据:[tb]
    IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
    GO 
    CREATE TABLE [tb]([序号] INT,[更改前] VARCHAR(1),[更改后] VARCHAR(1))
    INSERT [tb]
    SELECT 1,'A','B' UNION ALL
    SELECT 2,'J','K' UNION ALL
    SELECT 3,'Q','D' UNION ALL
    SELECT 4,'B','A' UNION ALL
    SELECT 5,'K','F' UNION ALL
    SELECT 6,'F','J'
    --------------开始查询--------------------------.;WITH t AS
    (
    SELECT a.*,[level]=1,[row]=ROW_NUMBER() OVER(ORDER BY 序号) FROM [tb] a WHERE  EXISTS(SELECT 1 FROM tb AS b WHERE a.[更改后]=b.[更改前]
    AND NOT EXISTS (SELECT  1 FROM tb  AS c WHERE (c.[更改前]=b.[更改后] OR  c.[更改前]=a.[更改后] ) AND c.序号<a.序号 ))
    UNION ALL 
    SELECT a.*,[level]=[level]+1,t.[row] FROM [tb] AS a,t WHERE  a.[更改前]=t.[更改后] AND t.[level]<4
    )
    SELECT 序号,更改前,更改后 FROM t AS a WHERE [level]=(select MIN([level]) FROM t WHERE a.序号=序号 AND a.更改前=更改前 AND 更改后=t.更改后)
    ORDER BY [row],[level]
    ----------------结果----------------------------
    /* 
    序号          更改前  更改后
    ----------- ---- ----
    1           A    B
    4           B    A
    2           J    K
    5           K    F
    6           F    J(5 行受影响)
    */
      

  2.   

    ---> 测试数据:[tb]
    IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
    GO 
    CREATE TABLE [tb]([序号] INT,[更改前] VARCHAR(1),[更改后] VARCHAR(1))
    INSERT [tb]
    SELECT 1,'A','B' UNION ALL
    SELECT 2,'J','K' UNION ALL
    SELECT 3,'Q','D' UNION ALL
    SELECT 4,'B','A' UNION ALL
    SELECT 5,'K','F' UNION ALL
    SELECT 6,'F','J' UNION ALL
    SELECT 7,'h','i' UNION ALL
    SELECT 8,'i','d' UNION ALL
    SELECT 9,'d','e' UNION ALL
    SELECT 10,'e','l' UNION ALL
    SELECT 11,'l','5' UNION ALL
    SELECT 12,'6','h' UNION ALL
    SELECT 13,'5','6' 
    --------------开始查询--------------------------.;WITH t AS
    (
    SELECT a.*,[level]=1,[row]=ROW_NUMBER() OVER(ORDER BY 序号) FROM [tb] a WHERE  EXISTS(SELECT 1 FROM tb AS b WHERE a.[更改后]=b.[更改前]
    AND NOT EXISTS (SELECT  1 FROM tb  AS c WHERE (c.[更改前]=b.[更改后] OR  c.[更改前]=a.[更改后] ) AND c.序号<a.序号 ))
    UNION ALL 
    SELECT a.*,[level]=[level]+1,t.[row] FROM [tb] AS a,t WHERE  a.[更改前]=t.[更改后] AND t.[level]<20
    )
    SELECT 序号,更改前,更改后 FROM t AS a WHERE [level]=(select MIN([level]) FROM t WHERE a.序号=序号 AND a.更改前=更改前 AND 更改后=t.更改后)
    ORDER BY [row],[level]
    ----------------结果----------------------------
    /* 
    序号 更改前 更改后
    1 A B
    4 B A
    2 J K
    5 K F
    6 F J
    3 Q D
    7 h i
    8 i d
    9 d e
    10 e l
    11 l 5
    13 5 6
    12 6 h*/
    第3 行又包括进来了,这又是怎么回事?