Oracle SQL用空值替换返回列

时间:2016-04-10 14:53:19

标签: sql oracle

我想修改以下查询,以便它不是ORDER.S_ID列,而是从表(称为STORES)S_ID引用的相应NAME列中获取值。

但是,在某些情况下,S_ID为null,在这种情况下,没有相应的名称列。在这种情况下,仍然有来自ORDER和ORDERLIST表的记录,我想要COUNT(*) - ed并由此查询显示,以便结果集的第二列为空

SELECT 
COUNT(*), ORDER.S_ID 
FROM 
ORDER, ORDERLIST 
WHERE 
ORDERLIST.O_ID = ORDER.ID AND 
ORDER.DATE = '13-APR.  -09 19.42.05,259000000' 
GROUP BY S_ID;

示例数据:

ORDER表

ID  DATE                            S_ID
----------------------------------------              
1   11-APR.  -09 19.41.39,187000000 null
2   12-APR.  -09 19.42.05,259000000 null
3   13-APR.  -09 19.42.41,688000000 null
11  16-APR.  -09 22.06.11,169000000 3

ORDERLIST表

O_ID    B_ID    PRICE
---------------------
3       6       7999
2       2       2000
2       6       7999
1       5       5000
1       1       1000
11      4       4000
11      6       7999

STORES表

ID  NAME
----------
1   Store1
2   Store2
3   Store3

如果用户查询S_ID值为非空的日期,我希望看到的内容:(此特定情况是查询日期16-APR。-09 22.06.11,169000000)

COUNT(*) STORENAME
2        Store3

如果它为空,我想要返回的内容: (查询日期13-APR.-09 19.42.41,688000000)

COUNT(*) STORENAME
1        null

1 个答案:

答案 0 :(得分:1)

正如Gordon所说,你需要一个外连接,并且使用正确的连接语法会更好 - 特别是对于外连接,但无论你的导师使用什么,都要一直使用。

由于您从订单开始并且可能具有匹配的商店,因此您需要将stores表的连接作为外部联接:

SELECT o.s_id, s.name, count(*)
FROM "ORDER" o
JOIN orderlist ol ON ol.o_id = o.id
LEFT JOIN stores s ON s.id = o.s_id
--WHERE o."DATE" = TO_TIMESTAMP('13-APR.  -09 19.42.05,259000000', 'DD-MON".  "-RR HH24.MI.SS,FF9')
GROUP BY o.s_id, s.name;

      S_ID NAME     COUNT(*)
---------- ------ ----------
                           5
         3 Store3          2

由于'order'和'date'是保留字,我必须使用带引号的标识符,但它们可能不是真实的名字。如果您可以避免使用带引号的标识符,请不要使用它们。我使用表别名来减轻痛苦。 'date'也是一个时间戳而不是一个日期,因为你有小数秒,使名称更令人困惑。

我已经注释了日期/时间戳限制,因为它与您的任何样本数据都不匹配,如果更改为4月12日仍然只匹配一个,这对于演示来说不是很有用。您的NLS_TIMESTAMP_FORMAT是......不寻常,但这是一个单独的问题。为了比较,使用时间戳文字更简单:

WHERE o."DATE" = TIMESTAMP '2009-04-12 19:42:05.259000000'

请注意,与NLS_TIMESTAMP_FORMAT不同,它具有冒号和句点作为秒值的小数分数。

如果您的导师真的坚持旧的,特定于Oracle的连接语法,那么可以将其排列为:

SELECT o.s_id, s.name, count(*)
FROM "ORDER" o, orderlist ol, stores s
WHERE ol.o_id = o.id
AND s.id (+) = o.s_id
--AND o."DATE" = TIMESTAMP '2009-04-12 19:42:05.259000000'
GROUP BY o.s_id, s.name;

...但是要弄清楚发生了什么事情要困难得多,而且更容易在连接条件中犯错(或者完全留下一个)。请使用正确的ANSI连接语法...