0

我们有应用程序,它们在主机上运行,​​主机上有软件。

一个应用程序可以在许多主机上运行。主机通常会加载许多软件项目。

我们使用一个应用程序表捕获此信息,并使用另外两个表来捕获关系,即应用程序-主机、主机-软件。

但是,主机可能没有软件。(它可能真的是空的,或者我们可能还没有信息,都需要突出显示。)

对于每个应用程序,我需要计算其上有软件的主机。我找不到办法做到这一点。

假设一个应用程序有 5 台主机,其中 4 台连接到软件。一个关系表包含 5 个 Host,另外一个包含 4 个 Host 的多个实例,但是这 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,而且我的操作系统计数经常闪烁。

4

3 回答 3

1

数据库设计似乎严重fubar'd,因此数据似乎不一致:

这些行似乎相互矛盾:

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 
于 2013-08-15T12:56:31.520 回答
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

http://sqlfiddle.com/#!2/c4bbb/2

于 2013-08-15T13:04:16.933 回答
0

我同意@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 Fiddle 演示: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)
于 2013-08-15T17:14:56.147 回答