操作数数据类型NULL对于max运算符无效

时间:2017-08-28 15:05:31

标签: sql sql-server tsql

此代码可以正常使用:

select fk, max(case when 1 = 0 then 1 else null end) maxx
    from (values(1, null), (1, null)) x(fk, a) 
    group by fk;

输出:

fk          maxx
----------- -----------
1           NULL

with:

Warning: Null value is eliminated by an aggregate or other SET operation.

但是这段代码:

select fk, max(a) maxx
    from (values(1, null), (1, null)) x(fk, a)
    group by fk;

给出错误:

Msg 8117, Level 16, State 1, Line 5 Operand data type NULL is invalid for max operator.

在这两种情况下,sql server从maxnull计算null?不是吗?

2 个答案:

答案 0 :(得分:9)

在第一种情况下,您隐式指定数据类型,即整数。这是从永远无法达到的allow_collections = CollectionBook.objects.filter(YOU_CONDITION) books_pks = allow_collections.values_list('book__pk', flat=true) Book.objects.filter(pk__in=books_pks) 推断出来的。 then将不会被执行的事实对于sql server无关紧要。 In fact,sql server确定返回类型的方式:“ result_expressions 中的类型集中的最高precedence类型和可选的else_result_expression ” 。因此,在实际执行之前,从thenthen中返回的所有潜在数据类型中选择返回类型。换句话说,在sql server'实现'之前,某些语句不可能达到。

由于数据类型已知,因此可以应用else

在第二种情况下,您没有指定数据类型,因此sql server无法知道如何实现maxmax的{​​{1}}与整数的max不同。

答案 1 :(得分:1)

这很整洁。在我看来,它可能隐式转换为int

文档为inserts提到了这一点:

  

多行insert语句中指定的值遵循union all语法的数据类型转换属性。    - Table Value Constructor (Transact-SQL)

这两项都将null值转换为int

select null as MyNullCol
into dbo.tmp
union all 
select null as MyNullCol

select fk, a
into dbo.tmp2
from (values(1, null), (1, null)) x(fk, a)

select c.name, t.name
from sys.columns c
  inner join sys.types t
    on c.user_type_id = t.user_type_id
where c.name in ('a','mynullcol')

rextester演示:http://rextester.com/VWMT9189

返回

+-----------+------+
|   name    | name |
+-----------+------+
| MyNullCol | int  |
| a         | int  |
+-----------+------+