【问题标题】:Find authors who ONLY wrote history books寻找只写历史书的作者
【发布时间】:2018-11-13 21:53:23
【问题描述】:

SQL 新手,虽然很流行 - 卡在这个查询上。 虽然 Paddy O'Furniture 不应该出现,但这是可行的,因为该作者没有写过任何书,并且他的 au_id 没有出现在 title_authors 表中。请帮忙。

寻找只写历史书的作者

选择 a.au_id、a.au_lname、a.au_fname

来自作者

哪里不存在(

    选择 ta.au_id

    来自 title_authors ta

    加入标题 t

    在 t.title_id = ta.title_id

    其中 t.type != '历史'

    和 a.au_id = ta.au_id

)

输出:

A01 布赫曼莎拉

A07 O'Furniture Paddy

【问题讨论】:

    标签: sql


    【解决方案1】:

    Paddy O'Furniture 在您的结果中,因为在相关子查询中未发现匹配行。即该作者没有行exist,因此where not exists 为真。

    select a.au_id, a.au_lname, a.au_fname
    from authors a
    inner join title_authors ta ON a.au_id = ta.au_id
    inner join titles t on ta.title_id = t.title_id
    group by a.au_id, a.au_lname, a.au_fname
    having count(case when t.type <> 'history' then 1 end) = 0
    

    上述方法在 count() 函数中使用 case 表达式,因此如果任何书籍具有非历史类型,则该计数将大于零。 having 子句允许使用聚合值来过滤最终结果(在group by 子句之后使用,并且不能替代where 子句)。

    【讨论】:

    • 谢谢。这个解释帮助我开始。我有很多东西要学。
    【解决方案2】:

    如果您使用另一个exists 来确保作者至少写过一本历史书,那么您的方法可以奏效,但这是使用conditional aggregation 的另一种方法:

    select a.au_id, a.au_lname, a.au_fname
    from authors a
        join title_authors ta on a.au_id = ta.au_id
        join titles t on ta.title_id = t.title_id
    group by a.au_id, a.au_lname, a.au_fname
    having sum(case when t.type != 'history' then 1 else 0 end) = 0
    

    Online Demo

    【讨论】:

    • 感谢您的帮助。
    【解决方案3】:

    你很接近。在外部查询中将JOIN 添加到title_authors 将过滤掉没有写过书的作者。

    select a.au_id, a.au_lname, a.au_fname
    from authors a
    join title_authors ta1 on ta1.au_id = a.au_id
    where not exists(
        select 1
        from title_authors ta
        join titles t on t.title_id = ta.title_id
        where t.type != 'history' and ta1.id = ta.id
    )
    

    内部查询中的title_authors实际上可以删除。

    select a.au_id, a.au_lname, a.au_fname
    from authors a
    join title_authors ta on ta.au_id = a.au_id
    where not exists(
        select 1
        from titles
        where t.type != 'history' and title_id = ta.title_id
    )
    

    【讨论】:

    • 我喜欢这个,但是我不理解“选择 1”——也许我的课程还不够远,无法理解这一点。
    猜你喜欢
    • 2016-01-04
    • 2012-08-21
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多