我有两张表如下
车辆表
Vehicle_id | Location | Status
------------------------------
1000 | FLT1 | OPERATING
1001 | FLT1 | OPERATING
. | . | .
. | . | .
和 Vehicle_Specs表
Vehicle_id | AttribID | AttribValue
------------------------------
1000 | Model | F150
1000 | Driver | John Smith
1000 | Odometer | 80000
1001 | Model | F350
1001 | Driver | Joe Douglas
1001 | Odometer | 50000
我很难使用SQL来实现以下目标。
返回车辆状态为“正在运行”的所有vehicle_ids及其驱动程序,其型号为F150。我的问题是如何创建一个子查询来在我的select语句和where子句的第二个表中获取两个AtrribValues。
答案 0 :(得分:5)
使用PIVOT
,您只需要对Vehicle_specs表进行一次表扫描:
SELECT v.vehicle_id,
s.Driver
FROM ( SELECT *
FROM Vehicle_specs
PIVOT ( MAX( attribvalue )
FOR AttribID IN ( 'Model' AS model, 'Driver' AS Driver ) )
) s
INNER JOIN
vehicle v
ON ( v.vehicle_id = s.vehicle_id )
WHERE s.model = 'F150'
AND v.status = 'OPERATING'
答案 1 :(得分:2)
您可以在查询中多次加入同一个表:
SELECT V.Vehicle_id, drivers.AttribValue AS Driver
FROM Vehicle V
JOIN Vehicle_Specs drivers ON V.Vehicle_id = drivers.Vehicle_id AND drivers.AttribId = 'Driver'
JOIN Vehicle_Specs models ON V.Vehicle_id = models.Vehicle_id AND models.AttribId = 'Model'
WHERE models.AttribValue = 'F150' AND V.Status = 'OPERATING'
答案 2 :(得分:1)
但查询相当简单:
select vehicle_id, attribvalue as driver
from vehicle_specs
where vehicle_id in
(select vehicle_id from vehicle where status = 'OPERATING')
and vehicle_id in
(select vehicle_id from vehicle_specs where attribid = 'Model' and attribvalue = 'F150')
and attribid = 'Driver';
答案 3 :(得分:0)
这样的东西?
select V2.Vehicle_id, V2.AttribValue
from Vehicle V1
inner join Vehicle_specs V2
on V1.Vehicle_id = V2.Vehicle_id
where Status = 'Operating'
and exists (select 1
from Vehicle_Specs V3
where V3.vehicle_id = V2.Vehicle_id
and V3.Attribid = 'Model'
and V3.AttribValue = 'F150')
答案 4 :(得分:0)
使用此查询:
SELECT V.Vehicle_id, Specs.AttribId, Specs.AttribValue FROM Vehicle V
LEFT JOIN Vehicle_Specs Specs ON Specs.Vehicle_id = V.Vehicle_id AND Specs.AttribId='Driver'
WHERE V.Status='OPERATING' AND V.Vehicle_id IN (SELECT Vehicle_id FROM Vehicle_Specs WHERE AttribId='Model' AND AttribValue='F150');
答案 5 :(得分:0)
我认为您的问题已经得到充分解决。
我只想建议数据库的规范化。您应该规范化的原因是为了避免冗余并保持数据的一致性。
冗余,例如:
Vehicle_id | Location | Status
------------------------------
1000 | FLT1 | OPERATING
1001 | FLT1 | OPERATING
对于状态为“OPERATING”的n条记录,您可以节省n次'OPERATING'。 但这不是必要的。相反,您可以将状态移动到另一个表并引用它。
归一化:
车辆表:(针对车辆特定属性)
v_id | m_id | odometer | ...
------------------------------------------
1000 | 0001 | 80000 | ...
1001 | 0002 | 50000 | ...
...
模型表:(对于特定于模型的属性)
m_id | model | ...
------------------
0001 | F150 | ...
0002 | F350 | ...
...
状态表:(针对特定于州的属性)
s_id | status
------------
0001 | OPERATING
0002 | ...
...
驱动程序表:(针对特定于驱动程序的属性)
d_id | first_name | last_name | ...
-----------------------------------
0001 | John | Smith | ...
0002 | Joe | Douglas | ...
...
VehicleDriver 表:
vd_id | v_id | d_id | s_id
--------------------------
0001 | 1000 | 0001 | 0001
0002 | 1001 | 0002 | 0001
规范化数据库的SQL语句如下所示:
SELECT vehicle.v_id, first_name, last_name
FROM driver, vehicle, vehicledriver, status, model
WHERE vehicle.v_id = vehicledriver.v_id
AND vehicledriver.d_id = driver.d_id
AND vehicledriver.s_id = status.s_id
AND vehicle.m_id = model.m_id
AND status = "OPERATING"
AND model = "F150";
结果:
v_id | first_name | last_name
--------------------------
0001 | John | Smith