合并和案例陈述 - 解释?

时间:2013-12-03 09:50:11

标签: sql tsql sql-server-2008-r2

我正在处理一个查询,因为从一个SSRS服务器转移到另一个SSRS服务器,它似乎没有做它应该做的事情,并且where语句的一部分中出现以下行成为差异的地方,或者至少是我能找到的地方。

where COALESCE(field, -1) = CASE field WHEN 1 THEN 0 ELSE -1 END

我知道这可能有点通用,但任何人都可以对这可能做的事情有所了解吗?我已经阅读了coalesce并收集它从指定的字段列表中找到第一个非null值,但我不明白那里的'-1'是什么。

我希望这不是一般问题,有人可以给我一些关于它可能做什么的线索

3 个答案:

答案 0 :(得分:2)

如果没有上下文,很难给出真正有用的答案。 乍一看,它看起来好像可以更简单地重写:

WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END

到此:

WHERE COALESCE(@field, -1) = -1

如果这是真的那么基本上你是说如果字段为空或字段等于-1则条件为真,否则为假。

以下是一些试图证明这一点的测试:

-- Original
DECLARE @field INT
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END
SET @field = -1
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END
SET @field = 0
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END
SET @field = 1
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END
SET @field = 2
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END
SET @field = 3
SELECT 1 WHERE COALESCE(@field, -1) = CASE @field WHEN 1 THEN 0 ELSE -1 END

--Rewritten
DECLARE @field INT
SELECT 1 WHERE COALESCE(@field, -1) = -1
SET @field = -1
SELECT 1 WHERE COALESCE(@field, -1) = -1
SET @field = 0
SELECT 1 WHERE COALESCE(@field, -1) = -1
SET @field = 1
SELECT 1 WHERE COALESCE(@field, -1) = -1
SET @field = 2
SELECT 1 WHERE COALESCE(@field, -1) = -1
SET @field = 3
SELECT 1 WHERE COALESCE(@field, -1) = -1

此测试中的两组查询都给出了相同的结果,但正如我所说的,没有上下文和实际的测试数据,很难知道查询是否以原来的方式编写的原因。

以下是使用LEFT JOIN从不同角度看的另一个例子:

DECLARE @MainTable AS TABLE(ident INT)
DECLARE @PossibleNullTable AS TABLE(mainIdent INT, field INT)

INSERT INTO @MainTable(ident) VALUES(1)
INSERT INTO @MainTable(ident) VALUES(2)
INSERT INTO @MainTable(ident) VALUES(3)
INSERT INTO @MainTable(ident) VALUES(4)
INSERT INTO @MainTable(ident) VALUES(5)

INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(1,-1)
INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(1,1)
INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(1,0)

INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(2,0)
INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(3,1)
INSERT INTO @PossibleNullTable(mainIdent, field) VALUES(5,-1)

--Original
SELECT *
FROM @MainTable mt
LEFT JOIN @PossibleNullTable pnt
    ON mt.ident = pnt.mainIdent
WHERE COALESCE(field, -1) = CASE field WHEN 1 THEN 0 ELSE -1 END

--Original Result 
ident   mainIdent   field
1       1           -1
4       NULL        NULL
5       5           -1

--Rewritten
SELECT *
FROM @MainTable mt
LEFT JOIN @PossibleNullTable pnt
    ON mt.ident = pnt.mainIdent
WHERE COALESCE(field, -1) = -1

--Rewritten Result 
ident   mainIdent   field
1       1           -1
4       NULL        NULL
5       5           -1

此测试中的两个查询都会给出相同的结果。

答案 1 :(得分:1)

  

指定字段列表中的第一个非空值

这意味着括号之间的字段列表。例如:

COALESCE(col1,col2,col3,-1)

表示如果col1不为null,则使用此方法,否则请检查col2。如果col2为空,请检查col3。如果它也为null,则使用-1作为值。

在您的示例中,COALESCE(field, -1)相当于ISNULL(field, -1)

在我的示例中,COALESCE(col1,col2,col3,-1)相当于ISNULL(ISNULL(ISNULL(col1, col2), col3), -1)

答案 2 :(得分:1)

这是在where子句中使用的一个复杂的表达式,暗示

使用字段列replace NULL values with -1& compare字段列with the case expression的所有这些值,例如

首先,我们必须考虑no null value in field column replaced all null with -1 using coalesce().

然后在案例陈述中if the values is 1 then it is replace by 0。所以0 is checked with coalesce(field,-1)if it is also 0, then expression is true else false

类似于字段值-1使用大小写。