4表SQL连接问题

时间:2011-06-14 01:55:53

标签: mysql sql join

我有四张表如下:

Cars:
car_id | make_id
1      | 1
2      | 3

Cars Makes 
make_id  | make_name
1        | BMW
2        | Ferrari
3        | Mercedes 


Car Properties 
car_id  | property_id | property_value
1       | 1           | Automatic
1       | 2           | 1000
1       | 3           | Diesel
2       | 1           | Manual
2       | 2           | 15000
2       | 3           | Gasoline

Properties
property_id | property_name
1           | Transmission
2           | Mileage
3           | Fuel

如您所见,每辆车都有一个make_id来自“Makes”表。

并且有一个单独的表包含汽车的所有主要属性。 然后是“Car Properties”表,其中包含car_id,property_id,property_value

现在我要进行以下查询: 让宝马汽车配备自动变速箱,里程为1000柴油。 我们假设表单可以提供以下内容: make_id = 1(宝马) properties = Automatic,1000,Diesel

P.S:如果我得到结果car_id

,那就没关系

6 个答案:

答案 0 :(得分:1)

对于mysql语法不是100%(抱歉在TSQL中过多了)但这是使用的关系思想。

FROM Car 
JOIN CarProperties Trans
    ON Car.car_id = Trans.CarID AND Trans.property_id = 1
JOIN CarProperties Mileage 
    ON Car.car_id = Mileage.CarID AND Mileage.property_id = 2
JOIN CarProperties Fuel 
    ON Car.car_id = Fuel.CarID AND Fuel.property_id = 3

您的选择可以从里程数,燃料费或转换数中抽取,您的where子句

也可以

答案 1 :(得分:1)

假设查询需要满足所有三个属性:

SELECT c.car_id
FROM
    Cars c INNER JOIN (
        SELECT car_id, COUNT(*) AS prop_count
        FROM
            CarProperties
        WHERE
            (property_id = 1 AND property_value = 'Automatic')
            OR (property_id = 2 AND property_value = '1000')
            OR (property_id = 3 AND property_value = 'Diesel')
        GROUP BY car_id
    ) AS cp ON c.car_id = cp.car_id AND cp.prop_count = 3
WHERE
    c.make_id = 1;

然后它发生在我身上:

SELECT c.car_id
FROM
    Cars c INNER JOIN (
        SELECT car_id FROM CarProperties
        WHERE property_id = 1 AND property_value = 'Automatic'
    ) AS t ON c.car_id = t.car_id INNER JOIN (
        SELECT car_id FROM CarProperties
        WHERE property_id = 2 AND property_value = '1000'
    ) AS m ON c.car_id = m.car_id INNER JOIN (
        SELECT car_id FROM CarProperties
        WHERE property_id = 3 AND property_value = 'Diesel'
    ) AS f ON c.car_id = f.car_id
WHERE
   c.make_id = 1;

答案 2 :(得分:1)

由于输入只有“自动,1000,柴油”之类的值,而没有像“传输,里程,燃料”这样的值,您将不得不忽略属性表并祈祷您的属性类型永远不会包含重叠键(或者超过一种数字类型)。此外,由于输入已直接具有make_id,我们也可以不使用Cars Makes表。

这里的另一个技巧是你可以多次加入同一个表。

SELECT c.car_id 
FROM cars c
INNER JOIN `Car Properties` cp1 
    ON cp1.car_id = c.car_id AND cp1.property_value = 'Automatic'
INNER JOIN `Car Properties` cp2 
    ON cp2.car_id = c.car_id AND cp2.property_value = 'Diesel'
INNER JOIN `Car Properties` cp3 
    ON cp3.car_id = c.car_id  AND cp3.property_value = '1000'

答案 3 :(得分:0)

您可以先加入汽车物业和物业,给它一个别名并获取car_id数组,然后搜索汽车加入汽车制作“IN”(car_id_array)。

答案 4 :(得分:0)

也许这可能会奏效:

SELECT car_id
FROM Cars LEFT JOIN CarMakes USING (make_id)
     JOIN (SELECT car_id
           FROM CarProperties JOIN Properties USING (property_id)
           WHERE property_name='Transmission' AND property_value='Automatic') a
     JOIN (SELECT car_id
           FROM CarProperties JOIN Properties USING (property_id)
           WHERE property_name='Mileage' AND property_value='1000') b
     JOIN (SELECT car_id
           FROM CarProperties JOIN Properties USING (property_id)
           WHERE property_name='Fuel' AND property_value='Diesel') c
WHERE make_name = 'BMW'

答案 5 :(得分:0)

select cars.car_id
   from
      cars 
         join `car properties` cp
            on cars.car_id = cp.car_id
            join properties p
               on cp.property_id = p.property_id
   where
         cars.make_id = 1
      and (   ( p.property_name = "Transmission" and cp.property_Value = "Automatic" )
           OR ( p.property_name = "Mileage" and cp.property_Value = "1000" )
           OR ( p.property_name = "Fuel" and cp.property_Value = "Diesel" )
          )
   group by
      cars.car_id
   having
      count(*) = 3