如何测试 table 中的所有行是否重复(一列除外)
How can I test whether all of the rows in a table are duplicated (except for one column)
我正在使用一个数据仓库 table,它可以分为声明的行和计算的行。
我怀疑计算出的行是声明行的完美副本(claimed/computed 列除外)。
我尝试使用 except 子句对此进行测试:
但是所有的记录都被返回了。我不相信这是可能的,我怀疑这是由于空值造成的。
有没有办法比较将空值与空值进行比较的记录?
SELECT a, b, c FROM table WHERE clm_cmp_cd = 'clm'
EXCEPT
SELECT a, b, c FROM table WHERE clm_cmp_cd = 'cmp'
但是所有的记录都被返回了。我不相信这是可能的,我怀疑这是由于空值造成的。
有没有办法比较将空值与空值进行比较的记录?
编辑:该解决方案应该适用于任意数量的不同类型的字段。在这种情况下,我有大约 100 个字段,其中 2/3 可能具有空值。这是一个数据仓库,必须预料到一定程度的非规范化。
编辑:我在将自己限制为非空列的同时测试了查询,并且得到了预期的结果(无)。
但是,我仍然想比较可能包含空值的字段。
您的假设似乎是错误的。你可以试试这个:
select a, b, c,
sum(case when clm_cmp_cd = 'clm' then 1 else 0 end) as num_clm,
sum(case when clm_cmp_cd = 'cmp' then 1 else 0 end) as num_cmp
from t
group by a, b, c;
这将显示三列的值以及每种类型的匹配数。
您的问题可能是看起来相似的值并不完全相同。这可能是由于浮点数略有不同或字符串中的字符不匹配,例如前导空格。
让我们看看 Db2 如何使用 GROUP BY
和 INTERSECT
中的 NULL
值:
with t(a, b, clm_cmp_cd) as (values
( 1, 1, 'clm')
, ( 1, 1, 'cmp')
, (null, 1, 'clm')
, (null, 1, 'cmp')
, ( 2, 1, 'cmp')
)
select a, b
from t
where clm_cmp_cd='clm'
intersect
select a, b
from t
where clm_cmp_cd='cmp';
with t(a, b, clm_cmp_cd) as (values
( 1, 1, 'clm')
, ( 1, 1, 'cmp')
, (null, 1, 'clm')
, (null, 1, 'cmp')
, ( 2, 1, 'cmp')
)
select a, b
from t
where clm_cmp_cd in ('clm', 'cmp')
group by a, b
having count(1)>1;
两个查询 return 相同的结果:
A B
-- --
1 1
<null> 1
NULL
这些运算符将值视为相同。
如果您的 table 中的列太多而无法在查询中手动指定它们,您可以使用以下查询生成列列表:
select listagg(colname, ', ')
from syscat.columns
where tabschema='MYSCHEMA' and tabname='TABLE' and colname<>'CLM_CMP_CD';
我正在使用一个数据仓库 table,它可以分为声明的行和计算的行。 我怀疑计算出的行是声明行的完美副本(claimed/computed 列除外)。
我尝试使用 except 子句对此进行测试:
但是所有的记录都被返回了。我不相信这是可能的,我怀疑这是由于空值造成的。
有没有办法比较将空值与空值进行比较的记录?
SELECT a, b, c FROM table WHERE clm_cmp_cd = 'clm'
EXCEPT
SELECT a, b, c FROM table WHERE clm_cmp_cd = 'cmp'
但是所有的记录都被返回了。我不相信这是可能的,我怀疑这是由于空值造成的。
有没有办法比较将空值与空值进行比较的记录?
编辑:该解决方案应该适用于任意数量的不同类型的字段。在这种情况下,我有大约 100 个字段,其中 2/3 可能具有空值。这是一个数据仓库,必须预料到一定程度的非规范化。
编辑:我在将自己限制为非空列的同时测试了查询,并且得到了预期的结果(无)。 但是,我仍然想比较可能包含空值的字段。
您的假设似乎是错误的。你可以试试这个:
select a, b, c,
sum(case when clm_cmp_cd = 'clm' then 1 else 0 end) as num_clm,
sum(case when clm_cmp_cd = 'cmp' then 1 else 0 end) as num_cmp
from t
group by a, b, c;
这将显示三列的值以及每种类型的匹配数。
您的问题可能是看起来相似的值并不完全相同。这可能是由于浮点数略有不同或字符串中的字符不匹配,例如前导空格。
让我们看看 Db2 如何使用 GROUP BY
和 INTERSECT
中的 NULL
值:
with t(a, b, clm_cmp_cd) as (values
( 1, 1, 'clm')
, ( 1, 1, 'cmp')
, (null, 1, 'clm')
, (null, 1, 'cmp')
, ( 2, 1, 'cmp')
)
select a, b
from t
where clm_cmp_cd='clm'
intersect
select a, b
from t
where clm_cmp_cd='cmp';
with t(a, b, clm_cmp_cd) as (values
( 1, 1, 'clm')
, ( 1, 1, 'cmp')
, (null, 1, 'clm')
, (null, 1, 'cmp')
, ( 2, 1, 'cmp')
)
select a, b
from t
where clm_cmp_cd in ('clm', 'cmp')
group by a, b
having count(1)>1;
两个查询 return 相同的结果:
A B
-- --
1 1
<null> 1
NULL
这些运算符将值视为相同。
如果您的 table 中的列太多而无法在查询中手动指定它们,您可以使用以下查询生成列列表:
select listagg(colname, ', ')
from syscat.columns
where tabschema='MYSCHEMA' and tabname='TABLE' and colname<>'CLM_CMP_CD';