GROUP BY但忽略空值,除非没有非空值

时间:2017-03-13 21:34:38

标签: mysql sql

(为了便于解释,我正在简化我的数据)

我有一个非规范化表(基本上是3个不同表之间连接的结果),如下所示:

driver_uuid | vehicle_uuid | document_uuid

司机有很多车辆,
司机有很多文件,
车辆有很多文件

我想运行一个查询,其中每个唯一的驱动程序/车辆对都有一行。

我尝试过做

SELECT * FROM driver_vehicle_documents
GROUP BY 
driver_uuid,
vehicle_uuid

这几乎可行,但有一个问题:

拥有1辆或更多车辆的驾驶员将比他们拥有的车辆多出现一次。即,有1辆车的驾驶员将出现两次:一次用于驾驶员/车辆对,一次用于驾驶员/无效对。

我们希望它能让一辆拥有0辆车的司机出现一次。一辆车的驾驶员将出现一次,两辆车的驾驶员将出现两次,等等。

我知道桌面设计并不适合这个问题,但是这个表用于许多不同的目的,并且是根据这些考虑因素设计的。目前改变其设计是不可行的。

3 个答案:

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