我正在使用sql server 2005。
我有两列a和b。
我希望从a中减去b来生成c,我按如下方式执行:
a - b as c
但如果a或b为0,我想通过c = 0来补充这一点。我该怎么做?
谢谢,
巴里答案 0 :(得分:3)
尝试使用案例
SELECT
CASE WHEN a = 0 OR b = 0
THEN 0
ELSE a - b
END c
更多关于此
答案 1 :(得分:2)
使用CASE
语句绝对是最推荐的方式,但为了娱乐和愉悦,使用一些位移也可以使用
c = ABS(a - b)
* (((CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF))
/ POWER(2, 16) / POWER(2, 15))
采取的步骤
乘以得到零(a或b为零)或非零(a和b都为<> 0)值。非零值需要转换为1
ABS(a * b)
转换为BIGINT
以阻止Arithmetic overflow
CAST(ABS(a * b) AS BIGINT)
如果ABS(a * b)
为非零值,请确保将位32设置为1。
CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF
移位31位保留0或1. (因为POWER返回一个int,这必须分两步完成而不是更简单的POWER(2,31))
((CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF))
/ POWER(2, 16) / POWER(2, 15)
将原始等式乘以我们计算的0或1。
ABS(a - b)
* (((CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF))
/ POWER(2, 16) / POWER(2, 15))
测试脚本
;WITH q (a, b) AS (
SELECT * FROM (VALUES
(0, 0)
, (0, 1)
, (0, 2)
, (1, 0)
, (1, 1)
, (1, 2)
, (2, 0)
, (2, 1)
, (2, 2)
, (9, 0)
, (9, 1)
, (9, 2)
) a (b, c)
)
SELECT a
, b
, c = ABS(a - b)
* (((CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF))
/ POWER(2, 16) / POWER(2, 15))
FROM q
修改强>
在评论中我们想知道性能差异,以下是快速测试设置。
性能测试设置
CREATE TABLE q (a INTEGER, b INTEGER)
;WITH numbers (a) AS (
SELECT 0
UNION ALL
SELECT a + 1
FROM numbers
WHERE a < 999
)
INSERT INTO q
SELECT a1.a, a2.a
FROM numbers a1
CROSS APPLY numbers a2
OPTION (MAXRECURSION 0)
效果测试
SET STATISTICS IO ON
SET STATISTICS TIME ON
SELECT c = (a - b)
* (((CAST(ABS(a * b) AS BIGINT)+0x7FFFFFFF))
/ POWER(2, 16) / POWER(2, 15))
FROM q
SELECT
CASE WHEN a = 0 OR b = 0
THEN 0
ELSE a - b
END c
FROM q
答案 2 :(得分:0)
嗯,这应该这样做:)
SELECT
CASE WHEN A=0 OR B=0 THEN 0 ELSE A-B END AS C
FROM
TABLE
答案 3 :(得分:0)
试试他的:
SELECT
a,b,
CASE
WHEN a = 0 OR b = 0 THEN 0
ELSE
a - b
END AS c
FROM table
答案 4 :(得分:0)
SELECT a, b,
COALESCE(NULLIF(a, 0) - NULLIF(b, 0), 0) AS c
FROM T1;
或者
SELECT a, b, 0 AS c
FROM T1
WHERE 0 IN (a, b)
UNION
SELECT a, b, a - b AS c
FROM T1
WHERE 0 NOT IN (a, b);
注意每个句柄的空值不同(你的规范没有提到如何处理空值)。