2
4

3 回答 3

0

you said σ(COUNT(Car)=3)(R), but COUNT is an aggregation function.

without aggregations, the only way I see is loop through the R table rows by row counting Owner. Something like:

for each row
    If owner=previous_owner then n_cars++ 
    else (if n_cars>=3 then return owner
end
于 2012-04-27T08:12:16.367 回答
0
\pi_{Car.owner}(\sigma_{Car.owner = C1.owner\wedge 
                        C1.owner = C2.owner\wedge 
                        Car.vin != C1.vin\wedge 
                        C1.vin != C2.vin\wedge 
                        Car.vin != C2.vin}(Car x 
                                           \rho_{C1}(Car) x 
                                           \rho_{C2}(Car)))
 -
 \pi_{Car.owner}(\sigma_{Car.owner = C1.owner\wedge 
                        C1.owner = C2.owner\wedge 
                        C2.owner = C3.owner \wedge
                        Car.vin != C1.vin\wedge 
                        C1.vin != C2.vin\wedge 
                        Car.vin != C2.vin \wedge
                        Car.vin != C3.vin\wedge 
                        C1.vin != C3.vin\wedge 
                        C2.vin != C3.vin}(Car x 
                                           \rho_{C1}(Car) x 
                                           \rho_{C2}(Car) x
                                           \rho_{C3}(Car)))

where \pi is projection, \sigma is selection, x is cartesian product, \rho is renaming, \wedge represents conjunction and I assume the attributes of relation Car to be called owner and vin.

于 2012-05-01T18:39:13.087 回答
-1

Here's one way of doing it, in SQL using operators that are easy to translate to relational algebra, and using slightly different test data (different types, same names):

WITH R 
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 1), 
                     (2, 2), (2, 3),
                     (3, 1), (3, 2), (3, 3),
                     (4, 1), (4, 2), (4, 3), (4, 4)
             ) AS T (Owner, Car)
     ),
     OwnersWithAtLeastThreeCars
     AS
     (
      SELECT DISTINCT R1.Owner
        FROM R AS R1, R AS R2, R AS R3
       WHERE R1.Owner = R2.Owner
             AND R2.Owner = R3.Owner
             AND R1.Car <> R2.Car
             AND R1.Car <> R3.Car
             AND R2.Car <> R3.Car
     ),
     OwnersWithAtLeastFourCars
     AS
     (
      SELECT DISTINCT R1.Owner
        FROM R AS R1, R AS R2, R AS R3, R AS R4
       WHERE R1.Owner = R2.Owner
             AND R2.Owner = R3.Owner
             AND R3.Owner = R4.Owner
             AND R1.Car <> R2.Car
             AND R1.Car <> R3.Car
             AND R1.Car <> R4.Car
             AND R2.Car <> R3.Car
             AND R2.Car <> R4.Car
             AND R3.Car <> R4.Car
     )
SELECT * FROM OwnersWithAtLeastThreeCars
EXCEPT       
SELECT * FROM OwnersWithAtLeastFourCars;

p.s. I'm using 'old style' (i.e. pre-1992) standard SQL joins, which are widely condemned on Stackoverflow. I'm using them not only because it fits with the OP's list of available operators but, frankly, in these circumstances I find them much easier to write than using infix INNER JOIN notation.

于 2012-04-27T12:43:38.063 回答