当COUNT()什么都不返回时显示0

时间:2014-04-24 21:23:16

标签: sql oracle join count subquery

我试图找到卡在某种状态的设备,并按类型对它们进行分组。我在数据库中查询该状态的count()设备,然后进行几项检查以查看这些设备是否符合标准。但是,它没有显示没有任何count()的类型。我需要显示所有类型,即使count()没有任何内容。

例如,目前我有这个:

TYPE   COUNT(DEVICE.NAME)
TYPE1                 200
TYPE2                 100
TYPE3                  50

我需要它像这样回来:

TYPE   COUNT(DEVICE.NAME)
TYPE1                 200
TYPE2                 100
TYPE3                  50
TYPE4                   0
TYPE5                   0

这是我到目前为止所拥有的:

SELECT device.type, count(device.name)
FROM device
LEFT OUTER JOIN (SELECT type, name
                  FROM device) b
  ON device.name = b.name
WHERE device.changedon < (((SYSDATE - DATE '1970-01-01') * 24 * 60 * 60) - (90 * 24 * 60 * 60))
  AND device.status != 6 AND device.status != 8 AND device.status != 13
GROUP BY device.type
ORDER BY count(device.name) DESC;

后来意识到表b上的联接是不必要的,但我会将其留在问题中,以便答案仍能准确反映问题。

我在子查询上尝试了所有类型的连接,结果是一样的。

3 个答案:

答案 0 :(得分:2)

如果使用left outer join,则需要将其用于查询中的所有联接(通常)。否则,您可能正在“撤消”之前的联接。

但是,我不认为这是你唯一的问题。表达式count(d.name)必须至少返回1(除非name可以是NULL)。

SELECT d.type, count(h471.id)
FROM device d INNER JOIN
     (SELECT type, name
      FROM device
     ) b
     ON d.name = b.name
WHERE d.changedon < (((SYSDATE - DATE '1970-01-01') * 24 * 60 * 60) - (90 * 24 * 60 * 60)) and
      d.status != 6 AND d.status != 8 AND d.status != 13
GROUP BY d.type;

使用外连接时,还必须注意where子句。但是,在这种情况下,您只是引用device表。如果切换到left outer join无法解决问题,则问题出在where子句中 - 它会过滤掉其他设备。如果是这种情况,则将where子句移动到条件聚合:

SELECT d.type,
       sum(case when d.changedon < (((SYSDATE - DATE '1970-01-01') * 24 * 60 * 60) - (90 * 24 * 60 * 60)) and
                       d.status != 6 AND d.status != 8 AND d.status != 13
                  then 1 else 0
            end)
FROM device d LEFT OUTER JOIN
     (SELECT type, name
      FROM device
     ) b
     ON d.name = b.name 
GROUP BY d.type;

出于性能原因,您可以将某些条件移回where子句。

另外,我没有得到表b的联接。它只是乘以行数(如果device中的多行具有相同的名称)或什么都不做。

答案 1 :(得分:2)

我认为你需要像

这样的东西
SELECT type, SUM(COUNT_RESULT)
  FROM (

          SELECT device.type, 0 COUNT_RESULT
          FROM device

          UNION ALL

          SELECT device.type, count(1)
          FROM device, h471
          WHERE device.recnum = h471.id
            AND device.changedon < (((SYSDATE - DATE '1970-01-01') * 24 * 60 * 60) - (90 * 24 * 60 * 60))
            AND device.status != 6 AND device.status != 8 AND device.status != 13

)        
GROUP BY type

答案 2 :(得分:-1)

通过将整个查询转换为子查询并将COALESCE应用于0以获取缺失结果,看起来可以实现您想要的任务。

SELECT d0.type, COALESCE(d.cnt,0) FROM device d0
LEFT OUTER JOIN (
  SELECT device.type, count(device.name) AS cnt
  FROM device
  LEFT OUTER JOIN (SELECT type, name
                    FROM device) b
    ON device.name = b.name
  WHERE device.changedon < (((SYSDATE - DATE '1970-01-01') * 24 * 60 * 60) - (90 * 24 * 60 * 60))
  AND device.status != 6 AND device.status != 8 AND device.status != 13
  GROUP BY device.type) d
ORDER BY COALESCE(d.cnt,0) DESC;