SQL查询从第二个表返回一些值并使用where子句中的其他值

时间:2016-12-15 14:11:13

标签: sql oracle

我有两张表如下

车辆表

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。

6 个答案:

答案 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