如何检查两个有序 SQL 查询结果是否匹配?

5
这是问题:我有一张表里面有两列,对于每个分组,这两列应该有相同的顺序。在我做出这样的假设之前,我想检查现有数据是否符合要求。
一些示例数据:
gid  c1  c2
1    1   5
1    2   7
2    1   22
2    2   38
2    3   40
3    1   4
3    2   8
3    3   2

正如您所看到的,如果我使用以下语句: select * from table t where t.gid = 1 order by c1 则结果将完全相同,且与以下语句排序后的结果相同: select * from table t where t.gid = 1 order by c2 对于gid=2,结果也将匹配。 然而,如果针对gid=3做相同的操作,则排序不再匹配。因为在这种情况下,按c2排序的结果与按c1排序的结果不同。
我想检查整个表格,以确保按任意一列排序时,每个gid值都具有相同的结果。Oracle的MINUS无法工作,因为其不允许在子查询中使用order by。我的第一次尝试失败了,因为MINUS的限制。
select gid, c1, c2 from table order by gid, c1, c2
  minus
select gid, c1, c2 from table order by gid, c2, c1;

我正在使用Oracle 11g,如果这有助于回答的话。


minus 不起作用,因为它会隐式执行 distinct 操作,而你只关心一个集合是否存在于另一个集合中。 - Ben
3个回答

6

通过分配row_number,在同一记录中可能会发现顺序上的差异。

with ordering as (
  select t.*,
         row_number() over (partition by gid
                            order by c1) order_c1,
         row_number() over (partition by gid
                            order by c2) order_c2
  from t
)
select *
  from ordering
 where order_c1 <> order_c2

@Nikola,row_number就是你要的。完美而且回复速度很快。谢谢。 - user399470

1
有趣的问题,我没有Oracle,但类似的东西。
Select gid,c1,c2,row_number() as rownum from ordering order by gid,c1,c2
join (select gid,c1,c2,row_number() as otherrownum from ordering order by gid,c2,c1) otherOrdering
On rownum = otherrownum and 
((ordering.gid <> otherOrdering.gid) Or
(ordering.c1 <> otherOrdering.c1) or
(ordering.c2 <> otherOrdering.c2))

如果它返回任何内容,那么你的假设是不正确的。 或者你可以将 <> 改为 =,将 Or 改为 AND,它应该返回与表中行数相同的行数。
我想是这样的。

0

我不确定Oracle上的EXCEPT等效物。但在MS SQL Server上它可以正常工作。


不幸的是,Oracle的“EXCEPT”和“MINUS”是相同的,并且在子查询中不接受“order by”。 - user399470

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接