【问题标题】:MySQL query using group by with multiple conditionsMySQL 查询使用 group by 和多个条件
【发布时间】:2016-09-06 11:57:22
【问题描述】:

编辑: 我删除了最后令人困惑的评论,并添加了一个我认为无关紧要的附加列 pl_id(由于我明显缺乏对 group by 工作原理的理解)。在尝试发布的建议时,我遇到了一个问题,即引入 MAX/Group By 会导致

  | name  | license_plate | pl_id | start_date |
  | aaron | AA-AA-22      |     3 | 2016-1-1   |

我期望的地方:

  | name  | license_plate | pl_id | start_date |
  | aaron | AA-AA-22      |     4 | 2016-1-1   |

所以不知何故,车牌 AA-AA-22 的最大日期,即 2016-1-1,出现在 pl_id = 3 的记录中,为什么结果返回日期为 pl_id 4 的记录? 结束编辑

我有一个带有列的表格:

  • 姓名
  • license_plate
  • 开始日期

我需要一个查询,它为每个具有最大 start_date 或 start_date 为空的车牌返回一条记录。但是空的 start_date 应该优先于最大 start_date。

保证每个车牌最多有一个 start_date = null 的条目,但可以有多个有效的 'start_date'-s 条目。

所以例如在下表中执行时:

  | name  | license_plate | pl_id | start_date |
  | aaron | AA-AA-11      |     1 | 2015-1-1   |
  | aaron | AA-AA-11      |     2 | null       |
  | aaron | AA-AA-22      |     3 | 2015-1-1   |
  | aaron | AA-AA-22      |     4 | 2016-1-1   |
  | bill  | BB-BB-11      |     5 | 2015-1-1   |
  | bill  | BB-BB-11      |     6 | null       |
  | bill  | BB-BB-22      |     7 | 2015-1-1   |
  | clark | CC-CC-11      |     8 | 2015-1-1   |
  | clark | CC-CC-11      |     9 | 2016-1-1   |
  | dave  | DD-DD-11      |    10 | 2014-1-1   |
  | dave  | DD-DD-11      |    11 | 2015-1-1   |
  | dave  | DD-DD-11      |    12 | 2016-1-1   |
  | eddy  | EE-EE-11      |    13 | null       |

查询应该返回:

  | name  | license_plate | pl_id | start_date |
  | aaron | AA-AA-11      |     2 | null       |
  | aaron | AA-AA-22      |     4 | 2016-1-1   |
  | bill  | BB-BB-11      |     6 | null       |
  | bill  | BB-BB-22      |     7 | 2015-1-1   |
  | clark | CC-CC-11      |     9 | 2016-1-1   |
  | dave  | DD-DD-11      |    12 | 2016-1-1   |
  | eddy  | EE-EE-11      |    13 | null       |

【问题讨论】:

    标签: mysql group-by multiple-conditions


    【解决方案1】:
    SELECT name, license_plate, IF(max(IF(start_date IS NULL, '2099-01-01',  start_date)) = '2099-01-01', null, max(start_date)) 
    FROM table
    GROUP BY name, license_plate;
    

    如果需要,您可以将“2099-01-01”更改为更大的数字。

    在您的数据集上测试。

    【讨论】:

      【解决方案2】:

      我很困惑,从您的示例来看,您似乎希望 null 优先于任何实际日期 - 我只是不明白这与按多个条件分组有什么关系...... 也许这个answer可以帮助你?

      SELECT
          `name`,
          license_plate,
          CASE
              WHEN MAX(start_date IS NULL) = 0 THEN MAX(start_date)
          END AS start_date
      FROM
          plates
      GROUP BY
          `name`,
          license_plate
      

      输出:

      +-------+---------------+------------+
      | name  | license_plate | start_date |
      +-------+---------------+------------+
      | aaron | AA-AA-11      | NULL       |
      | aaron | AA-AA-22      | 2016-01-01 |
      | bill  | BB-BB-11      | NULL       |
      | bill  | BB-BB-22      | 2015-01-01 |
      | clark | CC-CC-11      | 2016-01-01 |
      | dave  | DD-DD-11      | 2016-01-01 |
      | eddy  | EE-EE-11      | NULL       |
      +-------+---------------+------------+
      7 rows in set
      

      【讨论】:

      • 我的答案也会给出结果,你的答案更好。
      • 谢谢,确实您所指的帖子似乎正是我的问题。我现在正试图让您的解决方案发挥作用。但是,我遇到了一些非常奇怪的问题。关键是,我的原始表本身就是多个joins 的结果,一旦我引入group by,就会得到一个结果,其中多个记录的值似乎混合在一起。这可能与我对group by 内部工作原理的理解不佳有关。所以我将首先研究更多。我确实认为,尽管有了这个答案,我应该能够弄清楚。将分享结果。
      • 顺便说一句,我的多条件标签指的是start_date is nullMAX(start_date)
      【解决方案3】:

      您需要 2 个查询,一个用于 NULL 值,另一个用于 MAX(start_date)

      SELECT name, license_plate, MAX(start_date) FROM test.tab
      group by name, license_plate having count(start_date) = count(name)
      
      union 
      select name, license_plate, start_date From test.tab
      Where start_date is null
      

      在这种情况下count(start_date) = count(name) 您将发现具有null 值的记录,因为null 值不在count 语句中计算。

      另一个select 将返回带有start_date = null 的记录。

      如果您的数据库有多个记录具有相同license_platenull 值,则可以将where 条件添加到第二个查询中

      【讨论】:

        【解决方案4】:

        你可以使用分组方式

        SELECT  distinct * FROM [tablename] where start_date is null or start_date group by 
        license_number order by name,start_date
        

        如果license_plate组中的start_date中有null,则“start_date is null”是为了让您首先显示,“or start_date”是为了让您显示其他不为null的日期。

        它会产生相同的结果:

        | name  | license_plate | start_date |
        | aaron | AA-AA-11      | null       | 
        | aaron | AA-AA-22      | 2016-1-1   |
        | bill  | BB-BB-11      | null       |
        | bill  | BB-BB-22      | 2015-1-1   |
        | clark | CC-CC-11      | 2016-1-1   |
        | dave  | DD-DD-11      | 2016-1-1   |
        | eddy  | EE-EE-11      | null       |
        

        这是结果的捕获:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多