在 7 个表之间加入
JOINS between 7 tables
我在之前的 post 中得到了很多帮助,这让我更好地理解了数据库模型。我已经阅读了有关 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 查询,基本上我想 link 表:
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 等之间的区别。但我一直在寻找丢失的 link。我认为仍然缺少一些逻辑。
我如何通过适当的 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'
- INNER JOIN:只有 Return 两个
中的数据
- LEFT JOIN:总是 Return 数据在第一个 table,然后只有相关数据在第二个
- RIGHT JOIN:始终 return 来自第二个 table 的数据,然后仅是相关数据形式
第一的。
- FULL OUTER:始终 Return 来自所有 table 的所有数据并对齐
他们联系时。 (在 mySQL 中不可用)
- CROSS JOIN:Return 来自第一个 table 的所有数据并将其与第二个 table 中的所有数据相关联,没有关系....所以如果第一个有 2 个记录table 第二个是 5...总结果将是 10 条记录。
所以让我们试试...
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'
然后会显示一条记录。
但是,如果没有记录,则 return.
如果没有提供 where 子句,所有许可证类型将与人员和车辆一起 returned
使用这些许可证类型。
如果没有与特定许可证类型相关联的人员或车辆,则不会 returned。
如果您也需要人员,那么我们必须将上述查询与以
在以 vehicle 开头的 person 和 union 中。
我已将 table 放在其他更符合逻辑的位置:
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
这将导致所有人都拥有自己的车辆。
通过向最后一个左连接添加一些条件,您可以确定是否允许驾驶特定车辆。
如果您想要特定的人 and/or 特定的车辆,只需添加一个 WHERE 子句
更新
John has 1 drivers license, which has 2 licensetypes: B and AM. Both B and AM Licensetypes are connected to to the VehicleType: Scooter. Only Licensetype B, is connected to my VehicleType: Familywagon, when i change the vehicletype from Scooter to Familywagon, my value shows 0, that i'm not allowed to drive this vehicle
这与连接逻辑和数据模型有关。
因为驾照与人有关,而不是直接与车辆有关,所以使用左连接,车辆类型的条目数与许可证类型的车辆类型数一样多。
在您的情况下,John 的 Familywagon 将在结果中出现两次,一次是许可证类型的踏板车部分(不允许他驾驶汽车),一次是 Familywagon 部分(他是允许开车)。
这可以通过创建一个虚拟 table 来避免,该虚拟 table 的子查询包含一个人可以驾驶的不同车辆类型。
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
请注意,如果您需要有关某个人的信息,那么在子查询中包含人员 table 可能是明智的,这样您可以缩小子查询的结果数量。
我在之前的 post 中得到了很多帮助,这让我更好地理解了数据库模型。我已经阅读了有关 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 查询,基本上我想 link 表:
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 等之间的区别。但我一直在寻找丢失的 link。我认为仍然缺少一些逻辑。
我如何通过适当的 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'
- INNER JOIN:只有 Return 两个 中的数据
- LEFT JOIN:总是 Return 数据在第一个 table,然后只有相关数据在第二个
- RIGHT JOIN:始终 return 来自第二个 table 的数据,然后仅是相关数据形式 第一的。
- FULL OUTER:始终 Return 来自所有 table 的所有数据并对齐 他们联系时。 (在 mySQL 中不可用)
- CROSS JOIN:Return 来自第一个 table 的所有数据并将其与第二个 table 中的所有数据相关联,没有关系....所以如果第一个有 2 个记录table 第二个是 5...总结果将是 10 条记录。
所以让我们试试...
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' 然后会显示一条记录。 但是,如果没有记录,则 return.
如果没有提供 where 子句,所有许可证类型将与人员和车辆一起 returned 使用这些许可证类型。
如果没有与特定许可证类型相关联的人员或车辆,则不会 returned。 如果您也需要人员,那么我们必须将上述查询与以 在以 vehicle 开头的 person 和 union 中。
我已将 table 放在其他更符合逻辑的位置:
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
这将导致所有人都拥有自己的车辆。 通过向最后一个左连接添加一些条件,您可以确定是否允许驾驶特定车辆。 如果您想要特定的人 and/or 特定的车辆,只需添加一个 WHERE 子句
更新
John has 1 drivers license, which has 2 licensetypes: B and AM. Both B and AM Licensetypes are connected to to the VehicleType: Scooter. Only Licensetype B, is connected to my VehicleType: Familywagon, when i change the vehicletype from Scooter to Familywagon, my value shows 0, that i'm not allowed to drive this vehicle
这与连接逻辑和数据模型有关。 因为驾照与人有关,而不是直接与车辆有关,所以使用左连接,车辆类型的条目数与许可证类型的车辆类型数一样多。
在您的情况下,John 的 Familywagon 将在结果中出现两次,一次是许可证类型的踏板车部分(不允许他驾驶汽车),一次是 Familywagon 部分(他是允许开车)。
这可以通过创建一个虚拟 table 来避免,该虚拟 table 的子查询包含一个人可以驾驶的不同车辆类型。
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
请注意,如果您需要有关某个人的信息,那么在子查询中包含人员 table 可能是明智的,这样您可以缩小子查询的结果数量。