繁体   English   中英

使用多个条件进行自联接

[英]Self-join using multiple conditions

确定书籍的购买详细信息,这本书是在同一日期购买的,恰好是安妮购买这本书的日期。 编写 SQL 查询以显示客户姓名和书名,以获取已识别的购买详细信息。 不要在查询结果中显示 Anne 的详细信息。

这些要求有以下 3 个表:

('B101', 'Science Revolution', 'Journal')
('B102', 'Brain Teasers', 'Aptitude')
('B103', 'India Today', 'Magazine')
('B104', 'Tech World', 'Journal')
('B105', 'Bizz world', 'Magazine') 

顾客

('C101', 'Jack')
('C102', 'Anne')
('C103', 'Jane')
('C104', 'Maria') 

购买

('P201', 'C101', 'B102', '12-Dec-19')
('P202', 'C102', 'B103', '25-Nov-19')
('P203', 'C103', 'B104', '12-Dec-19')
('P204', 'C104', 'B105', '25-Nov-19') 
('P205', 'C101', 'B101', '11-Dec-19')
('P206', 'C101', 'B106', '12-Dec-19') 

我对上述要求使用了以下逻辑

select 
    b.bookname, c.custname 
from 
    customer c 
join 
    purchase p on c.custid > p.custid 
join 
    purchase p1 on p.custid > p1.custid 
                and p.purchasedate = p1.purchasedate 
join 
    book b on b.bookid = p1.bookid 
group by 
    b.bookname, c.custname;

谁能提供正确的解决方案? 只有“Maria”“Bizz world”必须出现在结果中。

步骤1

 -- -- what did Anne purchase? -- select c.custname, p.* from purchase as p join customer as c on c.custid = p.custid where c.custname = 'Anne';
 客户名 | 购买ID | 监护人 | 书号 | 购买:------- |:--------- |:----- |:----- |:----------- 安妮 |  P202 |  C102 |  B103 |  19 年 11 月 25 日

第2步

-- -- Any purchases on the same dates as Anna by other people? -- select p2.* from purchase as p1 join customer as c1 on c1.custid = p1.custid join purchase as p2 on p2.purchasedate = p1.purchasedate and p2.custid.= p1.custid where c1;custname = 'Anne';
 购买ID | 监护人 | 书号 | 购买:--------- |:----- |:----- |:----------- P204 |  C104 |  B105 |  19 年 11 月 25 日

第 3 步

-- -- Now get the names from those id's -- select c2.custname, b2.bookname from purchase as p1 join customer as c1 on c1.custid = p1.custid join purchase as p2 on p2.purchasedate = p1.purchasedate and p2.custid.= p1.custid join customer as c2 on c2.custid = p2.custid join book as b2 on b2.bookid = p2.bookid where c1.custname = 'Anne'
 客户名 | 书名:------- |:--------- 玛丽亚 | 商业世界

关于db<>fiddle 的演示在这里

在与 LukStorms 提供的类似结构中,首先,让我们从如何获取 Anne 购买这本书的日期开始。 这是您查询的首要要求。 我喜欢显示查询的缩进,表 A 到 B 到 C 等。

你已经有很多连接了,我只展示第一部分。 获取购买者和购买日期。 在这种情况下,我还获得了客户的 ID,因此我知道要从最终答案中排除哪个 ID。 不要依赖于知道他们的客户 ID 并知道您想要 ID 大于个人的购买。 如果你有 5000 个人,而 Anne 恰好是第 2789 个人会怎样。在任何购买相同日期但在客户 ID 上失败的情况下,做得比其他人都失败。

select
        p.custid,
        p.purchaseDate
    from
        customer c
            join purchase p
                on c.custid = p.custid
    where
        c.custname = 'Anne'

所以从这里开始,这可能是最终 select 的第一个别名,因为基础是购买日期,但现在我们知道结果中我们不想要的人。

select
        AnnePurchase.purchaseDate,
        c2.custname,
        b.bookName
    from
        (select
                p.custid,
                p.purchaseDate
            from
                customer c
                    join purchase p
                        on c.custid = p.custid
            where
                c.custname = 'Anne' ) AnnePurchase
            JOIN purchase p2
                -- first part, join to purchase on same date as Ann purchased her book
                on AnnePurchase.purchaseDate = p2.purchaseDate
                -- but now, get anyone who's customer ID is NOT the same as Anne.
                AND NOT AnnePurchase.custID = p2.custID
                -- now from the 2nd purchase table we can join to the customer and book 
                -- table to get whatever other parts you want
                JOIN customer c2
                    on p2.custid = c2.custid
                JOIN book b
                    on p2.bookid = b.bookid

请注意通过 -- 显示我为什么要加入的在线评论。 AnnePurchase 是主要依据。 加入购买(别名 p2)是基于相同的日期而不是与 Anne 相同的客户 ID。

从那里,它是从 P2 别名返回到客户和预订表的简单连接。 我个人在购买 p2 下缩进了customer c2book b的连接缩进,因为这是他们关系的基础。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM