【问题标题】:GROUP BY but ignore nulls unless no not-nullsGROUP BY 但忽略空值,除非没有非空值
【发布时间】:2017-03-14 06:01:14
【问题描述】:

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

我有一个像这样的非规范化表(基本上是 3 个不同表之间连接的结果):

driver_uuid | vehicle_uuid | document_uuid

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

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

我试着做

SELECT * FROM driver_vehicle_documents
GROUP BY 
driver_uuid,
vehicle_uuid

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

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

我们希望它让拥有 0 辆车辆的司机出现一次。有 1 辆车的司机会出现一次,有 2 辆车的司机会出现两次,以此类推。


我知道表格设计对于这个问题并不理想,但是表格用于许多不同的目的,并且在设计时考虑了这些因素。此时更改其设计是不可行的。

【问题讨论】:

    标签: mysql sql


    【解决方案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】:

    On 方法是分别处理 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
                     );
    

    【讨论】:

      【解决方案3】:

      看起来相当简单:过滤掉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
      

      【讨论】:

        猜你喜欢
        • 2018-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-05
        • 2012-12-06
        • 1970-01-01
        相关资源
        最近更新 更多