除了返回不可预测的结果

时间:2015-05-20 14:31:32

标签: sql sql-server except

我有一个表DB_Budget,其中包含3列Business_Unit_CodeLedger_PeriodBudget_GBP。为简单起见,我遗漏了其他专栏。

数据类型是 -

enter image description here

此表存在于我的开发和生产环境中。

在进行一些质量检查时,我运行了以下查询:

select 
Business_Unit_Code,
Ledger_Period,
Budget_GBP
from [SomeLinkedServer].[Database].dbo.DB_BUDGET
where business_unit_code = 'AV' and ledger_period = '200808'
and budget_gbp >= 32269

except

select 
Business_Unit_Code,
Ledger_Period, 
Budget_GBP
from [Database].dbo.DB_BUDGET
where business_unit_code = 'AV' and ledger_period = '200808'
and budget_gbp >= 32269

我得到了这个 -

enter image description here

如果我删除了除外,这就是我得到的 -

enter image description here

显然,两个表中的数据都相同!为什么EXCEPT会给我一行?

事情变得有趣。我在Budget_GBP构造周围包裹LTRIM(RTRIM( ...。 事情相匹配!

我做了一点googling,发现LTRIM(RTRIM(基本上将浮点数舍入为32269.2。这可能就是他们匹配的原因。

总而言之,我的第一个问题是为什么EXCEPT在记录匹配时会在结果中显示一行?

我的第二个问题可能很简单。如您所见,我被限制在budget_gbp >= 32269子句中使用WHERE子句。原因是当我提供确切的值(我从SSMS复制)时,我没有得到任何结果。请让我知道我在这里做错了什么。

编辑 - 数据验证有什么办法可行吗?数据库中有100个表,我几乎不可能清除float columsn并将它们包裹在cast中。使用EXCEPT是在开发环境中验证数据的一种方法。

2 个答案:

答案 0 :(得分:2)

将值转换为定点类型或字符串,然后重新运行代码。第一个查询看起来像:

select Business_Unit_Code, Ledger_Period, cast(Budget_GBP as decimal(18, 2)) as Budget_GBP

有了数字,你看到的并不总是你得到的。所以你看到32669.19,但它可能真的是32.669.189999。

答案 1 :(得分:2)

您可以定义准确度并检查该值是否在彼此的指定精度范围内。

declare @accuracy  float = 0.001

select * 
  from      DB_BUDGET1 t1
  full join DB_BUDGET2 t2 
    on  t1.Business_Unit_Code=t2.Business_Unit_Code
    and t1.Ledger_Period     =t2.Ledger_Period
    and t1.Budget_GBP between t2.Budget_GBP-@accuracy  and t2.Budget_GBP+@accuracy 
  where t1.id is null
     or t2.id is null

http://www.sqlfiddle.com/#!3/41da0/2/0