英文:
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 thresholdAND
-
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);
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论