选择查询以根据一列的多个值检索结果(AND条件)

时间:2014-05-09 17:08:50

标签: java sql sql-server

有三个表格如下

表1 - 车辆

Vehicle_Id PRIMARY KEY
姓名
Serial_Number

表2 - Propertyname

Property_Id PRIMARY KEY
名称

表3 - 财产

Property_Id(FOREIGN KEY)引用Propertyname表中的Property_Id 价值
Id(FOREIGN KEY)从Vehicle表中引用Vehicle_Id

样本数据

表1 - 车辆

Vehicle_Id    Name    Serial_Number 
1000        WagonR    Maruti-WagonR 
1001        Estilo    Maruti-Estilo 
1002        Zen       Maruti-Zen    

表2 - Propertyname

Property_Id    name
100            Mileage 
101            FuelType
102            Country 

表3 - 财产

Property_Id    Value    Id 
100            50       1000 
101            Petrol   1000 
102            India    1000 
100            35       1001 
101            Diesel   1002 

从三个表中我们可以看到每辆车都有一组属性,这些属性在Property表中保存为行。这样做是为了在我们向车辆添加更多属性的情况下,我们为车辆添加行条目,而不是添加不可行的列。

现在我有一个用户界面,我可以根据他们的

搜索车辆

1)Name,Serial_Number - 这些可作为Vehicle表中的列和&
2)里程,FuelType,国家 - 这些是特定车辆的属性

用户可以在上面的1)和2)中输入值的任意组合来搜索车辆列表。

例如: - 如果用户输入里程数为50,燃料类型为柴油,我应该获取里程为50且燃料类型为柴油的车辆的结果。

我尝试了以下SQL语句来执行相同的操作

select vh.Vehicle_Id, vh.name, pt.Property_Id, pn.name, pt.value
from property pt
inner join propertyname pn
on pt.Property_Id=pn.Property_Id
inner join vehicle vh
on vh.Vehicle_Id=pt.Id
and ((pn.Name='Mileage' AND pt.Value='50') AND (pn.Name='FuelType' AND pt.Value='Petrol'));

但由于单行结果的AND条件,我得到零结果。但是如果我将最后一个AND条件更改为OR,我会得到两个符合条件的结果。

但我正在尝试获取匹配属性的车辆。

我尝试过使用INTERSECT,两个SQL语句的内连接等。但是无法得到结果。

有人可以建议我搜索两个属性名称的最佳方法,它们以行而不是列的形式存在,以获得确切的搜索结果。

2 个答案:

答案 0 :(得分:0)

您的问题是PropertyName不能同时是'Mileage'和'FuelType'

您可以在两个属性名称的交集处找到所有车辆,如此

select Vehicle_Id, Vehicle.Name, Serial_Number, PropertyName.Name, Property.Value
from Vehicle
join Property on (Property.Id = Vehicle.Vehicle_Id)
join PropertyName on (PropertyName.Property_Id = Property.Property_Id)
where Vehicle_id in 
(select Id 
    from PropertyName 
    Join Property on (PropertyName.Property_Id = Property.Property_Id)
    where PropertyName.Name = 'Mileage' and Property.Value = '50'
 intersect 
 select Id 
    from PropertyName 
    Join Property on (PropertyName.Property_Id = Property.Property_Id)
    where PropertyName.Name='FuelType' AND Property.Value='Petrol'
 )


Vehicle_Id  Name    Serial_Number   Name    Value
1000    WagonR  Maruti-WagonR   Mileage 50
1000    WagonR  Maruti-WagonR   FuelType    Petrol
1000    WagonR  Maruti-WagonR   Country India

答案 1 :(得分:0)

有各种方法可以做到这一点

我会做这样的事情

select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
inner join propertyname pn_m ON pn_m.Name='Mileage'
inner join propertyname pn_f ON pn_f.Name='FuelType' 
inner join property     pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
inner join property     pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id

当您加入两个属性时,属性名称表需要两个别名,并且您同样需要两个别名作为属性值

这样做的一个优点是 它可以快速适应处理其中一个属性未实际填充的车辆

select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
left join propertyname pn_m ON pn_m.Name='Mileage'
LEFT join propertyname pn_f ON pn_f.Name='FuelType' 
LEFT join property     pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
LEFT join property     pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id

甚至处理不一致的属性名称

select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
left join propertyname pn_m ON pn_m.Name='Mileage'
LEFT join propertyname pn_f ON pn_f.Name IN ('FuelType','Fuel Type') 
LEFT join property     pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
LEFT join property     pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id