2014-03-24 204 views
0

我正在查询以获取安装了多个防病毒软件的所有计算机的列表。不幸的是,我无法让我的查询返回任何东西。正如你在截图参见下面我已经安装了数据,这样,当我得到查询工作我的结果集将包含在设备1,2的数据,和3SQL查询不返回行

Devices Table

Antivirus Products Table

以下是我已经得到了目前:

SELECT d.ip_address AS "IP Address", 
     d.name AS "Computer Name", 
     av.name AS "Antivirus Name", 
     COUNT(av.deviceID) AS "# of AV Installed" 
FROM devices d JOIN anti_virus_products av 
ON d.deviceID = av.deviceID 
GROUP BY d.ip_address, d.name, av.name 
HAVING COUNT(av.deviceID) > 1; 

回答

3

您需要从SELECTGROUP BY删除防病毒名称av.name。通过将其包含在结果中,GROUP BY将为每台计算机和防病毒名称创建一个新行 - 因为这些值会创建一个唯一的组。

SELECT d.ip_address AS "IP Address", 
     d.name AS "Computer Name", 
     COUNT(av.deviceID) AS "# of AV Installed" 
FROM devices d JOIN anti_virus_products av 
ON d.deviceID = av.deviceID 
GROUP BY d.ip_address, d.name 
HAVING COUNT(av.deviceID) > 1; 

更新基于意见,扩大查询,列出安装在设备上的所有反病毒软件的名称:

你可以划分COUNT功能。我无法找到此文档的Oracle文档链接,但OVER Clause的SQL Server语法似乎适用于Oracle。参见SQL Fiddle

SELECT d.ip_address AS "IP Address", 
     d.name AS "Computer Name", 
     d.deviceid, 
     av.name AS "Antivirus Name", 
     COUNT(*) OVER (PARTITION BY d.ip_address, d.name) AS "Total # of AV Installed" 
FROM devices d JOIN anti_virus_products av 
ON d.deviceID = av.deviceID 
GROUP BY d.ip_address, d.name, d.deviceid, av.name; 

这个例子查询此示例查询将返回一个行的每个设备和防病毒对和包括安装在设备上的AV的总数。

我不确定这是否能解决您的问题,但它提供了您正在寻找的其他数据。

+0

谢谢!如果我想扩展此查询以列出安装在这些设备上的所有防病毒软件名称,我需要做什么? – tylerbhughes

0

如果你不需要抗病毒的名字,把它拿出来查询的。如果你这样做,你会在你的查询中需要这个地方。我会让你弄清楚在哪里。

and device.deviceid in 
(select deviceid 
from 
(select deviceid, count(*) records 
from anti_virus_products 
group by device_id 
having count(*) > 1) temp 
) 
+0

内查询返回超过1列... – KrazzyNefarious

+0

哎呀。不再。 –

1

只需从group by条款中删除av.name即可。您的查询返回有相同的杀毒软件多次安装计算机 - 一个不太可能的情景:

SELECT d.ip_address AS "IP Address", 
     d.name AS "Computer Name", 
     COUNT(av.deviceID) AS "# of AV Installed" 
FROM devices d JOIN 
    anti_virus_products av 
    ON d.deviceID = av.deviceID 
GROUP BY d.ip_address, d.name 
HAVING COUNT(av.deviceID) > 1; 

如果你想在杀毒软件上单排名称,你可以使用listagg()。以下是listagg的Oracle文档页面:http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions089.htm#SQLRF30030

+0

实际上,它已安装多个防病毒软件的返回计算机。例如,如果计算机安装了趋势科技和AVG,那么它将返回该计算机名称和一个2,因为它安装了2个不同的AV程序 – tylerbhughes

1

正如其他人所说的那样,由于每个渴望组有多个AV名称,查询无法按AV名称进行分组。这个查询将返回一个逗号分隔的AV名称的列表,每个计算机与计数一起:

SELECT d.ip_address AS "IP Address", 
     d.name AS "Computer Name", 
     (select name + ',' from anti_virus_products where deviceid = d.deviceid for xml path('')) AS "Antivirus Name", 
     avc."# of AV Installed" 
FROM devices d 
    JOIN (select deviceid,count(*) AS "# of AV Installed" from anti_virus_products 
      group by deviceid having count(*) > 1) avc 
     ON d.deviceID = avc.deviceID 
+0

有趣的方法。 –