【问题标题】:How to use EXIST in a subquery?如何在子查询中使用 EXIST?
【发布时间】:2013-11-22 17:48:50
【问题描述】:

如何使用 Exists 查询为拥有不止一本书但没有图书销售的作者显示作者信息? 我以为这是解决方案,但我又不确定。据我所知,没有一个作家没有卖过任何书。我没有收到错误。只是一个空集。对我来说已经晚了,所以也许我错过了一些东西:

 SELECT author_id
      , author_name_last
      , author_name_first
 FROM a_bkinfo.authors
 WHERE EXISTS (
   SELECT 1
     FROM a_bkinfo.book_authors BS
     JOIN a_bkorders.order_details OD on BS.book_id = OD.book_id
     WHERE quantity > 1

         )
 AND NOT EXISTS (
           SELECT MAX(orders) 
             FROM (  
                  SELECT book_id
                      ,  count(order_id) AS orders
                    FROM a_bkorders.order_details
                   GROUP BY book_id
                  HAVING count(order_id) = 1
                  ) t
        )
 ;

【问题讨论】:

  • 你为什么特别希望使用 EXISTS?

标签: mysql subquery exists not-exists


【解决方案1】:

不知道你的表定义,很难说,但我会做这样的事情:

SELECT  author_id
  , author_name_last
  , author_name_first
FROM a_bkinfo.authors
WHERE
    -- Number of book by the author is greater than 1 
    (SELECT COUNT(*)
     FROM -- table of books (a_bkinfo.book_authors?)
     WHERE -- book was written by a_bkinfo.authors.author_id) > 1

    -- Number of book sales is zero
    AND NOT EXISTS (
           SELECT * 
           FROM -- table of book orders (a_bkorders.order_details)
           JOIN -- table of books joining the orders with the corresponding books 
           WHERE -- book was written by a_bkinfo.authors.author_id
    )

【讨论】:

    【解决方案2】:

    您实际上缺少 2 个相关的东西:两个子查询实际上都没有引用外部表 a_bkinfo.authors 中的任何列,因此它们实际上都没有选择您想要选择的东西。

    如果您将子查询拉出并单独运行它们,它们似乎都将自己运行这是错误的。在外部查询中,您需要给 a_bkinfo.authors 一个别名,例如“a”,然后内部子查询需要是 WHERE [something] = a.author_idWHERE [something] = a.book_id

    如果查询在逻辑上是合理的,它会起作用,但不会是最佳的,因为您不太可能从 EXISTS 获得与从 JOIN 获得相同的效率。

    现在,第一个子查询为外部查询中的每个作者返回 EXISTS = TRUE,只要一个作者,任何作者,至少写过 2 本书......第二个子查询返回 EXISTS =对外部查询中的每个作者都为 TRUE,因为它每次都在计算并返回“任何”作者的最大订单数。

    据我在这里看到的,数据库设计也存在缺陷,因为 a_bkinfo.authors 包含一个 author_id,它可能代表作者表中的一个 id,但还包含作者的名字和姓氏的副本,不应将其复制到每本书上,而应通过另一个联接从该作者表中获取。

    但根据我从您的数据中可以得出的结果,这里有一个更优化的查询。

    SELECT author_id,
           author_name_last,
           author_name_first,
           COUNT(DISTINCT(a.book_id)) as books_written,
           COUNT(od.order_id) as order_count
      FROM a_bkinfo.authors a
      LEFT JOIN  
      JOIN a_bkorders.order_details od ON od.book_id = a.book_id
     GROUP BY a.author_id
    HAVING written_count > 1
       AND order_count = 0;
    

    对于 bkinfo.authors 表中的每个 author_id,我们将通过计算我们找到的唯一 book_id 值来计算他们写了多少本书,然后我们将计算 order_id 的数量,并且 HAVING 子句重构结果集为written_count > 1 and order_count = 0;

    orders 表的大小可能使得EXISTS 检查订单会更快,因为大量订单是针对作者只写了一本书的书。

    【讨论】:

      猜你喜欢
      • 2019-03-13
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多