首页 > 解决方案 > MySQL 模拟延迟以减少旧服务器上的冗余项目

问题描述

前面的底线:我正在尝试找到一种格式化输出的方法,以便如果某些数据与前一行匹配,则将其留空。

我按照@philipxy 的建议进行了编辑,因为我真的很想学习如何编写更好的代码并编写更好的问题来支持这种学习。

话虽如此,@ysth 无论如何都能解决我过于复杂的问题。我更改了标题并标记为已回答。

这是我数据库中的示例表:( SELECT codename, dt_begin, id_alias FROM aliases GROUP BY codename;)

+--------------+------------+----------+
| codename     | dt_begin   | id_alias |
+--------------+------------+----------+
| Arachniblade | 1999-12-23 |        1 |
| Arachniblade | 2016-07-04 |        2 |
| Beta         | 2015-06-03 |        1 |
| Beta         | 2016-07-04 |        3 |
| Cyberwolf    | 2016-07-04 |        1 |
+--------------+------------+----------+

我希望“Arachniblade”和“Beta”的第二个(以及任何后续)实例在ORDER BY codename使用时为空白。

+--------------+------------+----------+
| codename     | dt_begin   | id_alias |
+--------------+------------+----------+
| Arachniblade | 1999-12-23 |        1 |
|              | 2016-07-04 |        2 |
| Beta         | 2015-06-03 |        1 |
|              | 2016-07-04 |        3 |
| Cyberwolf    | 2016-07-04 |        1 |
+--------------+------------+----------+

同样,如果我ORDER BY id_alias希望只打印一次 id 1,但仍保留“Arachniblade”、“Beta”和“Cyber​​wolf”的所有三个记录。

+--------------+------------+----------+
| codename     | dt_begin   | id_alias |
+--------------+------------+----------+
| Arachniblade | 1999-12-23 |        1 |
| Beta         | 2015-06-03 |          |
| Cyberwolf    | 2016-07-04 |          |
| Arachniblade | 2016-07-04 |        2 |
| Beta         | 2016-07-04 |        3 |
+--------------+------------+----------+

正如@ysth 提到的 LAG() 是解决方案的一部分。我不确定 COALESCE 是如何适应的。

标签: mysqljoin

解决方案


所以你不想 GROUP BY 任何东西,但你希望 Codename 是空白的,它等于前一行的 Codename?你会选择这个而不是只选择 aliases.codename:

IF(COALESCE(LAG(aliases.codename) OVER (),'')=aliases.codename,'',aliases.codename) AS 'Codename'

假设 mysql 8.0 或 mariadb 10.2+。完整查询:

SELECT IF(COALESCE(LAG(aliases.codename) OVER (),'')=aliases.codename,'',aliases.codename) AS 'Codename',
       aliases.dt_begin,
       public_ids.fname,
       public_ids.suffix
FROM   public_ids
JOIN   aliases ON aliases.id_alias 
WHERE  aliases.id_alias = public_ids.id
ORDER BY aliases.codename, aliases.dt_begin

(您在查询中省略了 ORDER BY;如果没有指定的顺序,想要这样做没有多大意义。)

在旧版本上,您可以使用变量模拟 LAG():

SELECT IF(COALESCE(@lag,'')=aliases.codename,'',@lag:=aliases.codename) AS 'Codename',
       aliases.dt_begin,
       public_ids.fname,
       public_ids.suffix
FROM   (select @lag:=NULL) initvars
CROSS JOIN public_ids
JOIN   aliases ON aliases.id_alias 
WHERE  aliases.id_alias = public_ids.id
ORDER BY aliases.codename, aliases.dt_begin

推荐阅读