我在上一篇文章中得到了很多帮助,这让我更好地理解了数据库模型。我已经阅读了关于JOINS的教程和解释,但我似乎无法弄明白,特此是我的数据库模型;
***Person*** ***DrivingLicense*** ***DrivingLicenseLicenseTypes***
ID ID ID
Name ExpiryDate DrivingLicense_ID
Person_ID LicenseType_ID
***LicenseTypes*** ***LicenseTypeVehicleTypes*** ***VehicleTypes*** ***Vehicles***
ID ID ID ID
LicenseType LicenseType_ID VehicleType Make
VehicleType_ID Model
VehicleType_ID
Person_ID
Person: (1, 'Person1'), (2, 'Person2');
DrivingLicense: (1, '2015-01-01', 1), (2, '2015-10-01', 2);
VehicleTypes: (1, 'Car'), (2, 'Motorbike');
LicenseTypes: (1, 'Car'), (2, 'Motorbike');
Vehicles: (1, 'Ford', 'Focus', 1), (2, 'Chevrolet', 'Caprice', 1), (3, 'Ducati', 'Multistrada', 2);
LicenseTypeVehicleTypes: (1, 1, 1), (1, 1, 2), (1, 2, 2);
DrivingLicenseLicenseTypes: (1, 1, 1), (1, 2, 2);
现在我想运行一个SELECT查询,基本上我想链接表:
PersonID.ID -> DrivingLicense.ID
DLLT.DrivingLicense_ID -> DrivingLicense.ID
DLLT.LicenseType_ID -> LicenseTypes.ID
LTVT.LicenseType_ID -> LicenseTypes.ID
LTVT.VehicleType_ID -> VehicleTypes.ID
Vehicles.Type_ID -> Vehicletypes.ID
我试过了:
SELECT * FROM Person
INNER JOIN DrivingLicense.ID ON Person.ID = DrivingLicense.ID
INNER JOIN DrivingLicenseLicenseTypes ON DrivingLicense.ID = DrivingLicenseLicenseTypes.DrivingLicense_ID
INNER JOIN LicenseTypes ON DrivingLicenseLicenseTypes.LicenseType_ID = LicenseTypes.ID
INNER JOIN LicenseTypeVehicleTypes ON LicenseTypes.ID = LicenseTypeVehicleTypes
INNER JOIN VehicleTypes ON LicenseTypeVehicleTypes.VehicleType_ID = VehicleTypes.ID
WHERE x=y AND x=y
我认为我开始的方式错误并且让新手犯错,我尝试以OUTER JOIN开始,即使他们是空白也能得到结果。
我是从错误的脚开始,我是否需要转动步骤?
也许要澄清一些事情:
在我运行查询的这个页面之前,我有2个搜索字段,1个人是唯一的,1个是车辆唯一的。
基于这两个值,我正在检查它们是否匹配(检查该人是否确实是该值的所有者)。到目前为止一切都很好。
之后,我想根据我的许可证类型,车辆类型和我的许可证的到期日期来检查该人是否有效驾驶车辆。有驾驶摩托车许可证的人可能不会驾驶汽车。
因此,我已经在这里帮助调整了数据库设置,我已经阅读了INNER,OUTER,CROSS,LEFT JOINS等之间的差异。但我一直在寻找缺失的链接。我认为仍然缺少一些逻辑。
我如何通过apprioriate JOINS收集我需要的信息?我想避免使用我的情况:
SELECT table1, table2 FROM column1, column2
例如。
以下查询给出了双重结果:
SELECT *
FROM RijbewijsTypes
LEFT JOIN RijbewijstypeVoertuigtype ON RijbewijstypeVoertuigtype.RijbewijstypeID = RijbewijsTypes.ID
LEFT JOIN RijbewijsRijbewijsType ON RijbewijsRijbewijsType.RijbewijstypeID
LEFT JOIN Rijbewijs ON Rijbewijs.ID = RijbewijsRijbewijsType.RijbewijsID
LEFT JOIN Persoon ON Persoon.ID = Rijbewijs.PersoonID
LEFT JOIN Voertuig ON Voertuig.PersoonID = Persoon.ID
LEFT JOIN Merk ON Merk.ID = Voertuig.Merk
LEFT JOIN Type ON Merk.Type = Type.ID
WHERE Persoon.BSNNummer = '20230913'
AND Voertuig.Kenteken = 'NH-UN-78'
答案 0 :(得分:1)
所以试试吧......
SELECT *
FROM LicenseTypes LT
LEFT JOIN LicenseTypeVehicleTypes LTVH
on LTVH.LicenseType_ID = LT.ID
LEFT JOIN DrivingLIcense DL
on DL.ID = DLLT.DrivingLicense_ID
LEFT JOIN Person P
on P.ID = DL.Person_ID
LEFT JOIN LicenseTypeVehicleTypes LTVT
on LTVT.LicenseType_ID = LT.ID
LEFT JOIN VehicleTypes VT
on VT.ID = LTVT.VehicleType_ID
LEFT JOIN Vehicles V
on V.ID = VT.ID
WHere P.Name = 'Person1' and V.ID = 'VIN'
如果Person1具有许可证类型'X'且'VIN'具有许可证类型'X' 然后将显示一条记录。 但是,如果没有记录将返回。
如果没有提供where子句,则所有许可证类型将与人员和车辆一起返回 它使用这些许可证类型。
如果没有与特定许可类型相关联的人或车辆将被退回。 如果你也需要这些人,那么我们必须将上述查询与一个开始的查询结合起来 以车辆开头的人和工会。
答案 1 :(得分:0)
我已将这些表放在另一个逻辑中:
SELECT DISTINCT
p.name,
v.VehicleType,
v.make,
v.model,
CASE
WHEN ltvt.VehicleType_ID = v.VehicleType_ID THEN 1
ELSE 0
END allowed
FROM
Person p
JOIN
Vehicles v
ON p.ID = v.person_id
LEFT JOIN
DrivingLicense dl
ON p.ID = dl.Person_ID
LEFT JOIN
DrivingLicenseLicenceType dlt
ON dl.ID = dlt.DrivingLicense_ID
LEFT JOIN
LicenseTypes lt
ON dlt.LicenseType_ID = lt.ID
LEFT JOIN
LicenseTypeVehicleTypes ltvt
ON dlt.LicenseType_ID = ltvt.LicenseType_ID
AND ltvt.VehicleType_ID = v.VehicleType_ID
AND dl.ExpiryDate >= CURRENT_DATE
这将导致所有人拥有他们拥有的车辆。 通过向最后左侧连接添加一些条件,您可以确定是否允许驾驶某辆车。 如果您想要特定人员和/或特定车辆,只需添加WHERE子句
<强>更新强>
John有1个驾驶执照,它有2种许可类型:B和AM。 B和AM许可类型都连接到VehicleType:Scooter。只有Licensetype B连接到我的VehicleType:Familywagon,当我将车型从Scooter更改为Familywagon时,我的值显示为0,我不允许驾驶此车辆
这与连接逻辑和数据模型有关。 由于驾驶执照与人有关而不是直接与车辆有关,因此左侧车辆的车型将具有与许可证类型所具有的车型数量一样多的条目。
在你的情况下,John的Familywagon将会在结果中出现两次,一次是用于许可类型的踏板车部分(他不允许驾驶汽车),一次用于Familywagon部分(他被允许驾驶汽车。)
这可以通过创建一个带有子查询的虚拟表来避免,该子查询具有允许某人驾驶的不同车型。
SELECT
p.name,
v.VehicleType_ID,
v.make,
v.model,
CASE
WHEN dls.VehicleType_ID = v.VehicleType_ID THEN 1
ELSE 0
END allowed
FROM
Person p
JOIN
Vehicles v
ON p.ID = v.Person_ID
LEFT JOIN
(SELECT DISTINCT
dl.Person_ID,
ltvt.VehicleType_ID
FROM
DrivingLicense dl
JOIN
DrivingLicenseLicenseTypes dlt
ON dl.ID = dlt.DrivingLicense_ID
JOIN
LicenseTypes lt
ON dlt.LicenseType_ID = lt.ID
JOIN
LicenseTypeVehicleTypes ltvt
ON dlt.LicenseType_ID = ltvt.LicenseType_ID
WHERE
dl.ExpiryDate >= CURRENT_DATE
) dls
ON p.ID = dls.Person_ID
AND dls.VehicleType_ID = v.VehicleType_ID
请注意,如果您需要有关某个人的信息,则可以明智地将子表包含在子查询中,这样您就可以缩小子查询的结果数量。