2014-03-24 240 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

有趣的方法。 –