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 @SSET @S=''SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @SSET @S=''SELECT DISTINCT @S=NAME FROM @TB
SELECT @S
/*(所影响的行数为 6 行)
--------------------------------------------------
jacksammicleJopJopNill(所影响的行数为 1 行)
--------------------------------------------------
sam(所影响的行数为 1 行)
--------------------------------------------------
sam(所影响的行数为 1 行)*/
DISTINCT为变量赋值的顺序是如何的呢?每次都会覆盖前面的值??
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 @SSET @S=''SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @SSET @S=''SELECT DISTINCT @S=NAME FROM @TB
SELECT @S
/*(所影响的行数为 6 行)
--------------------------------------------------
jacksammicleJopJopNill(所影响的行数为 1 行)
--------------------------------------------------
sam(所影响的行数为 1 行)
--------------------------------------------------
sam(所影响的行数为 1 行)*/
DISTINCT为变量赋值的顺序是如何的呢?每次都会覆盖前面的值??
解决方案 »
- bit型列插入了2
- 如何查找一个表的主键
- ERP会否处理调料问题?请大家给点意见!不调料在实际中又不行,有其它方法吗?
- (急!)关于datetime类型,如何获取最近三个月的数据
- 如何让Sql server 2005 远程连接到 sql Server 2008
- 请问在存储过程中怎么调用执行DTS包?
- 急!SQL2000 全文检索目录的增量填充不生效
- 选择什么数据库问题?(由于上一帜忘记给分,sorry!)
- 问一个关于VB中用ADO调用存储过程的问题!
- 急!怎么样把excel表格的数据转到SQL SERVER数据库中
- 求sql语句
- 多条记录合并为一条,同时将连续的编号写成“起始编号-结束编号”的形式
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 @SSET @S='a'SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @SSET @S='a'SELECT DISTINCT @S=NAME FROM @TB
SELECT @S/*
(6 行受影响)--------------------------------------------------
jacksammicleJopJopNill(1 行受影响)
--------------------------------------------------
asam(1 行受影响)
--------------------------------------------------
sam(1 行受影响)*/
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='a'SELECT @S=@S+NAME FROM @TB
SELECT @SSET @S='a'SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @SSET @S='a'SELECT DISTINCT @S=NAME FROM @TB
SELECT @S/*(6 行受影响)--------------------------------------------------
ajacksammicleJopJopNill(1 行受影响)
--------------------------------------------------
asam(1 行受影响)
--------------------------------------------------
sam(1 行受影响)
*/
SET @S='a'SELECT DISTINCT @S=@S+NAME FROM @TB
SELECT @SSET @S='a'SELECT DISTINCT @S=NAME FROM @TB
SELECT @S
就这两句的结果,第一句显然没累加,好像每次执行完后,@S又返回原值,最后才会得到那样的结果,
第二句很好理解,被覆盖了,
SELECT @S=@S+NAME FROM @TB
不需要排序,可以理解为循环读取表中的每一行,和@s进行加运算SELECT DISTINCT @S=@S+NAME FROM @TB
需要一个distinct排序,默认按照升序进行排序,那么取得是最后一个值,所以得到的结果是 sam,最后一个也是如此
排序以后指针已经指向了最后一行 而不加distinct的时候是从第一行读取到最后一行的同时在循环读取累加
SELECT DISTINCT @S=NAME FROM @TB
SELECT @S
这个好容易理解吧, 仅是因为列的输出取决于应用 DISTINCT 的列排序规则,记录里S的排在最后,所以@S里存的是最后一个列的输出也就是SAM
distinct
@s = t
from
(select @s+name as t from @tb) as b二次标量计算其实是这个过程,好,看到这儿,你再在第三个SQL的基础上来理解 一下这个SQL
我瞎想的
SELECT DISTINCT @S=''+NAME FROM @TB
SELECT @S
==>SELECT @S= ''+NAME FROM @TB order by name
SELECT @S
第二和第三个查询,由于使用了DISTINCT,另外使用了变量,所以相当于distinct top 1,这样就会取排序后的最后一条数据,所以取到了sam
不要被变量给蒙了呀,你可以把变量搞成常量或去了
@s+S
和
CASE WHEN S='D' THEN 'F'+S ELSE @s+S END
来进行排序的。
排序完成后进行@S=...的操作,这样@S最后得到的是排序结果的最后一条。
DECLARE @T TABLE (S VARCHAR(50))
INSERT INTO @T
SELECT 'A' UNION ALL
SELECT 'B' UNION ALL
SELECT 'C' UNION ALL
SELECT 'E' UNION ALL
SELECT 'D'
DECLARE @S VARCHAR(100)SELECT @S=''
SELECT DISTINCT @S= @s+S FROM @TSELECT @S
--E
SELECT @S=''
SELECT DISTINCT @S=CASE WHEN S='D' THEN 'F'+S ELSE @s+S END FROM @TSELECT @S
--FS
select
@s = t
from
(select @s+name as t from @tb) as b
先赋值@S+NAME,最后再赋值给@S的话,应该是不排序的最后一个呀?
SELECT @S=NAME FROM @TB
类似这种了
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
原来对变量进行排序都会有这个情况
比如
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
---------------
samdistinct有一个步骤就是对等号右边的值进行排序,而order by语句实际上就是如石头老大所说是先做一个套查询然后排序,而作嵌套查询的时候@s还是''
先计算,
再有个DISTINCT ORDER BY 排序,是按@S+NAME排的
再计算,
最后查询出结果!