我正在处理查询,以获取安装了多个防病毒软件的所有计算机的列表。不幸的是,我无法让我的查询返回任何内容。正如您在下面的屏幕截图中所看到的,我已经设置了数据,以便在我查询工作时,我的结果集将包含设备1,2和3上的数据。
这是我目前所拥有的:
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;
答案 0 :(得分:3)
您需要从av.name
和SELECT
中删除防病毒名称GROUP BY
。通过在结果中包含该值,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;
根据评论进行更新,以扩展查询以列出设备上安装的所有AV软件的名称:
您可以对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总数。
我不确定这是否可以解决您的问题,但它提供了您正在寻找的其他数据。
答案 1 :(得分:1)
只需从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;
如果您希望将防病毒软件的名称放在一行,则可以使用listagg()
。以下是listagg的Oracle文档页面:http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions089.htm#SQLRF30030
答案 2 :(得分: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
答案 3 :(得分:0)
如果您不需要防病毒名称,请将其从查询中删除。如果这样做,您将需要在查询中的某个位置。我会告诉你在哪里。
and device.deviceid in
(select deviceid
from
(select deviceid, count(*) records
from anti_virus_products
group by device_id
having count(*) > 1) temp
)