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

SQL查询从第二个表返回一些值,并在where子句中使用其他值,sql,oracle,Sql,Oracle,我有两张桌子如下 车辆表 Vehicle_id | Location | Status ------------------------------ 1000 | FLT1 | OPERATING 1001 | FLT1 | OPERATING . | . | . . | . | . 及 车辆规格表 Vehicle_id | AttribID | AttribValue ----------

我有两张桌子如下

车辆表

Vehicle_id | Location | Status
------------------------------
1000       | FLT1     | OPERATING
1001       | FLT1     | OPERATING
.          |   .      | .
.          |   .      | .
及 车辆规格表

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实现以下目标

返回车辆状态为运行且型号为F150的所有车辆ID及其驾驶员。我的问题是如何创建一个子查询以在select语句和where子句的第二个表中获取两个AtrribValues

像这样的

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')
像这样的

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')

您可以在查询中多次联接同一个表:

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'

您可以在查询中多次联接同一个表:

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'
使用枢轴,则只需对车辆规格表进行一次表扫描:

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'
使用枢轴,则只需对车辆规格表进行一次表扫描:

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'
使用此查询:

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');
使用此查询:

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');

啊,那些可怕的键/值表。他们让你一遍又一遍地读同一张表

不过,查询相当简单:

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';

啊,那些可怕的键/值表。他们让你一遍又一遍地读同一张表

不过,查询相当简单:

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';

我认为你的问题已经得到充分解决

我只向您推荐数据库的标准化。您应该规范化的原因是为了避免冗余和保持数据的一致性

冗余,例如:

Vehicle_id | Location | Status
------------------------------ 
1000       | FLT1     | OPERATING
1001       | FLT1     | OPERATING
对于n条状态为“正在运行”的记录,您可以保存n次“正在运行”。 但这是没有必要的。相反,您可以将状态移动到另一个表并引用它

非规范化数据库: 第三范式: 标准化:

车辆表:用于车辆特定属性

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   | ...
...
模型表:用于特定于模型的属性

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   | ...
...
状态表:用于特定于状态的属性

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   | ...
...
驱动程序表:用于特定于驱动程序的属性

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   | ...
...
车辆驾驶表:

规范化数据库的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

我认为你的问题已经得到充分解决

我只向您推荐数据库的标准化。您应该规范化的原因是为了避免冗余和保持数据的一致性

冗余,例如:

Vehicle_id | Location | Status
------------------------------ 
1000       | FLT1     | OPERATING
1001       | FLT1     | OPERATING
对于n条状态为“正在运行”的记录,您可以保存n次“正在运行”。 但这是没有必要的。相反,您可以将状态移动到另一个表并引用它

非规范化数据库: 第三范式: 标准化:

车辆表:用于车辆特定属性

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   | ...
...
模型表:用于特定于模型的属性

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   | ...
...
状态表:用于特定于状态的属性

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   | ...
...
驱动程序表:用于特定于驱动程序的属性

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   | ...
...
车辆驾驶表:

规范化数据库的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

这两个查询都不会返回驱动程序。@MT0你是对的,我看错了问题。我已经更新了答案,使用@before表名在Oracle中无效。@MT0正确,这是我在MSSQL中的模型遗留下来的;这两个查询都不会返回驱动程序。@MT0你是对的,我看错了问题。我已经更新了答案,使用@before表名在Oracle中无效。@MT0正确,这是我在MSSQL中的模型遗留下来的;为了简单起见,我没有包括所有的字段和相关的表来准确地反映确切的逻辑。这来自IBM资产管理数据库,它的设计方式是对的还是错的,但我同意您的建议。为了简单起见,我没有包括所有字段和相关表,以准确反映确切的逻辑。这来自IBM资产管理数据库,它的设计是正确的还是错误的,但我同意您的建议。