如何在具有多个条件的表格之间找到差异。

huangapple go评论57阅读模式
英文:

How to find difference between table with multiple conditions

问题

我有两个精确的表格,但有一些值的差异。所以我想要找出那些在列value的差异超过10的情况下的不同之处。

例如,两个表中的所有9列都具有相同的值,但值列之间的差异为11,因此这个记录是不同的。如果值的差异是9,那么记录是相同的。

所以我编写了这个查询来获取差异:

select * 
from test.test m 
inner join test.test1 t 
on
m.month_date = t.month_date and  
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and 
m.level_3 = t.level_3 and 
m.level_4 = t.level_4 and 
m.level_header = t.level_header and 
m.unit = t.unit and 
m.model_type_id = t.model_type_id and 
m.model_version_desc = t.model_version_desc 
where m.month_date = '2022-11-01' and abs(m.value - t.value) > 10

这将返回所有列值匹配但未通过值差异条件的记录。

其次,我有一个全外连接以获取所有差异:

select * 
from test.test m 
full outer join test.test1 t 
on
m.month_date = t.month_date and  
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and 
m.level_3 = t.level_3 and 
m.level_4 = t.level_4 and 
m.level_header = t.level_header and 
m.unit = t.unit and 
m.model_type_id = t.model_type_id and 
m.model_version_desc = t.model_version_desc 
where (m.month_date is null or t.month_date is null) and m.month_date = '2022-11-01'

这样可以获取所有差异。

如何将这两个查询的结果合并而不使用UNION?我想要只有一个查询(子查询也可以接受)。

英文:

I have exact two tables but some value differences. So I would like to find those differences with condition that if the column value has a difference of more than 10.

For example, all 9 columns have the same values in both tables, but the difference between the values column is 11, so this record is different. If the value difference is 9 so records are the same.

So I wrote this query to get differences:

select * 
from  test.test m 
inner join test.test1 t 
    on
m.month_date = t.month_date and  
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and 
m.level_3 = t.level_3 and 
m.level_4 = t.level_4 and 
m.level_header = t.level_header and 
m.unit = t.unit and 
m.model_type_id = t.model_type_id and 
m.model_version_desc = t.model_version_desc 


where m.month_date = '2022-11-01' and abs(m.value - t.value)  > 10)

so this returns me all records that all column values are matched but did not pass the value difference condition.

Second, i have full outer join to get all differences

select  *
from  test.test m 
full outer join test.test1 t 
    on
m.month_date = t.month_date and  
m.level_1 = t.level_1 and
m.level_2 = t.level_2 and 
m.level_3 = t.level_3 and 
m.level_4 = t.level_4 and 
m.level_header = t.level_header and 
m.unit = t.unit and 
m.model_type_id = t.model_type_id and 
m.model_version_desc = t.model_version_desc 


where m.month_date is null  or t.month_date is null and  m.month_date = '2022-11-01'

How can I combine the results of these two queries without UNION? I want to have only one query (sub query is acceptable)

答案1

得分: 0

在你的第一个查询中,你可以替换特定数字的空值。类似于这样:

    where m.month_date = '2022-11-01' and abs(ISNULL(m.value, -99) - ISNULL(t.value, -99)) > 10)

上面的代码将把空值替换为-99(根据你的数据选择适当的值)。所以,如果你有m.value为10而t.value为空,那么应该在你的第一个查询中返回。

英文:

In your first query, you can replace the null values for a specific number. Something like this:

    where m.month_date = '2022-11-01' and abs(ISNULL(m.value,-99) - ISNULL(t.value,-99))  > 10)

The above will replace the nulls for -99 (choose an appropriate value for your data), so if you have that m.value is 10 and t.value is null, then should be returned in your first query.

答案2

得分: 0

假设对于给定的日期,您需要查找以下部分:

  • 表之间匹配但超出“value”差异阈值的行

    并且

  • 在左表或右表中存在的行,没有在另一个表中有对应的行

select *
from test.test m
    full outer join test.test1 t
        using (
         month_date,
         level_1,
         level_2,
         level_3,
         level_4,
         level_header,
         unit,
         model_type_id,
         model_version_desc )
where (m.month_date is null
       or    t.month_date is null
       and   m.month_date = '2022-11-01'  )
or    (m.month_date = '2022-11-01' and abs(m.value - t.value) > 10);

在线演示

由于用于连接表的列具有相同的名称,您可以通过将冗长的“table1.column1 = table2.column1和...”列对列表替换为单个“USING (month_date,level_1,level_2,level_3,...)” (文档) 来缩短它们的列表。作为奖励,这将避免在输出中两次列出匹配的列,一次为左表,一次为右表。

select *
from (select 1,2,3) as t1(a,b,c)
    full outer join 
     (select 1,2,3) as t2(a,b,c)
        on t1.a=t2.a 
        and t1.b=t2.b 
        and t1.c=t2.c;
-- a | b | c | a | b | c
-----+---+---+---+---+---
-- 1 | 2 | 3 | 1 | 2 | 3

select *
from (select 1,2,3) as t1(a,b,c)
    full outer join 
     (select 1,2,3) as t2(a,b,c)
        using(a,b,c);
-- a | b | c
-----+---+---
-- 1 | 2 | 3
英文:

Assuming that for a given day, you need to find

  • rows that match between the tables but exceed the value difference threshold

    AND

  • rows present in either left or right table, that don't have a corresponding row in the other table

select  *
from  test.test m 
    full outer join test.test1 t 
        using (
         month_date,
         level_1,
         level_2, 
         level_3, 
         level_4, 
         level_header, 
         unit, 
         model_type_id, 
         model_version_desc )
where (m.month_date is null
       or    t.month_date is null
       and   m.month_date = '2022-11-01'  )
or    (m.month_date = '2022-11-01' and abs(m.value - t.value)  > 10);

Online demo

Since the columns used to join the tables have the same names, you can shorten their list by swapping out the lengthy table1.column1=table2.column1 and... list of pairs for a single USING (month_date,level_1,level_2,level_3,...) (doc). As a bonus, it will avoid listing the matching columns twice in your output, once for the left table, once for the right table.

select * 
from (select 1,2,3) as t1(a,b,c)
    full outer join 
     (select 1,2,3) as t2(a,b,c)
        on t1.a=t2.a 
        and t1.b=t2.b 
        and t1.c=t2.c;
-- a | b | c | a | b | c
-----+---+---+---+---+---
-- 1 | 2 | 3 | 1 | 2 | 3

select * 
from (select 1,2,3) as t1(a,b,c)
    full outer join 
     (select 1,2,3) as t2(a,b,c)
        using(a,b,c);
-- a | b | c
-----+---+---
-- 1 | 2 | 3

huangapple
  • 本文由 发表于 2023年2月6日 15:52:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定