简体   繁体   中英

A homework question: is there a way to compare contents in different tables at the same time?

The part of the schema is as follows:

  • Customer (cid, name, city) (primary key: cid)
  • Purchase (cid, club, title, year, when, qnty) (primary key: cid, club, title, year, when)

I want to list distinct pairs of customers who have made a purchase of a book (title) in common. For each pair of such customers, show first the one with the larger cid. In the answer table, only report the customers' names. The output columns' names are namea and nameb .

I already list all pairs with different namea and nameb with the same title

SELECT distinct c1.name as namea, c2.name as nameb
FROM purchase p1
JOIN customer AS c1 ON  c1.cid = p1.cid
JOIN purchase p2 ON p1.title = p2.title and p1.year = p2.year and p1.cid != P2.cid and p1.cid < p2.cid
JOIN customer AS c2 ON  c2.cid = p2.cid;

In case someone needs the table creation file: create , the expected return number should be 283, but I keep getting 282 since there are 2 people with the same name.

Edited:
There will be two people with the same name, so the output pairs need to be distinct by the cid , not the name . The number of my actual output tuples matches the expected output when I SELECT cid , but it doesn't work when I SELECT names. Since customers are identified by the cid , not the name , some customers with the same name will be filtered out if we distinct names. And this is the problem I'm working on right now.

Learn to use proper, explicit, standard , readable JOIN syntax. Here you just need a bunch of joins.

This will be simpler with a CTE:

with cp as (
      select p.*, c.name
      from purchase p join
           customer c
           on p.cid = c.cid
     )
select distinct cp.name as namea, cp2.name
from cp join
     cp cp2
     on cp.title = cp2.title and
        cp.cid > cp2.cid;

If this is for a specific title, then add where cp.title = <whatever the title is> .

I guess you can first join the purchase table with customer table and then can join both the derived tables -

SELECT  c1.name as namea, c2.name as nameb
From    (SELECT cid, name, title, year
         FROM customer C
         JOIN purchase P ON C.cid = P.cid) C1
JOIN   (SELECT cid, name, title, year
        FROM customer C
        JOIN purchase P ON C.cid = P.cid) C2
WHERE   C1.cid > C2.cid
AND     C1.title = C2.title
AND     c1.year = C2.year
ORDER BY C1.name, C2.name;
WITH
  Customer (cid, name) AS
(
VALUES
  (1, 'N1')
, (2, 'N2')
, (3, 'N3')
)
, Purchase (cid, club, title) AS 
(
VALUES
  (1, '1', 'T1')
, (2, '2', 'T1')  
, (2, '3', 'T2')  
, (3, '4', 'T2')  
)
FROM
(
SELECT distinct p1.cid cid1, p2.cid cid2
FROM Purchase p1
JOIN Purchase p2 on p2.title = p1.title and p2.cid > p1.cid
) p
JOIN Customer c1 on c1.cid = p.cid1
JOIN Customer c2 on c2.cid = p.cid2;

You may run it as is and edit base data to check the result.
I omitted a number of your non-significant fields for simplicity.

If the result is not expected, then edit your question with your sample data in the same form as above (edit the VALUES part of the query) and provide the result desired.

Add the cid s to the select list of your query and then select from it only the names:

SELECT t.namea, t.nameb
FROM (
  SELECT DISTINCT c1.cid ida, c1.name as namea, c2.cid idb, c2.name as nameb
  FROM purchase p1
  JOIN customer AS c1 ON  c1.cid = p1.cid
  JOIN purchase p2 ON p1.title = p2.title and p1.year = p2.year and p1.cid != p2.cid and p1.cid < p2.cid
  JOIN customer AS c2 ON  c2.cid = p2.cid
) t

Or you can group by c1.cid, c1.name, c2.cid, c2.name :

SELECT c1.name as namea, c2.name as nameb
FROM purchase p1
JOIN customer AS c1 ON  c1.cid = p1.cid
JOIN purchase p2 ON p1.title = p2.title and p1.year = p2.year and p1.cid != p2.cid and p1.cid < p2.cid
JOIN customer AS c2 ON  c2.cid = p2.cid
GROUP BY c1.cid, c1.name, c2.cid, c2.name

See the demo .
Result 283 rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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