我们有应用程序,它们在主机上运行,其上有软件。
应用程序可以在许多主机上运行。主机通常会在其上加载许多软件项。
我们使用Application表捕获此信息,并使用另外两个表来捕获关系,Application-Host,Host-Software。
但是,主机可能没有软件。 (它可能真的是空的,或者我们可能还没有信息,都需要突出显示。)
对于每个应用程序,我需要计算具有软件的主机。我无法找到办法。
假设一个应用程序有5个主机,其中四个连接到软件。一个关系表包含5个主机,另外4个主机的实例,但是4个通过第一个关系表间接连接。
我怎样才能得到正确答案,4?无论我做什么,我得到5,或所有主机上的软件项目总数。
这是我到目前为止所拥有的,包括调试代码。
select distinct
AH.APPLICATION_X_COMPONENT_NAME,
count(case when T.TECH_ITEM_REL_ITCM_CAT = 'Operating System' then 1 end) over (partition by AH.APPLICATION_X_COMPONENT_NAME) as NoOfOpsys,
x.APPLICATION_X_COMPONENT_NAME,
x.HOST_COMPONENT_NAME,
x.NoHostsWithTIR
from dbo.CTO_TechnologyItemRelease as T
inner join dbo.CTOR_HOST_TECHITEMRELEASE as HT
on HT.TECH_ITEM_RELEASE_COMP_ID = T.TechnologyItemReleaseComponent
inner join dbo.CTOR_APPLICATIONX_HOST as AH
on AH.HOST_COMPONENT_ID = HT.HOST_COMPONENT_ID
inner join
(
select distinct
AH2.APPLICATION_X_COMPONENT_NAME,
AH2.HOST_COMPONENT_NAME,
count(case when HT2.HOST_COMPONENT_NAME is not null then 1 end) over (partition by AH2.APPLICATION_X_COMPONENT_NAME, HT2.HOST_COMPONENT_NAME) as NoHostsWithTIR
from dbo.CTOR_APPLICATIONX_HOST as AH2
inner join dbo.CTOR_HOST_TECHITEMRELEASE as HT2
on HT2.HOST_COMPONENT_NAME = AH2.HOST_COMPONENT_NAME
)
as x on x.APPLICATION_X_COMPONENT_NAME = AH.APPLICATION_X_COMPONENT_NAME
order by AH.APPLICATION_X_COMPONENT_NAME
数据:
App table
App_ID App_Name
A0001 Application_1
A0002 Application_2
A0003 Application_3
A0004 Application_4
App-Host table
App_ID App_Name Host_ID Host_Name
A0001 Application_1 H0001 Host_1
A0002 Application_2 H0001 Host_1
A0002 Application_2 H0002 Host_2
A0002 Application_2 H0003 Host_3
A0002 Application_2 H0004 Host_4
A0003 Application_3 H0005 Host_5
A0004 Application_4 H0002 Host_2
A0004 Application_4 H0006 Host_6
Host-TI table
Host_ID Host_Name TI_ID TI_Name
H0001 Host_1 T0001 MS SQL Server 2005 SP1
H0001 Host_1 T0002 MS Windows Server 2008
H0002 Host_2 T0002 Red Hat Enterprise Linux 3
H0003 Host_3 T0002 MS Windows Server 2008
H0003 Host_3 T0003 Oracle Database Server 9i 9.2
H0005 Host_5 T0001 MS SQL Server 2005 SP1
H0006 Host_6 T0004 Tivoli Storage Manager 5.2
TI table
TI_ID TI_Name TI_Type
T0001 MS SQL Server 2005 SP1 Software Product
T0002 MS Windows Server 2008 Operating System
T0003 Red Hat Enterprise Linux 3 Operating System
T0003 Oracle Database Server 9i 9.2 Software Product
T0004 Tivoli Storage Manager 5.2 Software Product
所需的输出
App Name Operating System count Hosts with Tech Items
Application_1 1 1
Application_2 3 3
Application_3 0 1
Application_4 1 2
关键的一行是Application_2,它有3个带有技术项目的主机。我只能在这个位置得到4,我的操作系统计数经常眨眼。
答案 0 :(得分:1)
数据库设计看起来很严重,因此数据似乎不一致:
这些行似乎相互矛盾:
H0001 Host_1 T0002 MS Windows Server 2008
H0002 Host_2 T0002 Red Hat Enterprise Linux 3
这些:
T0003 Red Hat Enterprise Linux 3 Operating System
T0003 Oracle Database Server 9i 9.2 Software Product
我会假设数据无效,并且正确的数据是SQL Fiddle中的行。
根据这个假设,这段代码可以满足您的需求:
select a.app_ID, a.app_name,
(select Count(*)
from apphost ah
inner join hostti ht on ah.host_id = ht.host_id
inner join ti on ht.ti_id=ti.ti_id
where ti_type = 'Operating System'
and ah.app_id = a.app_id) as OSCount,
(select Count(distinct ah.host_id)
from apphost ah
inner join hostti ht on ah.host_id = ht.host_id
where ah.app_id = a.app_id) as HostWithSoftwareCount
from App a
答案 1 :(得分:0)
这样的事情:
select a.name, COUNT(*)
from application a
join application_host ah on (a.id = ah.application)
join host h on (h.id = ah.host)
where exists (select top 1 1 from host_software hs where hs.host = ah.host)
group by a.name
答案 2 :(得分:0)
我同意with @SWeko关于数据样本不一致的问题,以及我对这个问题的看法:
SELECT
ap.App_Name,
OperatingSystemCount = COUNT(ti.TI_ID),
HostsWithTechItems = COUNT(DISTINCT ah.Host_ID)
FROM
App AS ap
LEFT JOIN
AppHost AS ah
INNER JOIN HostTI AS ht ON ah.Host_ID = ht.Host_ID
LEFT JOIN TI AS ti ON ht.TI_ID = ti.TI_ID AND ti.TI_Type = 'Operating System'
ON ap.App_ID = ah.App_ID
GROUP BY
ap.App_Name
;
此查询的SQL小提琴演示可在此处找到:http://sqlfiddle.com/#!3/677ae/3
请注意,在计算操作系统时,查询无法识别其中某些操作系统可能安装在同一主机上的事实:在这种情况下,每个实例都会被计算在内。如果您实际上打算使用操作系统计算主机,则需要通过将COUNT(ti.TI_ID)
替换为类似
COUNT(DISTINCT CASE WHEN ti.TI_ID IS NOT NULL THEN ah.Host_ID END)