2013-11-27 2 views
0

내가 thusly 히 내가 다른 테이블에 다시 가입 할 수 있습니다 중간 값의 테이블을 반환하는 저장 SQL 서버 기능, 만들려고 노력 해요 :열 별칭 오류

CREATE FUNCTION [dbo].getmedian (@varPartionBy1 int,@varPartionBy2 int, @varForTieBreak int, @varForMeasure int) 
    RETURNS TABLE 
    AS 
    RETURN 
    (
     SELECT 
      @varPartionBy1, 
      @varPartionBy2, 
      AVG(@varForMeasure) 
     FROM 
     (
      SELECT 
       @varPartionBy1, 
       @varPartionBy2, 
       ROW_NUMBER() OVER (
       PARTITION BY @varPartionBy1, @varPartionBy2 
       ORDER BY @varForMeasure ASC, @varForTieBreak ASC) AS RowAsc, 
       ROW_NUMBER() OVER (
       PARTITION BY @varPartionBy1, @varPartionBy2 
       ORDER BY @varForMeasure ASC, @varForTieBreak DESC) AS RowDesc 
      from 
      [fakename].[dbo].[temptable] bp 

     ) bp 
     WHERE 
      RowAsc IN (RowDesc, RowDesc - 1, RowDesc + 1) 
     GROUP BY @varPartionBy1, @varPartionBy2 

    ) 

을 이동

이것은 다음과 같은 오류를 반환합니다. "메시지 8155, 수준 16, 상태 2, 프로 시저 getmedian'bp'의 열 1에 대해 열 이름이 지정되지 않았습니다." - UDF의 컨텍스트에서 열에 대한 테이블 별칭을 지정하는 방법을 이해할 수 없다는 것을 나타냅니다.

오류를 해결하려면 어떻게해야합니까?

이것은 내 첫 USF이므로 주 질문에 대답하는 동안 다른 유용한 디자인 통찰력에 감사드립니다. 어떤 도움을 주셔서 감사합니다!

+1

내부 선택에서 변수의 별칭 인'@ varPartionBy1 as varPartionBy1'을 제공 한 다음 외부 선택 호출에서 변수 대신 새 별칭 이름을 제공하십시오. – Taryn

+0

유혹에 빠져있는 샘플 데이터의 일부를 보여주는 질문을 작성한 다음 주어진 매개 변수 값에서 기대하는 결과를 보여줄 것을 제안합니다. 여기서는 코드에서 실제로 이것이 무엇을하는지 추측 할 수 없습니다. –

답변

2

여기에 SELECT @varPartionBy1, @varPartionBy2이있는 경우 열 이름이 지정되어 있어야합니다. 올바른 기능을 가능성이 잘

CREATE FUNCTION [dbo].getmedian (@varPartionBy1 int,@varPartionBy2 int, @varForTieBreak int, @varForMeasure int) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT 
     varPartionBy1, 
     varPartionBy2, 
     AVG(@varForMeasure) AS AvgVarForMeasure 
    FROM 
    (
     SELECT 
      @varPartionBy1 AS varPartionBy1, 
      @varPartionBy2 As varPartionBy1, 
      ROW_NUMBER() OVER (
      PARTITION BY @varPartionBy1, @varPartionBy2 
      ORDER BY @varForMeasure ASC, @varForTieBreak ASC) AS RowAsc, 
      ROW_NUMBER() OVER (
      PARTITION BY @varPartionBy1, @varPartionBy2 
      ORDER BY @varForMeasure ASC, @varForTieBreak DESC) AS RowDesc 
     from 
     [fakename].[dbo].[temptable] bp 

    ) bp 
    WHERE 
     RowAsc IN (RowDesc, RowDesc - 1, RowDesc + 1) 
    GROUP BY varPartionBy1, varPartionBy2 

) 
+0

감사합니다. 아론 베르트랑 (Aaron Bertrand)의 의견에 따르면이 결의안이 모든 문제를 해결하지는 못 하겠지만 적어도이 질문에 대한 답을 배웠습니다. – ouonomos

1

것이다 직접적 SELECT @varPartionBy1 AS varPartionBy1 또는 SELECT varPartionBy1 = @varPartionBy1 또는 테이블 별칭 ) bp(varPartionBy1, varPartionBy2,...

에 지정할 수 있습니다 당신이 길에서 구문 문제를 일단 당신도 그들에게 할당 할 수 있습니다 , 당신의 문제는 끝나지 않을 것입니다. 하나는 당신이하려는 일을 실제로 할 수 없다는 것입니다 (변수를 PARTITION BYORDER BY 절로 전달). 그것들은 그냥 상수로 취급되므로 ROW_NUMBER()이 임의로 적용됩니다.

여기에 무슨 관찰 :

DECLARE @foo SYSNAME = N'name'; 

SELECT name, foo = @foo, -- this is just a constant value, not a column 
    varASC = ROW_NUMBER() OVER (ORDER BY @foo ASC), 
    varDESC = ROW_NUMBER() OVER (ORDER BY @foo DESC), 
    colASC = ROW_NUMBER() OVER (ORDER BY name ASC), 
    colDESC = ROW_NUMBER() OVER (ORDER BY name DESC) 
FROM sys.objects --WHERE is_ms_shipped = 0 
ORDER BY varASC; 

부분 결과 :

name foo varASC varDESC colASC colDESC 
---- ---- ------ ------- ------ ------- 
t1 name  1  1  1  100 
t2 name  2  2  2  99 
t3 name  3  3  3  98 
t4 name  4  4  4  97 
t5 name  5  5  5  96 
------ only column that deviates ----^^^^^^^ 

@foo의 변수 값이 모든 단일 행에서 동일하므로, 그에 의해 분할 및 순서는 완전히 무의미한.

+0

동적 SQL을 사용 하시겠습니까? –

+0

함수에서 @CRAFTYDBA? 나는 그렇게 생각하지 않는다. –

+0

내 잘못, 나는 이것이 SP라고 생각했다. 그러나 동적 SQL이있는 SP가 해결책 일 수 있습니다. 판단 전화를하기에 충분한 비즈니스 요구 사항이 아닙니다. –