【问题标题】:How to select one to one relations from many to many table如何从多对多表中选择一对一关系
【发布时间】:2016-03-07 12:48:20
【问题描述】:

我有一个数据库,用于保存书籍及其作者。在我的模型中,一个作者可以有很多本书,而一本书可以由多个作者写。示例:

AUTHOR_ID|BOOK_ID
1|100
1|200
1|300
2|300
3|300
4|400

我正在努力寻找只写了一本书的作者,而那本书只能由该作者本人撰写。在上面的例子中,只有有效的作者是 AUTHOR_ID = 4。
我需要编写一个选择来获取满足上述要求的作者 ID,我该如何编写快速高效的选择来做到这一点?

【问题讨论】:

    标签: sql database relational-database


    【解决方案1】:
    select *
    from BookAuthors t1
    where not exists (select * from BookAuthors t2
                      where t2.BOOK_ID = t1.BOOK_ID
                        and t2.Author_ID <> t1.Author_ID)
      and not exists (select * from BookAuthors t3
                      where t3.Author_ID  = t1.Author_ID
                        and t3.BOOK_ID <> t1.BOOK_ID)
    

    第一个NOT EXISTS 是为了确保同一个bookid 没有第二个作者。

    第二个NOT EXISTS 用于确保相同的 Author_ID 没有写过另一本书。

    组合版:

    select *
    from BookAuthors t1
    where not exists (select * from BookAuthors t2
                      where (t2.BOOK_ID = t1.BOOK_ID
                             and t2.Author_ID <> t1.Author_ID)
                         or (t2.Author_ID  = t1.Author_ID
                             and t2.BOOK_ID <> t1.BOOK_ID))
    

    【讨论】:

      【解决方案2】:

      这是一个单独的答案,因为第一个是错误的。

      如果你的数据库支持窗口函数,一种方法是:

      select Author_ID
      from (select ba.*, count(*) over (partition by Author_ID) as numBooks,
                   count(*) over (partition by Book_ID) as numAuthors
            from BookAuthors ba
           ) ba
      where numBooks = 1 and numAuthors = 1;
      

      通过将条件移至where 子句或joins 也有多种方法:

      select ba.*
      from BookAuthors ba
      where Author_ID in (select Author_Id from BookAuthors group by Author_Id having count(*) = 1) and
            Book_ID in (select Author_Id from BookAuthors group by Book_ID having count(*) = 1);
      

      【讨论】:

        猜你喜欢
        • 2017-01-24
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多