问题
仓库表(store)
storeId | name |
---|---|
1 | A区 |
2 | B区 |
3 | C区 |
库存表(stock)
stockId | name | count | storeId |
---|---|---|---|
1 | 螺丝 | 5 | 1 |
2 | 钉子 | 4 | 2 |
3 | 脚手架 | 4 | 2 |
4 | 衣架 | 4 | 2 |
5 | 铁衣架 | null | 2 |
现要求用sql语句取出每个仓库中的货物数量
SELECT
SUM(ISNULL(K.count,0)) AS storeNum,
S.storeId
FROM
store AS S
LEFT JOIN
stock AS K
ON S.storeId = K.storeId
GROUP BY
S.storeId
我们使用sum(isnull(k.count,0))是为了将空数据的值返回0,而用上面的语句会发现仓库表中storeId为3的storeNum会为null而不是想象中的0
storeNum | storeId |
---|---|
5 | 1 |
12 | 2 |
null | 3 |
而使用
SELECT
ISNULL(SUM(K.count),0) AS storeNum,
S.storeId
FROM
store AS S
LEFT JOIN
stock AS K
ON S.storeId = K.storeId
GROUP BY
S.storeId
得到的数据却是正常的0
storeNum | storeId |
---|---|
5 | 1 |
12 | 2 |
0 | 3 |
原因
首先,来分析下sum的工作原理,由于sum是在对列进行相加的时候会在对值为null的行跳过,若单独使用sum函数时只有null数据的时候会跳过这些数据返回null,而没有数据进行sum的时候也会返回null,在这个例子中我们用了group by对其进行分组,而仓库表storeId为3的数据与库存表左连接时是没有数据的,所以当我们使用sum(isnull(K.count,0))的时候其实isnull函数没有执行,所以sum函数在进行相加的时候是没有相加的还是会返回null。
结论
所以其实在sum有数据的时候,isnull在sum的外面和isnull在sum的里面是没有区别的,当sum函数没有数据的时候,则需要将isnull函数放在外面防止sum的无数据的时候isnull不起作用。