我的问题:
我正在尝试与一个表中的数据子集进行比较,并且我有两种方法可以部分工作,并且确定必须有一种更正确的方法来做到这一点。
这里的想法是一个包含关于同一系统随时间推移的数据集的表格,我想比较它们,特别是看看何时有介绍或缺席。请允许我用一个简单的测试表来演示:
mysql> select * from gocore;
+-----+------------+------+----------+----------+
| uid | server | tag | software | revision |
+-----+------------+------+----------+----------+
| 1 | enterprise | old | apache | 2.2.25 |
| 2 | enterprise | new | apache | 2.4.6 |
| 3 | enterprise | new | tomcat | 7.0.42 |
| 4 | enterprise | old | geronimo | 2.1.7 |
+-----+------------+------+----------+----------+
Run Code Online (Sandbox Code Playgroud)
在这个例子中有两个数据集——标签“旧”数据集和标签“新”数据集。每个都反映了在某个时间点采集的数据样本。对于服务器“企业”,我们有一个随时间变化的软件包(apache)、一个引入的软件包(tomcat)和一个消失的软件包(geronimo)。
我的目标:一个可以让我总结“旧”和“新”之间状态的查询:
+------------+----------+----------+----------+
| server | software | revision | revision |
+------------+----------+----------+----------+
| enterprise | apache | 2.2.25 | 2.4.6 |
| enterprise | geronimo | 2.1.7 | NULL |
| enterprise | tomcat | NULL | 7.0.42 |
+------------+----------+----------+----------+
Run Code Online (Sandbox Code Playgroud)
能够看到上面的“NULL”单元格对于我的目的很重要 - 我需要知道何时从系统中添加或删除了软件。需要明确的是,上面的表格不是查询的结果——是我使用文本编辑器来修复我所描述的我正在寻找的内容。我需要你的帮助来找出制作该表的查询:)
我的 Kludges:
如果我执行 LEFT JOIN 并使用 WHERE 子句来区分“旧”和“新”标签,我只会得到两个标签下都存在的条目的结果:
mysql> select old.server, old.software, old.revision, new.software, new.revision
-> from gocore as old left join gocore as new on old.software = new.software
-> where old.tag = 'old' and new.tag = 'new';
+------------+----------+----------+----------+----------+
| server | software | revision | software | revision |
+------------+----------+----------+----------+----------+
| enterprise | apache | 2.2.25 | apache | 2.4.6 |
+------------+----------+----------+----------+----------+
Run Code Online (Sandbox Code Playgroud)
我的下一个尝试是创建两个视图,以便我可以在不将标签过滤器混入的情况下执行 JOIN:
mysql> create view gc_old as select uid,server,tag,software,revision
-> from gocore where tag = 'old';
Query OK, 0 rows affected (0.00 sec)
mysql> create view gc_new as select uid,server,tag,software,revision
-> from gocore where tag = 'new';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from gc_old;
+-----+------------+------+----------+----------+
| uid | server | tag | software | revision |
+-----+------------+------+----------+----------+
| 1 | enterprise | old | apache | 2.2.25 |
| 4 | enterprise | old | geronimo | 2.1.7 |
+-----+------------+------+----------+----------+
2 rows in set (0.00 sec)
mysql> select * from gc_new;
+-----+------------+------+----------+----------+
| uid | server | tag | software | revision |
+-----+------------+------+----------+----------+
| 2 | enterprise | new | apache | 2.4.6 |
| 3 | enterprise | new | tomcat | 7.0.42 |
+-----+------------+------+----------+----------+
2 rows in set (0.00 sec)
mysql> select old.server, old.software, old.revision, new.revision
-> from gc_old as old left join gc_new as new
-> on old.software = new.software;
+------------+----------+----------+----------+
| server | software | revision | revision |
+------------+----------+----------+----------+
| enterprise | apache | 2.2.25 | 2.4.6 |
| enterprise | geronimo | 2.1.7 | NULL |
+------------+----------+----------+----------+
2 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
那效果更好——我现在看到的是缺席,不仅仅是变化,但我仍然没有看到介绍。我不得不为此创建视图,这让我感到不灵活,因为随着时间的推移添加数据集。
我的问题:
非常感谢您可以提供的任何帮助。谢谢!
我认为您必须使用派生表对其进行一些修改,也就是隐式临时表,也就是“ from 子句中的子查询”。
我们派生出一个表,我们将其称为 `t`,其中包含来自 gocore 的每个不同的(服务器、软件),然后左连接到 gocore 两次,一次在 tag = 'old' 上,一次在 tag = 'new' 上。
SELECT t.server, t.software, o.revision AS old_rev, n.revision AS new_rev
FROM (SELECT DISTINCT server, software FROM gocore) t
LEFT JOIN gocore o ON o.server = t.server AND o.software = t.software AND o.tag = 'old'
LEFT JOIN gocore n ON n.server = t.server AND n.software = t.software AND n.tag = 'new';
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31221 次 |
最近记录: |