【问题标题】:Two databases interpreting data differently两个数据库以不同方式解释数据
【发布时间】:2014-02-28 16:46:32
【问题描述】:

这是迄今为止我在 SQL Server 中遇到的最奇怪的事情:

数据库 1: 表A ID,字段XYZ

表B ID,字段XYZ

DB2: 表A ID,字段XYZ

表B ID,字段XYZ

Query 1 in DB1:
Select *, 'Unmapped' as Flag 
FROM TableA 
Where NOT EXISTS (Select * FROM TableB B JOIN TableA A ON ISNULL(B.XYZ,'')=ISNULL(A.XYZ,''))

Result:
Id , XYZ , Flag   
23         unmapped   ---- Field XYZ here is blank, not NULL, just blank


Query 1 in DB2:
    Select *, 'Unmapped' as Flag 
    FROM TableA 
    Where NOT EXISTS (Select * FROM TableB B JOIN Table A ON ISNULL(B.XYZ,'')=ISNULL(A.XYZ,''))

Result:
Id , XYZ , Flag   --- I don't get any results in the DB2 for the same data as DB1

如果我在 DB1 中修改我的查询如下,那么我不会得到任何“未映射”的东西:

Query 2 in DB1:
Select *, 'Unmapped' as Flag 
FROM TableA 
Where NOT EXISTS (Select * FROM TableB B JOIN TableA A ON ISNULL(B.XYZ,'')=ISNULL(A.XYZ,'') OR A.XYZ = ' ') -- there is a space here in A.XYZ = ' '

如果在两个数据库中运行以下查询,我会从每个数据库中获取一条记录:

SELECT * FROM DB1.dbo.TableA where FieldXYZ = ' ' -- space within quotes

SELECT * FROM DB2.dbo.TableA where FieldXYZ = ' ' -- space within quotes

那么 db1 中的查询 1 发生了什么?

【问题讨论】:

  • JOIN ON 在语法上不正确,所以我很难相信这些查询中的任何一个都会产生任何结果。
  • 是否有不同的字段 "FieldXYZ" 和 "XYZ" ?您在示例查询中都提到了这两个。
  • 它们是一样的,我为错字道歉。我在这里寻找的更多是对我的问题的概念性答案,而不是实际代码。
  • 您的WHERE NOT EXISTS 中的子查询不应该引用主查询中的TableA 吗?由于您要加入一个新的 TableA 变量,我希望您的结果具有误导性。
  • 您能否在两个数据库上运行 NOT EXISTS 查询“Select * FROM TableB B JOIN TableA A ON ISNULL(B.XYZ,'')=ISNULL(A.XYZ,'')”并检查如果你得到相同的结果?

标签: sql sql-server sql-server-2008


【解决方案1】:

如果您想要 TableA 中与 TableB 不匹配的所有记录,那么您的查询是错误的。

你真的想要这个:

SELECT TableA.*, 'Unmapped' as Flag 
FROM TableA
LEFT OUTER JOIN TableB
ON ISNULL(TableA.XYZ,'') = ISNULL(TableB.XYZ,''))
WHERE TableB.ID IS NULL

这是您的查询正在执行的操作:

Select *, 'Unmapped' as Flag 
FROM TableA 
Where NOT EXISTS (
    Select *
    FROM TableB B
    JOIN TableA A
    ON ISNULL(B.XYZ,'')=ISNULL(A.XYZ,'')
)
  1. 尝试在XYZ 字段中将TableATableB 匹配。
  2. 如果没有任何记录匹配,则返回来自TableA 的所有记录。

另一种选择是:

Select *, 'Unmapped' as Flag 
FROM TableA 
Where NOT EXISTS (
    Select *
    FROM TableB B
    WHERE ISNULL(B.XYZ,'') = ISNULL(TableA.XYZ,'')
)

请注意,子查询引用回主查询中的TableA

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,如果您只在两个数据库中运行 NOT EXISTS 查询,您将看到这些数据库的结果相同的差异。所以我的观点是问题不在“NOT EXISTS”子句中,而是在该查询中使用的“ISNULL”条件中。

    这就是为什么我们不应该使用“ISNULL”函数来检查列的NULL值,而是使用“IS NULL”子句。

    Do not use ISNULL to find NULL values. Use IS NULL instead

    如果您按以下方式更改查询,您应该会很好并看到相同的结果。

        Select * 
        FROM TableB B 
        JOIN Table A ON 
            (CASE WHEN B.XYZ IS NULL THEN '' ELSE B.XYZ END)
            =
            (CASE WHEN A.XYZ IS NULL THEN '' ELSE A.XYZ END)
    

    【讨论】:

      猜你喜欢
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 2016-09-23
      • 2017-05-05
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多