仅过滤每个主-外键关系上的联接

时间:2018-07-25 06:13:17

标签: mysql sql database inner-join greatest-n-per-group

我正在使用MySql。

我有一个具有主键job的表job_pk_id,该表存储了每个作业的详细信息。我还有一个表job_running_status,其中job表的job_pk_id是外键,该表基本上包含为每个job_pk_id运行作业的记录。会有多个条目同一作业job_pk_id执行多次。 job_running_status表还具有字段job_start_time,该字段给出了作业运行的每个实例的开始时间。

现在,我的要求是为每个job_running_status获取最新的job。将根据job_running_status中的最新job_start_time(仅针对特定作业)值来选择最新的job_running_status

我知道这可以通过在INNER JOIN表和ORDER BY job_start_time desc表之间使用jobjob_running_status来实现,但是我面临的挑战是ORDER BY在所有JOIN中的作业,但我仅适用于与特定作业相对应的记录。

EDIT I understand it might be confusing to understand me by just reading so I am providing some examples:

job表:

Job Table Image

job_running_status表:

job_running_status image

My final requirement after joining both the tables

My final requirement after joining both the tables

注意:加入时,我应仅获得1条对应于每个JOB表记录的记录。该记录是根据该作业的最新job_start_time选择的。

2 个答案:

答案 0 :(得分:2)

where子句中相关子查询的示例

drop table if exists t,t1;
create table t(id int);
create table t1(jid int,dt date);
insert into t values
(1),(2),(3);

insert into t1 values
(1,'2018-01-01'),
(1,'2018-02-01'),
(2,'2018-01-01'),
(3,'2018-01-01'),
(3,'2018-02-01'),
(3,'2018-03-01');

select t.id,t1.dt
from t
join t1 on t1.jid = t.id
where t1.dt =(select max(dt) from t1 where t1.jid = t.id);

+------+------------+
| id   | dt         |
+------+------------+
|    1 | 2018-02-01 |
|    2 | 2018-01-01 |
|    3 | 2018-03-01 |
+------+------------+
3 rows in set (0.00 sec)

如果您需要最新的n条记录,而您没有使用8.0或更高版本,则可以使用行号模拟

select t.id,s.dt
from t
join 
(select t1.jid,t1.dt ,
          if(t1.jid<>@p,@rn:=1,@rn:=@rn+1) rn,
          @p:=t1.jid p
from t1 
cross join (select @rn:=0,@p:=0) r
order by t1.jid ,t1.dt desc
) s on s.jid = t.id
where s.rn <= 2;

+------+------------+
| id   | dt         |
+------+------------+
|    1 | 2018-01-01 |
|    1 | 2018-02-01 |
|    2 | 2018-01-01 |
|    3 | 2018-02-01 |
|    3 | 2018-03-01 |
+------+------------+

答案 1 :(得分:1)

您可以尝试此查询。 CROSS JOIN和子查询,它们得到MAX(job_running_status)

然后联接jobjob_running_status表。

TestDLL

CREATE TABLE JOB(
   job_pk_id int
);

INSERT INTO JOB VALUES (1),(2),(3);


CREATE TABLE job_running_status(
   fk_job_id INT,
   job_running_status DATE
);

INSERT INTO  job_running_status VALUES (1,'2018-01-01');
INSERT INTO  job_running_status VALUES (1,'2018-02-01');
INSERT INTO  job_running_status VALUES (2,'2018-01-03');
INSERT INTO  job_running_status VALUES (2,'2018-01-02');

查询

SELECT DISTINCT 
    j.job_pk_id,
    jrs.fk_job_id,
    t.job_running_status
FROM 
(SELECT MAX(job_running_status) job_running_status FROM job_running_status) t
CROSS JOIN job j 
inner join job_running_status  jrs on j.job_pk_id = jrs.fk_job_id

[结果]

| job_pk_id | fk_job_id | job_running_status |
|-----------|-----------|--------------------|
|         1 |         1 |         2018-02-01 |
|         2 |         2 |         2018-02-01 |

sqlfiddle