【问题标题】:Join queries properly - SQL正确连接查询 - SQL
【发布时间】:2022-01-04 05:44:37
【问题描述】:

我有两个名为BooksCo-author 的表。我想加入他们以使表格显示在“所需的输出”下。我是 SQL 新手,我正在努力加入我所做的两个查询...

书籍:

ISBN title author
1111 Book1 author1
2222 Book2 author2
3333 Book3
4444 Book4 author3

合著者:

id author book(isbn)
1 author_x 4444
2 author_y 1111
3 author_z 2222
4 author_w 4444

期望的输出:

title has_author count_co_author
Book1 1 1
Book2 1 1
Book3 0 0
Book4 1 2

我有以下疑问:

SELECT b.title, count(c.book)
FROM Books b
LEFT JOIN Coauthor c ON b.isbn = c.book
GROUP BY b.title

返回列count_co-author

另一个查询列has_author

SELECT 
    b.title, 
    CASE 
        WHEN b.author IS NULL 
            THEN 0 
            ELSE 1 
    END AS 'Has author'
FROM Books b

如何组合它们?

【问题讨论】:

  • use text, not images/links, for text--including tables & ERDs。转述或引用其他文本。只提供您需要的东西并将其与您的问题联系起来。仅将图像用于无法表达为文本或增强文本的内容。在图像中包含图例/键和说明。在给出业务关系(船舶)/关联或表(基础或查询结果)时,说明其中的一行根据其列值说明了业务情况。 Re SQL & relational querying
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出的示例输入(包括逐字错误消息);标签和版本;明确的规范和解释。对于包含最少代码的错误,您可以给出的代码是您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于 SQL 包括 DDL 和表格初始化代码。当你得到一个你不期望的结果时,暂停你的总体目标,切到第一个具有意外结果的子表达式并说出你的期望和原因,并通过文档证明是合理的。 How to AskHelp center
  • 您使用的是什么 DBMS?您应该始终使用 DBMS 标记您的 SQL 请求,以便只获得适合您的答案。

标签: sql join case


【解决方案1】:

选择书籍并加入合著者人数:

select
  b.title,
  case when b.author is null then 0 else 1 end as has_author,
  coalesce(c.cnt, 0) as count_co_author
from books b
left outer join
(
  select book, count(*) as cnt
  from co_author
  group by book
) c on c.book = b.isbn
order by b.title;

或从书籍中选择并在子查询中获取共同作者数:

select
  b.title,
  case when b.author is null then 0 else 1 end as has_author,
  (
    select count(*)
    from co_author c
    where c.book = b.isbn
  ) as count_co_author
from books b
order by b.title;

【讨论】:

    【解决方案2】:
    SELECT 
        b.title, 
        CASE
            WHEN b.author IS NULL
                THEN 0
                ELSE 1
        END AS has_author,
        count(c.book) as count-coauthor
    FROM
        Books b
    LEFT JOIN
        Coauthor c
    ON
        b.isbn = c.book
    GROUP BY
        b.title
    

    应该在 IG 上工作

    【讨论】:

    • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(近 30 年前),不鼓励使用它
    • 是的,这可能有效。要使此查询有效,标题不能为空并且在表中是唯一的,以便唯一标识 books 表中的行。也许它是独一无二的,也许不是。按 ISBN 分组似乎更安全,我认为它可以满足此要求。
    【解决方案3】:
    select  title, has_auther, count_co-author, 
    from 
    ( 
      (
        SELECT
          b.title,
          count(c.book) as count_co-author
        FROM Books b 
        LEFT JOIN Coauthor c ON b.isbn = c.book
        GROUP BY b.title
      ) as t1, 
      (
        SELECT 
          b.title, 
          CASE WHEN b.author IS NULL 
            THEN 0 
            ELSE 1 
        END AS has_auther
        FROM Books b
      ) as t2
    )
    

    试试这个

    【讨论】:

    • 您不应再使用逗号分隔的连接。大约三十年前,它们被显式连接(INNER JOINLEFT OUTER JOINCROSS JOIN 等)取代。逗号连接容易出错,因为您可能会错误地忘记连接子句,从而将您的预期内部连接呈现为交叉连接。这正是您的查询中发生的情况。您正在交叉连接两个查询结果,从而将每本书与每个共同作者计数相结合。如果有四本书,其中三本书有共同作者,您将获得 4 x 3 = 12 个结果行。
    • 逗号是交叉连接,优先级低于关键字连接。抱怨使用它是没有帮助的。阅读手册,学习语言。当表示“计数”时,它不会比使用“总和”更容易出错。 JOIN ON 在标准中定义为 COMMA WHERE。
    猜你喜欢
    • 2020-11-14
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多