我有一个包含这些表和列的数据库:
firstname
lastname
peid
peid
peid
pno
我正在尝试选择具有相同pno和不同peid的名称(买方1和买方2)。
FIRSTNAME LASTNAME PEID PNO
-------------------------------------------
Robert Young 0 18
Stephen Davison 2 32
Tony Nguyen 16 28
Lily Roy 32 14
Aaron Naidoo 50 51
Adam Jordan 64 32
Arun Isaacson 68 27
Charles Murphy 84 23
Adam Peter 94 27
我想要的是选择具有相同pno和不同peid的两个买家以及他们共同拥有的pno。例如:
亚当乔丹和斯蒂芬戴维森有32个共同点。 Adam Peter和Arun Isaacson有27个共同点。我正试图选择它们。 上表是我的一个查询的结果,而不是原始表。来自评论:
这是我到目前为止所做的事情
select A.firstname || ' ' || A.lastname as Buyer1,
B.firstname || ' ' || B.lastname as Buyer2
from person A, person B, buyer One, buyer Two
where A.peid = One.peid and B.peid = Two.peid
and (select off.pno from offer off where off.peid = One.peid) =
(select off.pno from offer off where off.peid = Two.peid)
and (select off.peid from offer off where off.peid = One.peid) <>
(select off.peid from offer off where off.peid = Two.peid)
group by A.firstname || ' ' || A.lastname, B.firstname || ' ' || B.lastname;
答案 0 :(得分:0)
如果您的DBMS支持CTE(公用表表达式,也就是WITH子句),您可以比不支持CTE更加整洁。但是,许多DBMS不支持它,所以这里是没有CTE的版本。分阶段开发(和测试)答案通常是最容易的。目前还不完全清楚为什么你需要买方表。但是,我们认为它至关重要。
我们可以使用以下查询生成人员列表和他们购买的内容:
SELECT P.*, O.pno
FROM Person AS P
JOIN Buyer AS B ON P.peid = B.peid
JOIN Offer AS O ON B.peid = O.peid;
两个回答主要查询,我们需要这个结果集的两个副本,在pno列上加入,条件是peid值不同:
SELECT P1.Name, P1.Peid, P2.Name, P2.Peid, P1.Pno
FROM (SELECT (P.FirstName || ' ' || P.LastName) AS Name, P.Peid, O.Pno
FROM Person AS P
JOIN Buyer AS B ON P.Peid = B.Peid
JOIN Offer AS O ON B.Peid = O.Peid
) AS P1
JOIN (SELECT (P.FirstName || ' ' || P.LastName) AS Name, P.Peid, O.Pno
FROM Person AS P
JOIN Buyer AS B ON P.Peid = B.Peid
JOIN Offer AS O ON B.Peid = O.Peid
) AS P2
ON P1.Pno = P2.Pno AND P1.Peid < P2.Peid;
在最后一行使用<
的技巧是常见的。它确保您拥有这样的对称查询,然后每对只列出一次。也就是说,如果Person1和Person2都购买了相同的商品,那么Person2和Person1也是如此。但是,<
条件确保只显示两行中的一行。它还确保Person1和Person1行以及Person2和Person2行都不会出现。
如果您的DBMS支持CTE,您可以将子查询转换为命名CTE,然后在主查询中引用它。
近似语法:
WITH Purchases AS
(SELECT (P.FirstName || ' ' || P.LastName) AS Name, P.Peid, O.Pno
FROM Person AS P
JOIN Buyer AS B ON P.Peid = B.Peid
JOIN Offer AS O ON B.Peid = O.Peid
)
SELECT P1.Name, P1.Peid, P2.Name, P2.Peid, P1.Pno
FROM Purchases AS P1
JOIN Purchases AS P2
ON P1.Pno = P2.Pno AND P1.Peid < P2.Peid;