SQL Server가 일반적인 해결 방법이 아닌 경우 GREATEST 및 LEAST를 지원합니까?


20

이 질문을 검토 하면 필요하지 않은 많은 작업이있는 것 같습니다. 그들은 날짜로 범위를 확장하려고합니다. 다른 데이터베이스에서는 greatestand least..

least(extendDate,min), greatest(extendDate,max)

그래도 이것을 사용하려고하면

'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.

그것은 어느 방향 으로든 확장을 커버 할 것입니다.

질문의 목적 상 여전히 독점 범위 교체를 수행해야합니다.

SQL Server 사용자가 쿼리 패턴을 구현 least하여 greatest기능 과 기능 을 어떻게 구현하는지 궁금합니다 .

조건을 CASE설명 으로 풀거나이 기능을 사용하는 Microsoft의 확장, 타사 애드온 또는 라이센스가 있습니까?


답변:


33

한 가지 일반적인 방법은 VALUES절 을 사용하고 CROSS APPLY두 개의 열을 단일 열로 별칭을 지정한 다음 MINMAX각각 을 가져 오는 것 입니다.

SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM   dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );

작성하는 다른 방법이 있습니다 (예 : UNION ALL

SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM   dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);

그러나 결과 쿼리 계획 은 동일한 것 같습니다.


14

하위 쿼리에 값을 인라인으로 넣을 수도 있습니다. 이처럼 :

select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
       (select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least

3

이것은 좋은 시작이 될 것입니다-

CASE WHEN A > B THEN A ELSE B END

좋은 제안이지만 "조건을 CASE 문에 풀기"라는 질문에 언급되었습니다
Evan Carroll

3

마지막 등가 :

IIF(@a < @b, @a, @b)

가장 큰 동등한 것 :

IIF(@a > @b, @a, @b)

3
예를 들어 세 개 이상의 값에 대해 어떻게합니까 least(5,6,7,8,9)?
a_horse_with_no_name

@a_horse_with_no_name 중첩 된 IIF 사용
Elnur

이 접근 방식은 빠르게 읽고 확인하기가 어려워 질 것입니다 ... 성능 측면에서 어떤 이점이 있습니까?
Dodecaphone

0

예를 들어 사용자 정의 함수를 만듭니다.

create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
  return case when @a <= @b then @a 
              when @b < @a  then @b
              else null
         end
end

간단한 경우에는 작동하지만이 방법에는 몇 가지 문제가 있습니다.

  • 귀찮게 각 데이터 유형마다 별도의 기능을 만들어야합니다.
  • 2 개의 매개 변수 만 처리하므로 많은 매개 변수를 처리하거나 동일한 함수의 중첩 된 호출을 사용하려면 더 많은 함수가 필요할 수 있습니다.
  • 스칼라 함수보다는 인라인 TVF로 더 효율적일 것입니다. 그것은 스칼라 함수의 구현과 관련이 있습니다. 이에 대한 많은 블로그가 있습니다 (예 : SQL 101 : 병렬 처리 금지 – 스칼라 사용자 정의 함수 (John Kehayias) 참조) .
  • 인수 중 하나가 널이면 널을 리턴합니다. 이는 least운영자가 Oracle 및 MySQL에서 수행 하는 작업과 일치 하지만 Postgres와 다릅니다. 그러나 null에 대한이 갑옷은 더 장황하게 만듭니다 (널이 아닌 것을 알면 평원 case when @a <= @b then @a else @b end이 작동합니다).

대체로 case성능이 중요하다면 성명서 를 작성하는 것이 좋습니다 . case비교할 여러 값이있을 때 클라이언트 측에서 중첩 문 을 생성하는 데 의존했습니다 .


0

@ ed-avis 답변에 의견을 추가하려고했지만 평판이 부족하여 그렇게 할 수 없으므로이 답변을 확장으로 게시하십시오.

"불쾌하게도 각 데이터 유형마다 별도의 기능을 만들어야합니다."라는 단점을 제거했습니다. 사용 SQL_VARIANT을 .

내 구현은 다음과 같습니다.

CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
  return case when @a <= @b then @a 
              when @b < @a  then @b
              WHEN @a IS NULL THEN @b
              WHEN @b IS NULL THEN @a
              else null
         end
END;

또한이 함수는 NULL을 처리 합니다. postgresql 버전과 같은 .

이 기능은 편의를 위해 DB에 추가 할 수 있지만 내장 기능을 사용하는 것보다 10 배 느립니다IIF . 내 테스트에 따르면 정확한 유형 ( datetime )의 함수 는 sql_variant 버전 과 동일하게 수행됩니다 .

추신 : 350k 값의 데이터 세트에서 일부 테스트를 실행했는데 성능이 같고 sql_variant 가 조금 더 빠르지 만 지터에 불과하다고 생각합니다.

그러나 IIF 버전은 10x입니다. 배 빠릅니다 !!!

나는 인라인 CASE WHEN으로 테스트하지 않았지만 기본적으로 t-sql에 대해 테스트했습니다. IIF에 대해서는 case와 동일 하며 iif는 옵티 마이저에 의해 case 표현식으로 변환됩니다.

IIF가 CASE로 변환된다는 사실은이 기능의 동작에 대한 다른 측면에도 영향을 미칩니다.

결론 : 성능이 중요하지만 프로토 타이핑 또는 코드 선명도가 더 필요하고 큰 계산이 필요하지 않은 경우 함수를 사용할 수있는 경우 IIF 를 사용하는 것이 더 빠릅니다 .


LEAST () 및 GREATEST ()는 SQL 언어로 존재하는 경우 n 열 사이의 행 내에서 비교를 허용합니다. 나는 동등한 결과를 제공하는 솔루션을 따랐다. 여기에 대한 답변 (여러 가지와 함께)은 2 만 지원합니다.
Dodecaphone
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.