Mysql LEFT JOIN GROUP BY LAST 每个表的记录
Posted
技术标签:
【中文标题】Mysql LEFT JOIN GROUP BY LAST 每个表的记录【英文标题】:Mysql LEFT JOIN GROUP BY LAST Records from each Table 【发布时间】:2020-09-08 18:37:38 【问题描述】:我想链接几个表,并在链接表中拥有每个条目的最后记录。
例如
Tabelle Domain
-- ID -- | -- DOMAIN -- | -- DATE --
1 seite.de 08-09-2020
Tabelle Domain Verify
-- ID -- | -- DOMAIN_ID -- | -- IS SSL -- | -- DATE --
1 1 0 06-09-2020
2 1 1 07-09-2020
3 1 1 08-09-2020
Tabelle Domain SSL
-- ID -- | -- DOMAIN_ID -- | -- SSL NAME -- | -- DATE --
1 1 NOT 06-09-2020
2 1 ENCRYPT 07-09-2020
3 1 ENCRYPT 08-09-2020
Tabelle Revoked:
-- ID -- | -- DOMAIN_ID -- | -- REVOKED -- | -- DATE --
1 1 1 06-09-2020
2 1 0 07-09-2020
3 1 0 08-09-2020
现在他在域 SSL 表中向我显示 SSL 名称不是。但想展示从 08.09 开始的 ENCRYPT STANDS 的最新帖子
SELECT
domain.id,
domain_verify.domain_id,
domain_verify.ssl_check
domain_ssl.domain_id,
domain_ssl.ssl_name,
domain_ssl_revoked.domain_id,
domain_ssl_revoked.revoked
FROM domain
LEFT JOIN domain_verify
ON domain_verify.domain_id = domain.id
LEFT JOIN domain_ssl
ON domain_ssl.domain_id = domain_verify.id
LEFT JOIN domain_ssl_revoked
ON domain_ssl_revoked.domain_id = domain_verify.id
GROUP BY domain_verify.id ORDER BY domain_verify.date DESC
【问题讨论】:
哪个版本的mysql,能不能显示出预期的数据。 你应该学习如何使用GROUP BY
。您的代码不应该执行。它应该会出错。
【参考方案1】:
考虑通过相应的聚合查询加入。下面使用表别名来提高可读性(即减少所有 domain
引用)。
SELECT d.id
, v.domain_id AS v_domain_id, v.ssl_check
, s.domain_id AS s_domain_id, s.ssl_name
, r.domain_id AS r_domain_id, r.revoked
FROM domain d
LEFT JOIN domain_verify v ON v.domain_id = d.id
INNER JOIN
(SELECT domain_id, MAX(date) as max_date
FROM domain_verify v
GROUP BY domain_id) agg_v
ON agg_v.domain_id = v.domain_id
AND agg_v.max_date = v.date
LEFT JOIN domain_ssl s ON s.domain_id = v.id
INNER JOIN
(SELECT domain_id, MAX(date) as max_date
FROM domain_ssl
GROUP BY domain_id) agg_s
ON agg_s.domain_id = s.domain_id
AND agg_s.max_date = s.date
LEFT JOIN domain_ssl_revoked r ON r.domain_id = v.id
INNER JOIN
(SELECT domain_id, MAX(date) as max_date
FROM domain_ssl_revoked
GROUP BY domain_id) agg_r
ON agg_r.domain_id = r.domain_id
AND agg_r.max_date = r.date
ORDER BY v.date DESC
如果你有一天支持window functions(在 MySQL 8.0+ 中合并),请考虑标记行并检查最大日期。
SELECT `id`, `date`, v_domain_id, ssl_check, ssl_namme, revoked
FROM
(SELECT d.id
, v.date, v.domain_id AS v_domain_id, v.ssl_check
, s.domain_id AS s_domain_id, s.ssl_name
, r.domain_id AS r_domain_id, r.revoked
, if(v.date = MAX(v.date) OVER(PARTITION BY v.domain_id), 1, 0) AS latest_v_dt
, if(s.date = MAX(s.date) OVER(PARTITION BY s.domain_id), 1, 0) AS latest_s_dt
, if(r.date = MAX(r.date) OVER(PARTITION BY r.domain_id), 1, 0) AS latest_r_dt
FROM domain d
LEFT JOIN domain_verify v
ON v.domain_id = d.id AND latest_v_dt = 1
LEFT JOIN domain_ssl s
ON s.domain_id = v.id AND latest_s_dt = 1
LEFT JOIN domain_ssl_revoked r
ON r.domain_id = v.id AND latest_r_dt = 1
) sub
ORDER BY `date` DESC
【讨论】:
以上是关于Mysql LEFT JOIN GROUP BY LAST 每个表的记录的主要内容,如果未能解决你的问题,请参考以下文章
带有 LEFT JOIN 和 GROUP BY 的 COUNT(*) 在 MySQL 中包含 NULL
来自 GROUP_BY 的两个 LEFT JOIN 的 GROUP_CONCAT 的奇怪重复行为
SQL 笔记1,left join,group by,having
SQL GROUP BY 与 LEFT JOIN MS SQL Server
带有 WHERE 子句的 GROUP BY 以及 sql 中的 OR 的 LEFT JOIN
SQL sum()后许多字段要group by不使用group by, 改用left join select 需要的字段。哪个方法好?速度快?