2009-06-11 2 views
4

select by order by와 tsql string concat가 order by 절에서 함수와 함께 작동하지 않습니까?

create function dbo.wtfunc(@s varchar(50)) returns varchar(10) begin return left(@s, 2); end 
GO 
select t.* into #test from (
    select 'blah' as s union 
    select 'foo' union 
    select 'bar' 
) t 
select * from #test; 

declare @s varchar(100); 
set @s = ''; 

select @s = @s + s from #test order by s; 
select @s; 
set @s = ''; 
select @s = @s + s from #test order by dbo.wtfunc(s); 
select @s; 
/* 2005 only*/ 
select cast((select s+'' from #test order by dbo.wtfunc(s) for xml path('')) as varchar(100)) 

drop function dbo.wtfunc; 
drop table #test; 

내가 MSSQL 2000 년과 2005 년에 그것을 시도하고에 의해 순서대로 함수를 사용하는 경우 모두 문자열을 CONCAT하지 않는 다음 TSQL을 ... 고려하십시오. 2005 년 XML 경로 ('')가 작동합니다. 출력은 ...

bar 
blah 
foo 

barblahfoo 

foo --nothing concatenated? 

barblahfoo 

이 문서화 된 곳을 찾을 수 없습니다. 누군가가 왜 이것이 작동하지 않는지에 대해 밝힐 수 있습니까?

편집 :

실제 실행 계획은 다음과 같습니다. 분명히 정렬 및 계산 스칼라이 전혀 도움이 경우

alt text http://i41.tinypic.com/2d6pht3.jpg alt text http://i41.tinypic.com/w2og48.png

답변

4

이것은 known issue with Aggregate Concatenation Queries 인 것으로 보입니다. 링크에서

:.

"는 ANSI SQL-92 사양은 표현이 적용되면 ORDER BY 절에서 참조하는 모든 열이 SELECT 목록에 컬럼에 의해 정의 된 결과 집합을 일치해야합니다 ORDER BY 절의 멤버에게 결과 열이 SELECT 목록에 표시되지 않으므로 정의되지 않은 동작이 발생합니다. "

+0

아주 좋은 찾기! – dotjoe

2

은 몰라요 ... 같은 순서에없는,하지만 난이하려고하면

set @s = '   '; 

select @s = @s + s from #test order by dbo.wtfunc(s); 
select @s AS myTest 
을 이 몇 가지 모호한 가짜 진주 목걸입니다 같아요

foo 

:

나는이합니다 ('foo는'와 없음 후행 앞에 추가 공백이 주) 도착 전자 버그?!

+0

참, 내가 그것까지 무엇 몰라. 마지막 행만 사용하는 것 같습니다. "desc"로 변경하면 '막대'만 표시되기 때문입니다. – dotjoe

3

당신은 예를 들어, 계산 된 열을 사용하여이 작업을 수행 할 수 있습니다 :

DROP TABLE dbo.temp; 

CREATE TABLE dbo.temp 
(
    s varchar(20) 
,t AS REVERSE(s) 
); 
INSERT INTO dbo.temp (s) VALUES ('foo'); 
INSERT INTO dbo.temp (s) VALUES ('bar'); 
INSERT INTO dbo.temp (s) VALUES ('baz'); 
INSERT INTO dbo.temp (s) VALUES ('blah'); 
GO 

-- Using the function directly doesn't work: 
DECLARE @s varchar(2000); 
SELECT s, REVERSE(s) FROM dbo.temp ORDER BY REVERSE(s); 
SET @s = ''; 
SELECT @s = @s + s FROM dbo.temp ORDER BY REVERSE(s); 
SELECT @s; 
GO 

-- Hiding the function in a computed column works: 
DECLARE @s varchar(2000); 
SELECT s, t FROM dbo.temp ORDER BY t; 
SET @s = ''; 
SELECT @s = @s + s FROM dbo.temp ORDER BY t; 
SELECT @s; 
GO 
+0

은 계산 된 열을 완전히 잊었습니다. 흠, 지금 나는 나의 테이블에 1를 넣을 것인지에 관해 결정할 필요가있다. .. 큰 팁 그러나! – dotjoe