此代码可以正常使用:
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从max
和null
计算null
?不是吗?
答案 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 ” 。因此,在实际执行之前,从then
和then
中返回的所有潜在数据类型中选择返回类型。换句话说,在sql server'实现'之前,某些语句不可能达到。
由于数据类型已知,因此可以应用else
。
在第二种情况下,您没有指定数据类型,因此sql server无法知道如何实现max
。 max
的{{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 |
+-----------+------+