从两个表中选择比预期更多的行

Posted

技术标签:

【中文标题】从两个表中选择比预期更多的行【英文标题】:Select from two tables giving more rows than expected 【发布时间】:2012-01-12 18:07:20 【问题描述】:

我不确定为什么会这样。我需要根据一些标准从两个表中选择几个值,这些标准应该从我下面尝试的查询中清楚。

query = @"SELECT n.borrower, a.sum, n.lender FROM Notification AS n, Acknowledgment AS a 
          WHERE n.deleted=@del2 AND n.id IN (SELECT parent_id FROM Acknowledgment
                                             WHERE status=@status AND deleted=@del1)";

这会返回比预期更多的行 (12)。

我有两个表 Notification 和 Acknowledgement 都有字段“sum”。当我尝试下面的查询时,它会按预期给出正确的 3 行。

@"SELECT n.borrower, n.sum, n.lender FROM Notification AS n 
  WHERE n.deleted=@del2 AND n.id IN (SELECT parent_id FROM Acknowledgment
                                     WHERE status=@status AND deleted=@del1)";

现在我需要扩展这个查询,以便我需要a.sum 而不是n.sum。但是当我尝试第一个查询时,它提供了更多的行,我的意思是 WHERE 条件不起作用。我不知道它是 MS Access 的怪癖还是查询有问题。如果我的查询看起来不错,我很欣赏访问中的替代实现,因为它根本不起作用! :)

我读过here,不同的数据库以不同的方式实现选择。不知道它是否具有特定的访问权限..

根据 Li0liQ 的建议,我尝试了这个:

@"SELECT n.borrower, a.sum, n.lender FROM Notification AS n 
  INNER JOIN Acknowledgment AS a ON a.parent_id = n.id AND a.status=@status AND a.deleted=@deleted1 
  WHERE n.deleted=@deleted2"

但我现在收到“不支持 JOIN 表达式”错误。

【问题讨论】:

【参考方案1】:

由于笛卡尔积,这是预期的行为:

FROM Notification AS n, Acknowledgment AS a

如果您有 10 个通知和 5 个确认,您将在结果中获得 50 行,代表通知和确认的所有可能组合。然后该集合由WHERE 子句过滤。 (这是 SQL 的标准,并非特定于 MS Access。)

听起来你需要JOIN

FROM Notification AS n INNER JOIN Acknowledgement AS a ON n.id = a.parent_id

然后你可以摆脱子查询:

WHERE n.deleted=@del2 AND a.status=@status AND a.deleted=@del1

编辑

应nawfal的要求,这是他得出的解决方案,它基本上包含了上述建议:

string query = @"SELECT n.borrower, a.sum, n.lender FROM Notification AS n   
           INNER JOIN Acknowledgment AS a ON a.parent_id=n.id   
           WHERE a.status=@status AND a.deleted=@deleted1 AND n.deleted=@deleted2"; 

【讨论】:

完美。和我想的差不多! 不需要子查询。必须满足这个条件! @nawfal 但应该可以通过将这些条件放入WHERE 子句来获得相同的结果,这将比子查询更有效。 是的,我不知道如何实现这一点,我的意思是我不是联接方面的专家,因此采用了子查询方法.. @nawfal 编辑您的问题以添加您的新查询文本和错误消息的全文。让加入工作应该很容易。【参考方案2】:

在第一个查询中,您似乎正在尝试执行JOIN。 但是,您最终会执行CROSS JOIN,即您从两个表中查询所有可能的组合(我敢打赌,Acknowledgment 表中有 4 行)。

我希望以下查询可以解决问题,或者至少可以帮助您朝着正确的方向思考:

SELECT
    n.borrower, a.sum, n.lender
FROM
    Notification AS n
INNER JOIN
    Acknowledgment AS a
ON
    a.parent_id = n.id
WHERE
    n.deleted=@del2 AND a.status=@status AND a.deleted=@del1

【讨论】:

这似乎是一个完美的答案。经过一些测试后回复你们:) 当我运行此查询时,我从 Access 收到“JOIN”不支持的错误消息!但我记得之前通过访问成功完成了 LEFT OUTER JOIN @nawfal 不支持联接,因为您不能在 JOIN 子句中使用 AND a.status=@status AND a.deleted=@del1。连接表达式应该将连接一侧的列关联到连接的另一侧。这些表达式仅使用 a 中的列。它们可以合并到WHERE 子句中。 @phoog 完全正确!!我现在明白你的意思了。我的错。您可以用我的帖子(最终有效)更新您的答案,以便我可以标记它吗?将来可以帮助像我这样的新手从标记为答案的代码中查看工作代码。感谢您的努力.. :)【参考方案3】:

Access 似乎有问题,我只能通过以这种方式重建回答者提供的查询来使其正常工作:

string query = SELECT n.borrower, a.sum, n.lender FROM Notification AS n 
               INNER JOIN Acknowledgment AS a ON a.parent_id=n.id 
               WHERE a.status=@status AND a.deleted=@deleted1 AND n.deleted=@deleted2;

【讨论】:

这在功能上等同于我的答案所暗示的查询。为什么您认为 Access 有问题? @phoog 功能上是的。我认为我在问题中更新的查询可以在 mysql(我更习惯使用)而不是在 Access 中正常工作。这是我在使用 MySQL 和 Access 之后的直觉。我在 MySQL 中从未遇到过任何使用 JOIN 语句的问题。如果 JOIN 语句的语法错误,我可以理解,但这里 Access 只是说不支持 JOIN 表达式。从互联网上阅读更多内容后,我可以让它工作 让我说明 MS Access 的另一个怪癖。如果我通过参数和占位符传递要更新的值,我需要 $%%^ 以 EXACT EXACT EXACT 的顺序传递它,查询读取这些值。当你有一些复杂的查询时,这变得非常艰巨'因为你不能一直在查看查询并弄清楚首先执行哪个查询,顺序等。MySQL(我相信其他强大的数据库,如 DB2 等)也没有这个问题。另一个,Access 不支持很多我可以在其他数据库中使用的***关键字。所有这些让我觉得它是一个 Access 的东西 对于上面提到的问题,请看我的这个链接..***.com/questions/7165661/…我在问题中发布的链接指出不同的数据库实现复杂的选择略有不同。这一切让我相信:)

以上是关于从两个表中选择比预期更多的行的主要内容,如果未能解决你的问题,请参考以下文章

如何从两个表中选择同一字段中具有相同值的行?

MySQL Query Join 从两个表中选择不匹配的行

如何使用从两个表中的选择查询问题检索行

Oracle 过程分页带来比预期更多的行

Oracle SQL - 从视图中选择比在视图中运行选择更多的行

子查询处理比需要更多的行