今天遇到了个有关DISTINCT的执行疑问!!!!

SQL77 2009-10-11 06:56:46
DECLARE @TB TABLE (id INT,name NVARCHAR(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


declare @s varchar(50)
set @s=''

SELECT @S=@S+NAME FROM @TB
SELECT @S

SET @S=''

SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @S

SET @S=''

SELECT DISTINCT @S=NAME FROM @TB
SELECT @S


/*

(所影响的行数为 6 行)


--------------------------------------------------
jacksammicleJopJopNill

(所影响的行数为 1 行)


--------------------------------------------------
sam

(所影响的行数为 1 行)


--------------------------------------------------
sam

(所影响的行数为 1 行)

*/

DISTINCT为变量赋值的顺序是如何的呢?每次都会覆盖前面的值??
...全文
724 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
SQL77 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 55 楼 victarary 的回复:]
楼主我明白了
原来对变量进行排序都会有这个情况
比如
DECLARE @TB TABLE (id INT,name NVARCHAR(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


declare @s varchar(50)
set @s=''

SELECT  @S=@S+NAME  FROM @TB order by @s+name
select @s
---------------
sam

distinct有一个步骤就是对等号右边的值进行排序,而order by语句实际上就是如石头老大所说是先做一个套查询然后排序,而作嵌套查询的时候@s还是''
[/Quote]
呵呵,理解了,这个看执行计划,
先计算,
再有个DISTINCT ORDER BY 排序,是按@S+NAME排的
再计算,
最后查询出结果!
SQL77 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 happyflystone 的回复:]
或是这样,因为@s最初始''

就是这样,
SELECT  DISTINCT @S=''+NAME  FROM @TB
SELECT @S


==>

SELECT @S= ''+NAME  FROM @TB  order by name
SELECT @S
[/Quote]
石头大哥,这个我看懂了,就是DISTINCT后会排序,这个我理解了,呵呵,
SQL77 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 xiequan2 的回复:]
引用 48 楼 sql77 的回复:
引用 33 楼 happyflystone 的回复:
引用 31 楼 sql77 的回复:
引用 28 楼 happyflystone 的回复:
呵呵,distinct排序与取最后一个值这个行为无关

石头哥可否再赐教一下第一个标量的计算过程?


就是那个子查询呀

石头大哥,越想越闷了,那么
select

    @s = t
from
    (select @s+name as t from @tb) as  b
先赋值@S+NAME,最后再赋值给@S的话,应该是不排序的最后一个呀?
SELECT @S=NAME FROM @TB
类似这种了
SQL codeDECLARE@TBTABLE (idINT,nameNVARCHAR(10))INSERT@TBSELECT1 ,'jack'UNIONALLSELECT2 ,'sam'UNIONALLSELECT6 ,'micle'UNIONALLSELECT7 ,'Jop'UNIONALLSELECT7 ,'Jop'UNIONALLSELECT12,'Nill'declare@svarchar(50)set@s=''SELECTDISTINCT@S=@S+NAMEFROM@TBSELECT@S


重点看这个sql的执行情况,其它两个很好理解;此sql的实际执行文本为(set SHOWPLAN_TEXTon)------------------------------------------------------------------------------------------------|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(varchar(50),[Expr1004],0)))|--Sort(DISTINCT ORDER BY:([Expr1004] ASC))|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(nvarchar(50),[@s],0)+[name]))|--Table Scan(OBJECT:(@TB))

这个执行顺序是select@s+namefrom@tb(这里的@s='',这里没有赋值,而且@s并没有保存name的值,只是做了一个"+"运算,执行完的结果其它就是原表@tb的结果,下两步就是排序和循环赋值)----->排序--->再把最后一个值赋值给@s
[/Quote]
这个执行计划,石头哥也解释了,并且以查询语句体现了,很好理解,谢谢
victarary 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 sql77 的回复:]
引用 33 楼 happyflystone 的回复:
引用 31 楼 sql77 的回复:
引用 28 楼 happyflystone 的回复:
呵呵,distinct排序与取最后一个值这个行为无关

石头哥可否再赐教一下第一个标量的计算过程?


就是那个子查询呀

石头大哥,越想越闷了,那么
select
   
    @s = t
from
    (select @s+name as t from @tb) as  b
先赋值@S+NAME,最后再赋值给@S的话,应该是不排序的最后一个呀?
SELECT @S=NAME FROM @TB
类似这种了
[/Quote]
是因为distinct是select后再排序,所以最后出来的还是最后一个
xiequan2 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 sql77 的回复:]
引用 33 楼 happyflystone 的回复:
引用 31 楼 sql77 的回复:
引用 28 楼 happyflystone 的回复:
呵呵,distinct排序与取最后一个值这个行为无关

石头哥可否再赐教一下第一个标量的计算过程?


就是那个子查询呀

石头大哥,越想越闷了,那么
select

    @s = t
from
    (select @s+name as t from @tb) as  b
先赋值@S+NAME,最后再赋值给@S的话,应该是不排序的最后一个呀?
SELECT @S=NAME FROM @TB
类似这种了
[/Quote]
DECLARE @TB TABLE (id INT,name NVARCHAR(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


declare @s varchar(50)
set @s=''


SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @S


重点看这个sql的执行情况,其它两个很好理解;此sql的实际执行文本为(set SHOWPLAN_TEXT on)
------------------------------------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(varchar(50),[Expr1004],0)))
|--Sort(DISTINCT ORDER BY:([Expr1004] ASC))
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(nvarchar(50),[@s],0)+[name]))
|--Table Scan(OBJECT:(@TB))


这个执行顺序是

select @s+name from @tb(这里的@s='',这里没有赋值,而且@s并没有保存name的值,只是做了一个"+"运算,执行完的结果其它就是原表@tb的结果,下两步就是排序和循环赋值)----->排序--->再把最后一个值赋值给@s
SQL77 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 happyflystone 的回复:]
引用 31 楼 sql77 的回复:
引用 28 楼 happyflystone 的回复:
呵呵,distinct排序与取最后一个值这个行为无关

石头哥可否再赐教一下第一个标量的计算过程?


就是那个子查询呀
[/Quote]
石头大哥,越想越闷了,那么
select

@s = t
from
(select @s+name as t from @tb) as b
先赋值@S+NAME,最后再赋值给@S的话,应该是不排序的最后一个呀?
SELECT @S=NAME FROM @TB
类似这种了
xuejie09242 2009-10-12
  • 打赏
  • 举报
回复
看看,接分.
liangCK 2009-10-12
  • 打赏
  • 举报
回复
强力学习.
SQL77 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 guguda2008 的回复:]
77整理一下放博客里吧
[/Quote]
呵呵,没写过博客呢
华夏小卒 2009-10-12
  • 打赏
  • 举报
回复
什么情况?
SQL77 2009-10-12
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 dawugui 的回复:]
看看,接分.
[/Quote]
乌龟大侠也不发表言论,
SQL77 2009-10-12
  • 打赏
  • 举报
回复
,呵呵,大家早,
victarary 2009-10-12
  • 打赏
  • 举报
回复
楼主我明白了
原来对变量进行排序都会有这个情况
比如
DECLARE @TB TABLE (id INT,name NVARCHAR(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


declare @s varchar(50)
set @s=''

SELECT @S=@S+NAME FROM @TB order by @s+name
select @s
---------------
sam

distinct有一个步骤就是对等号右边的值进行排序,而order by语句实际上就是如石头老大所说是先做一个套查询然后排序,而作嵌套查询的时候@s还是''
lgq_liang 2009-10-12
  • 打赏
  • 举报
回复
一个DISTINCT 引发的争议
xuejie09242 2009-10-12
  • 打赏
  • 举报
回复
是排序的问题吗?
victarary 2009-10-11
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 happyflystone 的回复:]
第二句,我先写一个SQL

select
    distinct
    @s = t
from
    (select @s+name as t from @tb) as  b

二次标量计算其实是这个过程,

好,看到这儿,你再在第三个SQL的基础上来理解 一下这个SQL


我瞎想的
[/Quote]
额..sqlserver的语法解析真是高深难测....不知道为什么加了distinct会让select语法编译出现如此大的变化?
哈哈V大侠 2009-10-11
  • 打赏
  • 举报
回复
学习
dawugui 2009-10-11
  • 打赏
  • 举报
回复
看看,接分.
linguojin11 2009-10-11
  • 打赏
  • 举报
回复
学习了。。谢谢
guguda2008 2009-10-11
  • 打赏
  • 举报
回复
77整理一下放博客里吧
加载更多回复(35)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧