我正在使用SQL Server 2012并且我认为内联视图是一个非常奇怪的问题。
首先,我有这个问题:
select
parcelnumber,
sectionname,
value.Value CalculatedValue,
overriddenvalue.Value OverriddenValue,
homk.Value CalculatedHomeownersValue,
cv.CharacteristicValue,
pdt.PropertyDataTypeID
from landsections ls
join lands l
on ls.landid = ls.landid
join parcels p
on l.ParcelID = p.ParcelID
join CharacteristicValueGroups cvg
on cvg.ParcelObjectID = ls.ParcelObjectID
join CharacteristicValues cv
on cvg.CharacteristicValueGroupID = cv.CharacteristicValueGroupID
join Characteristics c
on cv.CharacteristicID = c.CharacteristicID
join CharacteristicDetails cd
on c.CharacteristicDetailsID = cd.CharacteristicDetailsID
and cd.name = '09 Composite Adjustment'
join PropertyDataTypes pdt
on cv.PropertyDataTypeID = pdt.PropertyDataTypeID
and pdt.Label = 'Type'
join parcelobjectvalues value
on value.ParcelObjectID = ls.ParcelObjectID
and value.valuetype = 'CalculatedAdjustedValue'
left join parcelobjectvalues overriddenvalue
on overriddenvalue.ParcelObjectID = ls.ParcelObjectID
and overriddenvalue.valuetype = 'OverriddenValue'
join parcelobjectvalues homk
on homk.ParcelObjectID = ls.ParcelObjectID
and homk.valuetype = 'CalculatedHomeownersValue'
where year(appraisaldate) = 2016
and CharacteristicValue like '%F%'
注意where子句中的最后一项。此查询返回0结果,这应该证明没有包含F的CharacteristicValue
列的行。
现在让我们运行此查询:
select *
from
(
select
*,
case
when CharacteristicValue like '%A' then convert(int, substring(characteristicvalue, 1, len(characteristicvalue) - 1))
when CharacteristicValue like '%K' then convert(int, substring(characteristicvalue, 1, len(characteristicvalue) - 1))
when isnumeric(CharacteristicValue) = 1 then convert(int, characteristicvalue)
else 0
end Quantity
from
(
select
parcelnumber,
sectionname,
value.Value CalculatedValue,
overriddenvalue.Value OverriddenValue,
homk.Value CalculatedHomeownersValue,
cv.CharacteristicValue,
pdt.PropertyDataTypeID
from
landsections ls
join lands l on ls.landid = ls.landid
join parcels p on l.ParcelID = p.ParcelID
join CharacteristicValueGroups cvg on cvg.ParcelObjectID = ls.ParcelObjectID
join CharacteristicValues cv on cvg.CharacteristicValueGroupID = cv.CharacteristicValueGroupID
join Characteristics c on cv.CharacteristicID = c.CharacteristicID
join CharacteristicDetails cd on c.CharacteristicDetailsID = cd.CharacteristicDetailsID and cd.name = '09 Composite Adjustment'
join PropertyDataTypes pdt on cv.PropertyDataTypeID = pdt.PropertyDataTypeID and pdt.Label = 'Type'
join parcelobjectvalues value on value.ParcelObjectID = ls.ParcelObjectID and value.valuetype = 'CalculatedAdjustedValue'
left join parcelobjectvalues overriddenvalue on overriddenvalue.ParcelObjectID = ls.ParcelObjectID and overriddenvalue.valuetype = 'OverriddenValue'
join parcelobjectvalues homk on homk.ParcelObjectID = ls.ParcelObjectID and homk.valuetype = 'CalculatedHomeownersValue'
where
year(appraisaldate) = 2016
) Tbl
) Tbl2
where
CharacteristicValue like '%A' and Quantity > 10
请注意,我已删除%F%支票。由于第一个查询证明在CharacteristicValue
列中没有带有F的行,我认为外部查询可以依赖于此。
然而,我明白了:
转换varchar值时转换失败' F'数据类型int。
我认为这可能发生的唯一方法是忽略pdt.Label = 'Type'
,但对于我的生活,我无法理解为什么。
答案 0 :(得分:2)
您的视图会过滤:
where year(appraisaldate) = 2016 and CharacteristicValue like '%F%'
这意味着可以存在仅满足CharacteristicValue like '%F%'
的行。
在T-SQL中未指定执行顺序。当试图保护可能会进行一些检查的计算时,这是一个问题。
通常,case ... when
是一个可靠的守卫。在我看来,我认为没有理由不这样做。所以你可以做when CharacteristicValue like '%A' and CharacteristicValue not like '%F%'
。
或者,您可以使用始终安全的TRY_CONVERT
。
where
不是可靠的后卫。在另一个答案中,你发布了这个有效,但这只是巧合。使用不同的查询计划,这可能会失败。计划的变化有很多原因。
答案 1 :(得分:-1)
答案似乎是由于相关性而无法在外部查询之前执行内部查询。在外部查询中添加过滤器解决了这个问题。