【问题标题】:Filter a join on each primary-foreign key relation only仅过滤每个主外键关系上的连接
【发布时间】:2019-01-01 20:44:10
【问题描述】:

我正在使用 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 获取最新的 job_running_status 。最新的job_running_status 将根据job_running_status 中最新的job_start_time(仅针对该特定工作)值进行选择。

我知道这可以在job 表和job_running_status 表之间使用INNER JOINORDER BY job_start_time desc 来实现,但我的挑战是这个ORDER BY 适用于JOIN 中的所有工作,但我需要仅适用于与特定工作对应的记录。

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

job表:

job_running_status表:

My final requirement after joining both the tables

注意:在加入时,我应该只获得与每个 JOB 表记录相对应的 1 条记录。该记录是根据该 JOB 的最新 job_start_time 选择的。

【问题讨论】:

  • 显示一些示例数据会很好 ^ ^
  • '最新的 job_running_status 将根据 job_running_status 中最新的 job_start_time(仅针对该特定作业)值进行选择。您似乎只为每个工作选择了 1 条记录,那么为什么除了工作之外还需要订单?
  • '但我只需要适用于与特定工作相对应的记录。' - 所以如果你有那个jobname/id,就放一个过滤器
  • 搜索相关子查询。顺便说一句,样本数据和预期输出作为文本更好,我们可以使用它而不是我们不能使用的图像。
  • @TimBiegeleisen 编辑了我的原始帖子以提供示例。

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


【解决方案1】:

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 条记录)。是否有任何方法可以使用与我想要获取作业记录的最新 2 个作业运行实例相同的条件来获取多于 1 条记录?
  • 那是范围蔓延。您的问题应该是如何获得最新的 n 条记录。不,你不能使用这种方法。我很快就会为此添加代码。
  • 哎呀,对不起,伙计……请务必添加代码……我将编辑原帖上的标题
  • 呃,为什么?我在 2 天前添加的“如果您需要最新的 n 条记录...”开始的编辑满足了您的要求。
【解决方案2】:

你可以试试这个查询。 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

【讨论】:

  • 知道了,很有帮助
  • 此查询给出最新记录(即 1 条记录)。是否有任何方法可以使用与我想要获取作业记录的最新 2 个作业运行实例相同的条件来获取多于 1 条记录?
  • 你想这样使用MAX吗? SELECT j.job_pk_id, jrs.fk_job_id, MAX(t.job_running_status) job_running_status FROM job j inner join job_running_status jrs on j.job_pk_id = jrs.fk_job_id GROUP BY j.job_pk_id, jrs.fk_job_id
  • 我可以更正一下吗:在FROM之前你写了job_running_status这是一个表名。是故意的还是只是一个错字?
猜你喜欢
  • 2018-08-28
  • 2013-07-20
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多