SQL Query不返回任何行

时间:2014-03-24 19:33:18

标签: sql oracle

我正在处理查询,以获取安装了多个防病毒软件的所有计算机的列表。不幸的是,我无法让我的查询返回任何内容。正如您在下面的屏幕截图中所看到的,我已经设置了数据,以便在我查询工作时,我的结果集将包含设备1,2和3上的数据。

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;

4 个答案:

答案 0 :(得分:3)

您需要从av.nameSELECT中删除防病毒名称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
 )