[英]Oracle SQL, how to compare and find mismatches between two tables
我有两个表,在下面的结构中
Table 1
Type ID NAME FROMPOS SIZE
.doc 1 A Number 4 9
.doc 1 C Number 14 10
.doc 1 Total 24 10
.doc 1 Date 36 8
.doc 1 Data null null
表 2
ID TYPE NAME SEQUENCE SIZE SKIP
1 doc A Number 1 9 3
1 doc C Number 2 10 1
1 doc Total 3 10 0
1 doc Date 4 8 2
1 doc Data 5 80 0
1 doc Type 6 1 0
表1和表2的解释,表1和2中的记录是“csv”文件的结构
在 table1 和 table2 中都将具有类型和 id,所有记录都相同。
表1说明:
在第一条记录中,“A Number”和“FROMPOS”(FROM POSITION)值为4,这意味着前三个字符将是空格,帐号将在后面,即从第4个position到第12个position作为“大小” “A Number”的值为 9,对于“C Number”,我们跳过 position 并从 14 到 23 开始,因为该字段的“大小”为 10,对于所有其他记录也是如此。 Table1 列中的“NULL”可以忽略
表2说明:
Table2没有“FROMPOS”列,但有序列,表示csv中记录的输入顺序,Table1是旧格式,table2是新格式。
因此,在这两个表中,记录实际上将表示相同的格式,但方式不同。两个表中的类型、ID 和 SIZE 将相同
所以在表2中,“A Number”的“SEQUENCE”为1,“SKIP”是要跳过的字符数,即这里的“3”,所以它将从第4位开始,应该与表1中的“FROMPOS”匹配
类似地,“C Number”的“SEQUENCE”为 2,“SKIP”为 1,因此它将在“A Number”之后跳过 1 位,即它将跳过第 13 位并从 14 开始,“SIZE”为 10,因此以 23 结束.
同样,“Total”将从 24 开始,因为没有“SKIP”,长度为 10,并在第 34 位结束。 同样,它适用于所有记录。
我的目标是写一个 SQL 以确保表 2 中的 SEQUENCE、SKIP、SIZE 与表 1 中的 FROMPOS 和 SIZE 匹配
在 CSV 文件中考虑这种格式,
123456789, 1234567890,1000000, 24/06/20
注意:我尝试加入表格并且成功,但我无法编写逻辑来确保表 2 中的 SEQUENCE、SKIP、SIZE 与表 1 中的 FROMPOS 和 SIZE 匹配。 如果他们匹配我需要“成功”,如果他们不匹配需要“失败”
我是SQL的新手,我开始做这个项目来学习,坚持了4天。请帮助解决这个问题
您可以编写查询以使用分析 function 将表 2 数据转换为与表 1 相同格式的数据,然后将其与表 1 进行检查,如下所示:
Select t1.*, t2.*,
Case when t1.frompos = t2.frompos and t1.size = t2.size
then 'SUCCESS'
else 'FAIL'
end as result
from table1 t1 join
(Select t.id, t.type, t.name, t.sequence, t.size, t.skip,
sum(skip+size) over (partition by t.id, t.type order by t.sequence)
- size + 1 as frompos,
t.size
From table2 t) t2
On t1.id = t2.id
And t1.type = t2.type
And t1.name = t2.name
注意:根据您的要求添加处理 null 的条件。
这个查询:
with a as (
select id, name, frompos, size_, type,
row_number() over (partition by id order by frompos) sequence,
frompos - lag(frompos, 1, 0) over (partition by id order by frompos)
- lag(size_, 1, 0) over (partition by id order by frompos)
- case when row_number() over (partition by id order by frompos) = 1
then 1 else 0
end as skip
from table1 )
select id, sequence, a.name, b.name, a.type a_type, b.type b_type, a.frompos,
a.size_ as a_size, a.skip as a_skip,
b.size_ as b_size, b.skip as b_skip
from a full join table2 b using (id, sequence)
为您的数据提供此结果:
ID SEQUENCE NAME NAME A_TYPE B_TYPE FROMPOS A_SIZE A_SKIP B_SIZE B_SKIP
1 1 A Number A Number .doc doc 4 9 3 9 3
1 2 C Number C Number .doc doc 14 10 1 10 1
1 3 Total Total .doc doc 24 10 0 10 0
1 4 Date Date .doc doc 36 8 2 8 2
1 5 Data Data .doc doc 80 0
1 6 Type doc 1 0
根据需要在比较空值case when
。 第一行略有不同,我必须减去 1。我将size
更改为size_
, Oracle 不喜欢它作为列名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.