从视图中选择 - 意外的副作用

时间:2009-09-17 10:20:04

标签: sql-server

我遇到了一个嵌入在应用程序中的奇怪查询(是的,太棒了!):

SELECT PersonId
    , Salutation
    , Email
    , Postcode
FROM    vw_NewsletterSubscriptions
WHERE    PersonId IN (SELECT PersonId FROM vw_NewsletterSubscriptions) 
    AND NewsletterTypeID=1 
    AND UnSubscribeDate Is NULL
GROUP BY PersonId
    , Salutation
    , Email
    , Postcode

这是WHERE子句中的SELECT。它似乎在说“从视图中选择数据在视图中的一些数据”,这有点不必要。所以我在WHERE子句中注释掉了这一行:

SELECT PersonId
    , Salutation
    , Email
    , Postcode
FROM    vw_NewsletterSubscriptions
WHERE    NewsletterTypeID=1 
    AND UnSubscribeDate Is NULL
GROUP BY PersonId
    , Salutation
    , Email
    , Postcode

为了完整性,我运行了两个版本来检查它们是否完全相同而不是。新版本返回更多行 - 不在第一个版本中的行。我已经加入了两套以查看差异,但是额外的行没有明显不同。

我在这里显然遗漏了一些东西。你能解释一下发生了什么吗?

5 个答案:

答案 0 :(得分:2)

PersonID中是否有任何带NULL的行 - 在第一个查询中会被IN子句过滤掉,但在第二个查询中没有被过滤掉,所以会解释第二个查询返回更多行。

如果您可以发布一些样本数据(包含名称和其他识别数据以保护假定的无辜者),可能会有所帮助 - 只出现在一行中的行样本和出现在两者中的行。

(另外,这个问题可能更适合StackOverflow)

答案 1 :(得分:0)

如果NULL不是问题(正如David Spillett建议的那样),那么最好的策略是开始详细查看哪些行包含在一个而不是另一个中,看看你是否可以弄清楚他们有什么不同。

如果这对任何事都没有帮助,你将不得不开始深入研究底层视图的定义,看看是否能给你提供任何线索。视图可以包含复杂的连接,过滤器,UNIONS,触发器和其他令人讨厌的东西。

如果视图足够简单,请尝试构造引用基础表的查询...看看你是否得到了相同的古怪行为。

答案 2 :(得分:0)

我假设这是ms sql server(我看到sql-server标签),但如果不是,请澄清。我用750插入数据库的假行测试了这个。我的数据都很好(没有空的地方应该没有),我无法复制你的问题。我必须假设它是某种数据问题。我没有看到如何在不看数据的情况下解决问题。您可能想要尝试的一件事是将视图中的数据转储到常规表(只是引用的字段)。看看查询是否对常规表失败会很有趣。另外,如果你只限于5或6个引用字段,那么你可能会跳出一些东西。

-don

答案 3 :(得分:0)

PersonId IN (SELECT PersonId FROM vw_NewsletterSubscriptions)

意味着

PersonId IS NOT NULL

您可以将此条件添加到查询中

答案 4 :(得分:0)

感谢所有的想法,伙计们。我将查询的结果与看似不必要的条款进行了比较,如果我能看到一个模式,我就该死了。视图是一个过于复杂的混乱,所以我重构它,现在我得到相同数量的行。此外,我们的新闻通讯订阅者数量也增加了!