开发者

Querying multiple tables in database

I have a database with these tables and columns:

Person

firstname
lastname 
peid

Buyer

peid

Offer

peid  
pno

I am trying to select names (buyer 1 and buyer 2) that have the same pno and different peid.

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      Mur开发者_开发百科phy     84       23
Adam         Peter      94       27

What I want is to select two buyers that have the same pno and different peid and the pno that they have in common. For example:

Adam Jordan and Stephen Davison have 32 in common. Adam Peter and Arun Isaacson have 27 in common. I'm trying to select them. The above table is the result of one of my queries, not the original table.


From a comment:

This is what I have done so far

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;


If your DBMS supports CTE (common table expressions, aka WITH clauses), you can do this more neatly than if it does not. However, many DBMS do not support it, so here's a version without CTEs. It is often easiest to develop (and test) the answer in stages. It is not entirely clear why you need the Buyer table at all. However, we'll assume it is crucial.

We can generate a list of the people and what they bought with a query like:

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;

Two answer the main query, we need two copies of this result set, joined on the pno column, with the condition that the peid values are different:

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;

The trick using < in the last line is a common one. It ensures that where you have a symmetric query like this, then each pair is only listed once. That is, if Person1 and Person2 both bought the same item, then so did Person2 and Person1. The < condition, though, ensures that only one of the two rows appears. It also ensures that neither the Person1 and Person1 row nor the Person2 and Person2 row appears.

If your DBMS supports CTEs, you can make the sub-query into a named CTE, and then refer to it in the main query.

Approximate syntax:

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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜