(为了便于解释,我正在简化我的数据)
我有一个非规范化表(基本上是3个不同表之间连接的结果),如下所示:
driver_uuid | vehicle_uuid | document_uuid
司机有很多车辆,
司机有很多文件,
车辆有很多文件
我想运行一个查询,其中每个唯一的驱动程序/车辆对都有一行。
我尝试过做
SELECT * FROM driver_vehicle_documents
GROUP BY
driver_uuid,
vehicle_uuid
这几乎可行,但有一个问题:
拥有1辆或更多车辆的驾驶员将比他们拥有的车辆多出现一次。即,有1辆车的驾驶员将出现两次:一次用于驾驶员/车辆对,一次用于驾驶员/无效对。
我们希望它能让一辆拥有0辆车的司机出现一次。一辆车的驾驶员将出现一次,两辆车的驾驶员将出现两次,等等。
我知道桌面设计并不适合这个问题,但是这个表用于许多不同的目的,并且是根据这些考虑因素设计的。目前改变其设计是不可行的。
答案 0 :(得分:1)
接近方法是分别处理NULL
值。因此,基本上运行您的查询过滤掉NULL
值,然后添加回您想要的值:
SELECT DISTINCT driver_uuid, vehicle_uuid
FROM driver_vehicle_documents
WHERE vehicle_uuid
UNION ALL
SELECT DISTINCT driver_uuid, NULL
FROM driver_vehicle_documents dvd
WHERE NOT EXISTS (SELECT 1
FROM driver_vehicle_documents dvd2
WHERE dvd2.driver_uuid = dvd.driver_uuid AND
dvd2.vehicle_uuid IS NOT NULL
);
答案 1 :(得分:1)
想象一下,你有两个名单;一份司机名单和一份车辆清单。
您需要完整的驱动程序列表以及任何车辆记录(如果存在)。
您可以通过自我加入来完成此操作,如下所示:
SELECT drivers.driver_uuid,
vehicles.vehicle_uuid,
vehicles.document_uuid
FROM driver_vehicle_documents drivers
LEFT JOIN driver_vehicle_documents vehicles ON vehicles.driver_uuid = drivers.driver_uuid
AND vehicles.vehicle_uuid IS NOT NULL
联接仅允许有车辆ID的记录。但如果没有找到,驱动程序记录仍然会输出(因为它是一个外连接),车辆和文件ID将只返回为空。
答案 2 :(得分:0)
似乎相当直接:过滤掉null
值并且不包括第三列
似乎很简单:过滤掉空值而不包括第三列
SELECT driver_uuid, 0
FROM driver_vehicle_documents
WHERE vehicle_uuid is null
GROUP BY
driver_uuid,
vehicle_uuid
UNION ALL
SELECT driver_uuid, vehicle_uuid
FROM driver_vehicle_documents
WHERE vehicle_uuid is not null
GROUP BY
driver_uuid,
vehicle_uuid