【问题标题】:MySQL grouping and sortingMySQL 分组和排序
【发布时间】:2020-05-16 13:09:07
【问题描述】:
mysql> describe jobs;
+--------------+---------+------+-----+---------+----------------+
| Field        | Type    | Null | Key | Default | Extra          |
+--------------+---------+------+-----+---------+----------------+
| job_id       | int(11) | NO   | PRI | NULL    | auto_increment |
| candidate_id | int(11) | NO   | MUL | NULL    |                |
| company_id   | int(11) | NO   | MUL | NULL    |                |
| start_date   | date    | NO   | MUL | NULL    |                |
| end_date     | date    | NO   | MUL | NULL    |                |
+--------------+---------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

每个候选人可以有多个工作。我想为每个候选人找到最新的工作(基于开始日期,因为结束日期可以是 0000-00-00),并检查(在 PHP 中)end_Date 是否不是 0000-00-00。

(如果您的最后结束日期不是 0000-00-00,那么您目前处于失业状态,这正是我要寻找的;我不知道如何在我的查询中执行此操作,因此将在 PHP 中执行)。

查询SELECT candidate_id, end_Date FROM jobs ORDER BY candidate_id , start_date DESC 让我走到了一半。

+--------------+------------+
| candidate_id | end_Date   |
+--------------+------------+
|            1 | 2019-08-31 |
|            1 | 2019-01-31 |
|            1 | 2019-05-31 |
|            2 | 0000-00-00 |
|            2 | 2018-02-28 |
|            2 | 2017-05-31 |
|            2 | 2016-09-30 |
|            3 | 0000-00-00 |
|            3 | 2019-05-31 |
|            4 | 2019-04-30 |
|            4 | 2019-09-30 |

(如何)我能否只获得每个候选人 ID 的第一个条目(最近的 start_date 行)?我只能得到结束日期不是 0000-00-00 的那些吗?

(糟糕,看来我在 end_date 之前的订单不起作用)

【问题讨论】:

标签: mysql sql date select greatest-n-per-group


【解决方案1】:

您可以使用相关子查询进行过滤:

select j.*
from jobs j
where j.start_date = (
    select max(start_date)
    from jobs j1
    where j1.candidate_id = j.candidate_id and j1.end_date <> '0000-00-00'
)

子查询返回最大的start_date,其end_date 不是当前候选的null

解决这个前 1 个每组问题的另一种典型方法是使用 anti-left 连接:

select j.*
from jobs j
left join jobs j1 
    on  j1.candidate_id = j.candidate_id
    and j1.start_date > j.start_date
    and j1.end_date is not null
where 
    j.end_date is not null
    and j1.job_id is null

这句话是:给我一个非null end_date 的记录,没有其他记录存在相同的candidate_id,一个更大的start_date 和一个非null end_date

【讨论】:

    【解决方案2】:

    您可以通过候选人加入 max start_date 组

    select  * 
    from jobs j
    inner join  (
    
      select candidate_id ,  max(start_date) max_start_date 
      from jobs
      group by   candidate_id
    
      ) t on t.candidate_id = j.candidate_id 
        and t.max_start_date = j.start_date 
    

    【讨论】:

      【解决方案3】:

      不带子查询的选项:

      SELECT
          j.*
      FROM
          jobs AS j
          LEFT JOIN jobs AS j2 ON (
                  j2.candidate_id = j.candidate_id
              AND j2.start_date   > j.start.date
          )
      WHERE
          j2.candidate_id IS NULL
      
      

      您希望使用复合索引 (candidate_id, start_date) 来优化查询。

      【讨论】:

        【解决方案4】:

        您可以通过聚合来做到这一点:

        select candidate_id,
               (case when sum(end_date = '0000-00-00') > 0
                     then '0000-00-00'
                     else max(end_date)
                end) as enddate
        from jobs j
        group by candidate_id;
        

        或者其他方法:

        select j.*
        from jobs j
        where j.end_date = '0000-00-00' or
              (not exists (select 1
                           from jobs j2
                           where j2.candidate_id = j.candidate_id and
                                 (j2.end_date = '0000-00-00' or
                                  j2.end_date > j.end_date
                                 )
                          )
              );
        

        甚至:

        select j.*
        from jobs j
        where j.job_id = (select j2.job_id
                          from jobs j2
                          where j2.candidate_id = j.candidate_id
                          order by (j2.end_date = '0000-00-00') desc,
                                   j2.end_date desc
                         );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-15
          • 2021-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-11
          • 1970-01-01
          相关资源
          最近更新 更多