查询数据库中的多个表

时间:2011-09-15 03:04:32

标签: sql

我有一个包含这些表和列的数据库:

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;

1 个答案:

答案 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;