问题
I'm working on some book exercises and can't find an explanation on how to express the following in relational algebra. I did find an answer for SQL though but I'm interested in whether there are any alternatives to solve it.
The question from the book is: Find those pairs of PC models that have both the same speed and RAM. A pair should be listed only once; e.g., list(i,j) but not (j,i).
The schema for PC is:
PC (
model INTEGER NOT NULL PRIMARY KEY,
speed NUMERIC,
ram INTEGER,
hd INTEGER,
price INTEGER);
and the query I made:
SELECT PC.model, PC1.model
FROM PC, PC AS PC1
WHERE PC.model != PC1.model AND PC.speed = PC1.speed AND PC.ram = PC1.ram;
which returns:
model | model
-------+-------
1004 | 1012
1012 | 1004
The relational algebra expression I constructed according to:
- Define a copy of PC named PC1 with attribute "model" renamed as "model1".
- Project model, speed and ram of PC and model1, speed and ram of PC1.
- Theta join between above projections of PC and PC1 with condition that model != model1.
- Project model and model1 from result in (3).
So in both the SQL query and the relational algebra the matching results will be listed twice but in reversed order. How do I make it be listed only once irrespective of order?
回答1:
Just use the fact that if PC.model != PC1.model
, then one is smaller than the other. So if you need one of these pairs, just use either PC.model < PC1.model
or PC.model > PC1.model
(depending on which pair you want to preserve).
SELECT PC.model, PC1.model
FROM PC, PC AS PC1
WHERE PC.model < PC1.model AND PC.speed = PC1.speed AND PC.ram = PC1.ram;
回答2:
Here is one option:
SELECT DISTINCT LEAST(pc1.model, pc2.model),
GREATEST(pc1.model, pc2.model)
FROM PC pc1
INNER JOIN PC AS pc2
ON pc1.model <> pc2.model
WHERE pc1.speed = pc2.speed AND
pc1.ram = pc2.ram;
来源:https://stackoverflow.com/questions/42674254/how-to-list-each-pair-of-tuple-only-once-irrespective-of-column-order-in-sql-and