[英]Is there a more efficient query to check multiple conditions in a self-join?
[英]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 c2
和book b
的连接缩进,因为这是他们关系的基础。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.