2010-07-07 2 views
4

정수를 리턴하는 사용자 정의 함수 (예 : myUDF(a,b))가 있습니다. 나는이 기능을 보장하기 위해 노력하고UDF의 결과 인 열의 where 절

는 한 번만 호출되며, 그 결과는 WHERE 절에 조건으로 사용할 수 있습니다

SELECT col1, col2, col3, 
     myUDF(col1,col2) AS X 
From myTable 
WHERE x>0 

SQL 서버가 열로 x를 감지하려고 시도하지만 정말입니다 계산 된 값의 별칭입니다.

UDF를 두 번 이상 실행하지 않고 계산 된 값에서 필터링을 수행 할 수 있도록이 쿼리를 다시 작성할 수 있습니까?

답변

5

을, 당신은 십자가 적용을 사용할 수 있습니다

Select T.col1, T.col2, FuncResult.X 
From Table As T 
    Cross Apply (Select myUdf(T.col1, T.col2) As X) As FuncResult 
Where FuncResult.X > 0 
+0

정확히 교차 적용이란 무엇입니까? – Gzim

+0

@Gzim - 교차 적용은 파생 테이블과 상관 된 부속 조회 간의 혼합으로 생각하십시오. 결과적으로 쿼리 외부의 항목을 참조하는 하위 쿼리에 조인 할 수 있습니다. 필자의 예에서는 From 절에있는 다른 테이블의 col1과 col2를 참조합니다. 주제에 대한 또 다른 기사가 있습니다. http://www.sqlteam.com/article/using-cross-apply-in-sql-server-2005 – Thomas

+0

오, 이런, 너무 강력합니다. 특히 테이블에서 (동시에) 삽입 W 선택하는 경우와 선택된 테이블의 매개 변수를 승인하는 테이블 UDF에서 복잡한 케이스가있는 경우. 고맙습니다 토마스. – Gzim

4

시도

SELECT col1, col2, col3, dbo.myUDF(col1,col2) AS X 
From myTable 
WHERE dbo.myUDF(col1,col2) >0 

하지만 여기 SARGable

하지

select * from(
SELECT col1, col2, col3, dbo.myUDF(col1,col2) AS X 
From myTable) as y 
WHERE x>0 
+0

네,하지만이 함수는 시간이 많이 걸리고 두 번 사용하는 것을 피하려고합니다. – Gzim

+0

첫 번째 경우는 실제로 한 번만 실행해야하며 두 번째 경우는 공통 테이블 식 (또는 Baaju의 답) 만 사용해야합니다. 한번만 계산하십시오 – Rup

+0

함수를 두 번 입력했기 때문에 두 번 호출된다는 의미는 아닙니다. SQL Server는 두 위치 모두에서 동일한 기능을 인식하고 한 번만 평가합니다. – Gabe

2

SQL 서버는 열을 참조 할 수 없습니다 또 다른 방법이기 때문에이 검사의 원인이되므로주의 별칭으로.

SELECT col1, col2, col3, myUDF(col1,col2) AS X 
From table myTable 
WHERE myUDF(col1,col2) > 0 

또는 하위 쿼리 사용 : 당신은 두 번 열을 작성해야 하나 당신이 넘어 SQL 서버 2005를 사용하는 경우

SELECT * 
FROM (
     SELECT col1, col2, col3, myUDF(col1,col2) AS X 
     From table myTable 
     ) as subq 
WHERE x > 0 
0

나는 당신이하고있는 일을 100 % 확신하지는 않지만 x는 열이 아니므로 SQL 문에서 제거 할 것이므로

SELECT col1, col2, col3, myUDF(col1,col2) AS X From myTable 

그리고 당신은 단지 x > 0

7
With Tbl AS 
(SELECT col1, col2, col3, myUDF(col1,col2) AS X 
     From table myTable ) 

SELECT * FROM Tbl WHERE X > 0 
+1

SQL Server 2005+에 대한 탁월한 해답! –

1

가 UDF에 따라 얼마나 유용하거나 자주 당신은 computed column로 테이블에 추가 고려할 수있다 사용될 때 호출 그래서 다음 코드에 조건을 추가 . 그런 다음 정상적으로 열을 필터링하고 쿼리에서 함수를 전혀 쓸 필요가 없습니다.

0

귀하의 질문에 "With"조항 (CTE, MSSS)이 가장 잘 답변됩니다.

정말로 가장 좋은 질문은 다음과 같습니다.이 계산 된 값을 저장하거나 테이블을 쿼리 할 때마다 모든 행에 대해 다시 계산해야합니까?

테이블에 10 개의 행이 있고 항상 10 개의 행이 있습니까?

행을 지속적으로 추가합니까?

퍼지 전략을 사용하고 있습니까?

한 달에 한 번만 해당 테이블을 쿼리합니까?

"장기 실행"기능 (최적화 된 경우 라하더라도)을 한 번 이상 실행하려는 이유는 무엇입니까?

한 번 물어 보았지만 쿼리 당 한 행당 한 번만 요청했습니다.

인덱스 또는 "가상 열"

프로에 대답을 저장 : 정확히 한 번만 행 당

계산. 쿼리 시간이 선형 적으로 증가하지 않습니다.

단점 :

삽입/업데이트 시간 최적화

단점 : 증가/업데이트 시간마다

프로를 계산

를 삽입 쿼리 시간이 행 수와 함께 증가한다.

한 달에 한 번 쿼리하면 왜 성능이 얼마나 나쁜지 신경 쓰지 만 작업에 실제로 큰 영향을 미칠 수있는 부분을 조정하십시오 (약간은 우스꽝 스럽습니다).

초당 행 수 (하드웨어에 따라 다름)를 삽입하지 않으면 시간을 앞당겨서 큰 차이를 만들 것입니까?