2012-05-13 4 views

답변

-2

당신은 T-SQL에서 "최소"기능을 사용할 수 있습니다 : 당신이 중첩 된 CASE 문을 피하려면

SELECT MIN(Value) FROM MyTable 
+1

그는 열을 가로 질러 묻습니다. 가장 훌륭하고 최후의 기능 –

+0

[어떤 데이터베이스에 대해? PostgreSQL, MySQL, Oracle에서 가장 큰 성과를 거두었습니다. SQL Server는 대단한/최강을 지원하지 않는 메이저 중 유일합니다] (http://stackoverflow.com/questions/3794451/greatest-and-least-in-sql-standard#comment4021993_3794451) –

2

, 이것은 할 것을 (비록 약간 어색한) :

CREATE TABLE #t(ID INT, V1 INT, V2 INT, V3 INT) 
INSERT INTO #t VALUES 
    (1, 10, 20, 30) 
    , (2, 60, 50, 40) 

SELECT * FROM #t t1 
CROSS APPLY (SELECT MAX(V), MIN(V) FROM (
SELECT V1 AS V 
UNION SELECT V2 
UNION SELECT V3 
) T) AS t2(VMAX, VMIN) 

DROP TABLE #t 
+3

'UNION ALL' 대신'UNION'을 사용합니다. UNION을 사용하면 SQL Server가 작업 테이블을 사용하게됩니다. –

1

그리고 명백한 중첩 된 case 문은 다음과 같습니다

select case when val1 < val2 then 
       case when val1 < val3 then val1 
       else val3 
       end 
     when val2 < val3 then val2 
       else val3 
    end 
from cols; 

create table cols (val1 int, val2 int, val3 int); 

더 높은 비교 수로는 쉽게 확장 할 수 없으며 널 (null)을 억제하는 병합 성 명령문이 없습니다.

유일한 장점은 다른 프로그래머가 코드를 볼 때 신속하게 알아낼 수 있다는 것입니다. (이 성능 병목하지 않는 한, 나는 그것이 꽤 좋은 배려라고 생각!)

+0

개인적으로 말하면, 내가 다른 프로그래머라면, 중첩 된 CASE 문을 "알아 내야"하는 대신 코드가하는 일을 알려주는 유용한 주석을 읽는 편이 낫다. 모르겠다.). – Pondlife

+0

@Pondlife 나는 종종 레거시 코드베이스를 사용한다. 내가 코멘트를 변경하지 않고 변경된 코드를 몇 번 발견했는지 말할 수 없습니다. 코드베이스가 오래 갈수록 코멘트를 신뢰하지 않습니다. 따라서, 더 적은 설명이 더 나은 것을 설명 할 수 있습니다. YMMV –

2

는 MySQL의에서 최소() 함수와 유사한 SQL 서버에는 기능이없는

의 MySQL의 최소() 함수가

두 개 이상의 인수를 가지고 다음, 가장 작은 (최소 값) 인수를 반환합니다. 인수는 다음 규칙을 사용하여 비교됩니다.

인수가 NULL이면 결과는 NULL입니다. 비교가 필요 없습니다.

반환 값이 INTEGER 문맥에서 사용되거나 모든 인수가 정수 값인 경우 정수로 비교됩니다.

REAL 문맥에서 반환 값이 사용되거나 모든 인수가 실수 값 이면 실제 값과 비교됩니다.

인수가 숫자와 문자열의 혼합으로 구성되는 경우 숫자로 비교하면 입니다.

인수가 이진수가 아닌 문자열 인 경우 이진수가 아닌 문자열 인 이 인수로 사용됩니다.

다른 모든 경우에 인수는 2 진 문자열과 비교됩니다.

SQL 서버의 최소() 함수는 여기

은 시뮬레이션하지만 그것은 단지 걸릴 수 있기 때문에 여전히 최소 좋아하지 인수를 고려하지 않습니다 테이블 의 열 중 가장 작은 값을 반환 정수에

여기
CREATE FUNCTION [dbo].[GetSmallest] 
(
    -- Add the parameters for the function here 
    @val1 int, @val2 int, @val3 int 
) 
RETURNS int 
AS 
BEGIN 
Declare @result int 
set @result = case when @val1 < @val2 then 
       case when @val1 < @val3 then 
       @val1 
       else 
       @val3 
       end 
     when @val2 < @val3 then 
       @val2 
     else 
       @val3 
    end 
    return @result 
END 

SELECT [dbo].[GetSmallest] ( 32 ,31 ,6) 
3

당신은이 작업을 수행 할 수 있습니다를 호출하는 방법입니다 중첩 된 사례가없는 경우 :

select (case when val1 < val2 and val1 < val3 then val1 
      when val2 < val3 then val2 
      else val3 
     end) as least_of_three 

이것은 무엇을하고있는 것처럼 꽤 명확하게 보입니다. 그것은 또한 꽤 쉽게 일반화됩니다.

NULL에주의하십시오. LEAST와 GREATEST는 무시합니다. 당신이이 처리해야하는 경우, 그것은 좀 더 복잡 :

select (case when val1 <= coalesce(val2, val1) and val1 <= coalesce(val3, val1) then val1 
      when val2 <= coalesce(val3, val2) then val2 
      else val3 
     end) as least_of_three 

공지 사항 나는 "<"을 "< ="변경했습니다. 나는 유착을 사용하여 사실을 평가함으로써 가치를 "무시"합니다. 따라서 val2가 null이면 val1은 항상 val2보다 작습니다. 모든 데이터 유형 (문자열, 숫자, 날짜)에서 작동하기 때문에이 방법을 선택했습니다.