对数据库查询感到疯狂

时间:2017-01-23 23:06:37

标签: sql advantage-database-server

请原谅我的模糊标题。我很想知道某个数据库查询发生了什么。对我来说不幸的是,我们使用此查询来列出要执行的操作,并且由于我不理解的原因导致任务被删除。我一直在尝试调试查询的“mininal”版本。

让我解释一下我想要找到的东西。我们的实践有“考试”,基本上只是与医生的互动。我们为其中一些考试开账单,我们会跟踪我们的分类账表中的账单。 (换句话说,我们在处理账单时插入Ledger)

现在,如果我进行查询:

 SELECT Patient.PatUnique,
        Exam.ExamUnique,
        Exam.[Date],
        Patient.Last,
        Patient.First

 FROM Patient
 INNER JOIN Exam ON Patient.PatUnique = Exam.PatUnique

这会产生您可能期望的结果:患者和日期列表以及ExamUnique数字(我们在Exam表中的键)。

但如果我像这样修改查询:

SELECT Patient.PatUnique,
       Exam.ExamUnique,
       Exam.[Date],
       Patient.Last,
       Patient.First

  FROM Patient
  INNER JOIN Exam ON Patient.PatUnique = Exam.PatUnique
  WHERE Exam.ExamUnique NOT IN (SELECT Ledger.ExamUnique FROM Ledger)

我得到 0 条记录。另一方面,我知道 Exam.ExamUnique表中没有Ledger个。让我们将其匿名为X。我跑了:

SELECT Ledger.ExamUnique FROM Ledger WHERE Ledger.ExamUnique = X

并没有结果。所以X就在那里。

我错过了什么?

以下是一些示例数据,因为有人认为它会有所帮助:

Patient.PatUnique      Patient.Last      Patient.First
1                      Smith             Adam
2                      Jones             Sarah

Exam.ExamUnique      Exam.PatUnique      Exam.Date
1                    1                   01012016
2                    1                   01022016
3                    2                   01032016

Ledger.ExamUnique
1
2

查询的预期结果:

Patient.PatUnique  Exam.ExamUnique  Exam.Date  Patient.Last  Patient.First
2                  3                01032016   Jones         Sarah

实际结果:

0 records

1 个答案:

答案 0 :(得分:0)

评论者非常有帮助地建议我将查询转换为:

SELECT Patient.PatUnique,
       Exam.ExamUnique,
       Exam.[Date],
       Patient.Last,
       Patient.First

FROM Patient
INNER JOIN Exam ON Patient.PatUnique = Exam.PatUnique
LEFT OUTER JOIN Ledger ON Exam.ExamUnique = Ledger.ExamUnique
WHERE Ledger.ExamUnique IS NULL

这在逻辑上等同于我试图调试的原始查询,并且它可以工作。显然,第一个查询是在Advantage数据库中触发了一个错误,因为逻辑上等效的查询应该会产生相同的结果(但这些结果并不是这样)。

一位评论者有用地指出这些查询在逻辑上并不相同,因为我隐含地使用原始查询对NULL进行比较。新查询与IS NULL进行了明确的比较,因此它避免了导致原始查询错误的未定义行为。