我目前正在尝试制定一个查询,以确定是否在所述主机上安装了某些软件应用程序。我们在数据库中的表是这样设置的,其中包含包含主机名和软件的列,例如,主机 A 可能有 10 条记录,展示了在其上找到的 10 个单独的软件。前任。以下
ID Host SW
--------------------------
1 Host A SW A
1 Host A SW B
1 Host A SW C
2 Host B SW B
2 Host B SW C
3 Host C SW F
我试图找到的是所有安装了软件 A(标志 Y/N)和安装了软件 B(标志 Y/N)的主机,并以(使用上面的示例)返回的方式格式化结果。 ..
Expected Results
Host SWA_Installed SWB_Installed
----------------------------------------------
Host A Y Y
Host B N Y
Host C N N
我在下面的查询是到目前为止我所拥有的(注意实际的数据库代码,那些是实际的软件名称)...
SELECT DISTINCT
HOST.a_display_label AS HOST,
CASE
WHEN
sof.a_display_label = 'HPS' THEN 'Y'
ELSE 'N'
END AS HPS_INSTALLED,
CASE
WHEN
sof.a_display_label = 'PowerToken' THEN 'Y'
ELSE 'N'
END AS PT_INSTALLED
FROM vcms.node_1 HOST
JOIN vcms.installed_software_1 sof
ON LOWER (sof.a_root_container) = LOWER (HOST.cmdb_id)
问题是,即使它正在获取 DISTINCT 结果,它仍然会返回主机的多个记录,因为安装在其上的每个软件都有多个主机记录。最终结果如下所示:
Query Results
Host SWA_Installed SWB_Installed
----------------------------------------------
Host A Y N
Host A N Y
Host A N N
Host B N N
Host B N Y
Host C N N
我想知道返回“预期结果”数据需要哪些附加信息。先感谢您。
最佳答案
只需使用条件聚合:
select h.a_display_label as host,
max(case when s.a_display_label = 'HPS' then 'Y' else 'N'
end) as hps_installed,
max(case when s.a_display_label = 'PowerToken' then 'Y' else 'N'
end) as pt_installed
from vcms.node_1 h join
vcms.installed_software_1 s
on lower(s.a_root_container) = lower(h.cmdb_id)
group by h.a_display_label;
注意:这取决于
'Y'
> 'N'
,因此该逻辑不适用于 min()
而不是 max()
.我通常只使用“1”表示是,“0”表示否,而不是字符。我还应该评论我发现
SELECT DISTINCT
聚合函数是一个非常尴尬的构造。你真的应该考虑 GROUP BY
而不是 SELECT DISTINCT
用于聚合查询。
关于sql - SELECTING 数据与 CASE 语句问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38460516/