读书人

MS SQL 分组求最大值的疑点

发布时间: 2013-04-12 18:33:12 作者: rapoo

MS SQL 分组求最大值的疑问
最近在做项目时,遇到一个很奇怪的问题,求高手解释

【开发环境】
SQL Server 2008

【问题描述】
有2张表,结构和测试数据如下:

表tb1 表tb2
[Name] [varchar](10) NULL, [ITEM_ID] [int] NULL,
[ITEM_ID] [int] NULL, [TYPES] [int] NULL
[Score] [nvarchar](50) NULL

表tb1 表tb2
Name ITEM_ID Score ITEM_ID TYPES
张三 1 74 1 0
张三 1 83 2 1
张三 1 93
李四 1 84
李四 1 184
李四 2 OK

【查询情况】
我写了2个sql语句,一个根据ITEM_ID分组,查出最大的Score;一个根据Name分组,查出最大的Score
1、select tb1.ITEM_ID,max(cast(tb1.Score as int))
from tb1
inner join tb2 on tb1.ITEM_ID=tb2.ITEM_ID
where tb2.[TYPES]=0
group by tb1.ITEM_ID
语句执行正常,是我期望的结果

2、select tb1.Name,max(cast(tb1.Score as int))
from tb1
inner join tb2 on tb1.ITEM_ID=tb2.ITEM_ID
where tb2.[TYPES]=0
group by tb1.Name
语句执行失败,报错“在将 nvarchar 值 'OK' 转换成数据类型 int 时失败”

【疑问】
1、sql的执行顺序应该是先走where,用where之后的结果,再进行group by吧?!(我看执行计划也是这样的呀)


测试数据‘OK’的[TYPES]=1,我明明在where中用tb2.[TYPES]=0把它过滤掉了,为什么还会出现‘OK’呢?
2、为什么在第一个sql语句中,‘OK’被过滤掉了呢?
3、以上的测试数据是我随便模拟的,只是反映了问题的现象,不一定完美,希望高手能指出这2条语句的主要区别,以及sql内部到底是如何处理这2条语句的? SQL?Server?2008
[解决办法]

引用:
引用:引用:
理论上的顺序是你说的那样

但是实际执行顺序不一定是这样的。

出现这样的提示,应该是先对表 tb2 进行扫描 然后标量计算 在排序
同时并行的动作是对tb1进行扫描、排序
然后做合并连接

查询1也有可能出现这种错误提示的

那有没有什么方法可以避免呢?
1、测试表和测试……

要避免的话在where 条件里面加上 AND ISNUMERIC([Score])=1

这样会过漏掉一部分数据

读书人网 >SQL Server

热点推荐