检查两个表的记录顺序是否相同

时间:2018-04-06 07:11:25

标签: sql sql-server tsql

我有两个记录集(临时表数据)和一些列。我需要检查两个表的记录是否在相同的顺序

我没有检查两个记录集或公共行之间的差异。我需要检查它们是否处于相同的顺序。(两个表已经有一些列的记录顺序,需要使用GUID列检查两个表的顺序是否相同)

如果Guid匹配,那么我将在某些表中插入信息,如果没有,则将其插入到日志表中,但在两种情况下都应该移动到/比较下一条记录。

我正在考虑为两个临时表嵌套循环,并通过比较Guid列来检查顺序。

还有其他办法吗?

3 个答案:

答案 0 :(得分:1)

你的问题不是很清楚。只是一些事实:

  • 没有隐含的顺序!您可以按给定的顺序填充表格,下一个SELECT可能会按此顺序返回数据 - 但这是随机的!您应该永远不要依赖排序顺序!没有!
  • 强制执行排序顺序的唯一保证方法是在最外层查询中使用ORDER BY
  • 一个专业可能是使用排序功能,如ROW_NUMBER()。但这是广泛的讨论这里。

如果我找到你,你需要检查双方存在的行,如果它们以相同的顺序出现。试试这个:

DECLARE @t1 TABLE(YourGuid UNIQUEIDENTIFIER, Descr VARCHAR(100),SomeSortableColumn DATETIME);
INSERT INTO @t1 VALUES('653E6A93-3EBA-4D5E-A8F3-C36462A55FEF','Row 1',{d'2018-01-01'})
                     ,('5461F417-1D14-4CFE-822D-3F028492F839','Row 2',{d'2018-01-02'})
                     ,('E9BDE8C6-237A-49F6-88BD-9EB211FB12F2','Row 3',{d'2018-01-03'})
                     ,('64343D33-8AD2-475F-AC27-66A6BFD011C9','Row 4',{d'2018-01-04'})
                     ,('5778229D-B20E-41FC-9A2E-8694B204E4D3','Row 5',{d'2018-01-05'})
                     ,('9AC0BB10-0F70-488C-A249-45A3C688D877','Row 6',{d'2018-01-06'})
                     ,('330526D6-B931-4CEA-BB03-30F3783E6284','Row 7',{d'2018-01-07'})
                     ,('6F68F260-2F64-4C78-9DA5-20E0FF22B4A1','Row 8',{d'2018-01-08'})
                     ,('E09090F1-FC85-41EE-819B-8275A22BD075','Row 9',{d'2018-01-09'});

DECLARE @t2 TABLE(YourGuid UNIQUEIDENTIFIER, Descr VARCHAR(100),SomeSortableColumn DATETIME);
INSERT INTO @t2 VALUES('653E6A93-3EBA-4D5E-A8F3-C36462A55FEF','Row 1',{d'2018-01-01'})
                     ,('5461F417-1D14-4CFE-822D-3F028492F839','Row 2',{d'2018-01-02'})
                     --missing in 2: 3 & 4
                     ,('5778229D-B20E-41FC-9A2E-8694B204E4D3','Row 5',{d'2018-01-05'})
                     --other GUID  
                     ,(NEWID(),'Row 6',{d'2018-01-06'})
                     ,('330526D6-B931-4CEA-BB03-30F3783E6284','Row 7',{d'2018-01-07'})
                     --other date
                     ,('6F68F260-2F64-4C78-9DA5-20E0FF22B4A1','Row 8',{d'2018-01-01'})
                     ,('E09090F1-FC85-41EE-819B-8275A22BD075','Row 9',{d'2018-01-09'})
                     --missing in 1
                     ,(NEWID(),'Other row',{d'2018-01-03'})
;

- 此查询使用INNER JOIN列上的GUID来省略两个集合中不存在的行。它使用两次ROW_NUMBER(),每个调用在同一列之后排序,但取自不同的来源。结果显示这些索引不同的行。

WITH ColumnsToCompare AS
(
    SELECT t1.YourGuid
          ,t1.Descr AS Descr1
          ,t2.Descr AS Descr2
          ,t1.SomeSortableColumn AS Sort1
          ,t2.SomeSortableColumn AS Sort2
          ,ROW_NUMBER() OVER(ORDER BY t1.SomeSortableColumn) AS Index1
          ,ROW_NUMBER() OVER(ORDER BY t2.SomeSortableColumn) AS Index2
    FROM @t1 AS t1
    INNER JOIN @t2 AS t2 ON t1.YourGuid =t2.YourGuid 
)
SELECT *
FROM ColumnsToCompare
WHERE Index1<>Index2

答案 1 :(得分:0)

不确定我的问题是否正确,但我认为你应该做的就是以下。

以下是您的问题 “如果Guid匹配,那么我会在某些表中插入信息,如果没有,则会在日志表中插入,但在两种情况下都应该移动到/比较下一条记录。”

您需要2个插入语句

在第一个中,在GUID上执行内部联接并将结果插入table1。

在第二个查询中,执行左连接并将其过滤为null,然后将结果集插入日志表中。

insert into sometable
select * 
from Table1 t1
inner join Table2 t2 on T1.GUID = T2.GUID

insert into logtable
select * 
from Table1 t1
left join Table2 t2 on T1.GUID = T2.GUID
where t2.guid is null

答案 2 :(得分:0)

您可以生成行号(无需排序)并检查具有不同行号的GUID。

    declare @table1 table(id varchar(MAX))
    declare @table2 table(id VARCHAR(MAX))

    insert into @table1
    select '653E6A93'
    union all
    select '5461F417'
    union all
    select '330526D6'

    insert into @table2
    select '653E6A93'
    union all
    select '330526D6'
    union all
    select '5461F417'


    ;with cte1
    AS
    (
        select *, ROW_NUMBER() OVER (ORDER BY (SELECT null)) AS rn from @table1
    )
    ,

    cte2
    AS
    (
        select *, row_number() OVER(order by (SELECT NULL)) rn from @table2
    )

    select c1.id from cte1 c1
    JOIN cte2 c2 on c1.id=c2.id and c1.rn<>c2.rn