Return 如果在 Oracle 中没有选择行,列中为 0

Return 0 in columns if no rows selected in Oracle

当我在 Oracle 数据库中执行查询时,它 return 有 0 行。如果未选择任何行,我需要将 return 列值设置为 0。请查找随附的示例查询。

select NVL(staff,0), NVL(code,0)
       from stafftable
      where staffid= 123
        and code in (112, 251)
        and closedate is not null
        and rownum<2
        order by opendate desc;

如果没有选择行,我需要以下结果:

NVL(staff,0)      NVL(code,0)
0                 0

我试过NVL()、coalsce()都没有得到预期的结果。

I have tried NVL(), coalsce() not able to get the expected result.

因为它确实return没有任何结果,所以我们可能得到空结果

我们可以尝试使用 CTEUNION ALL

一个用于过滤结果,另一个用于空结果的默认结果

WITH cte AS ( 
      select staff, code
       from stafftable
      where staffid= 123
        and code in (112, 251)
        and closedate is not null
        and rownum<2
)
SELECT staff, code
FROM cte
UNION ALL 
SELECT 0 , 0 
FROM dual
WHERE NOT EXISTS (
   SELECT 1
   FROM cte 
) 

另一个最大值的解决方案,假设 staff 中的值为正数:

select max(staff) staff, max(code) code
FROM (
       select staff, code
         from stafftable
        where staffid= 123
          and code in (112, 251)
          and closedate is not null
          and rownum<2 
       UNION ALL
       SELECT 0 , 0 FROM dual
    )

您可以 UNION ALL 一个带有零的行,然后,从 Oracle 12,FETCH FIRST ROW ONLY:

SELECT NVL(staff,0) AS staff,
       NVL(code,0) AS code
FROM   stafftable
WHERE  staffid= 123
AND    code in (112, 251)
AND    closedate is not null
UNION ALL
SELECT 0, 0 FROM DUAL
-- ORDER BY staff DESC, code DESC
FETCH FIRST ROW ONLY;

这只会对 stafftable.

执行一次 table/index 扫描

如果您想在 Oracle 11 中执行相同操作,请使用 sub-query 并在 ROWNUM:

上过滤外部查询
SELECT staff,
       code
FROM   (
  SELECT NVL(staff,0) AS staff,
         NVL(code,0) AS code
  FROM   stafftable
  WHERE  staffid= 123
  AND    code in (112, 251)
  AND    closedate is not null
UNION ALL
  SELECT 0, 0 FROM DUAL
-- ORDER BY staff DESC, code DESC
)
WHERE  ROWNUM = 1;

如果您想按 OPENDATE 对行进行排序,则:

SELECT *
FROM   (
  SELECT NVL(staff,0) AS staff,
         NVL(code,0) AS code
  FROM   stafftable
  WHERE  staffid= 123
  AND    code in (112, 251)
  AND    closedate is not null
  ORDER BY opendate DESC
)
UNION ALL
SELECT 0, 0 FROM DUAL
FETCH FIRST ROW ONLY;

SELECT *
FROM   (
  SELECT *
  FROM   (
    SELECT NVL(staff,0) AS staff,
           NVL(code,0) AS code
    FROM   stafftable
    WHERE  staffid= 123
    AND    code in (112, 251)
    AND    closedate is not null
    ORDER BY opendate DESC
  )
UNION ALL
  SELECT 0, 0 FROM DUAL
)
WHERE  ROWNUM = 1;

db<>fiddle here