ProgramingTip

SQL Server ORDER BY 날짜 및 마지막 null

bestdevel 2020. 11. 1. 18:29
반응형

SQL Server ORDER BY 날짜 및 마지막 null


날짜별로 주문합니다. 가장 최근 날짜가 먼저 나오길 원합니다. 간단하지만 null 인 레코드가 많고 날짜가있는 레코드가 오는 레코드가.

나는 성공하지 못한 몇 가지를 시도했습니다.

ORDER BY ISNULL(Next_Contact_Date, 0)

ORDER BY ISNULL(Next_Contact_Date, 999999999)

ORDER BY coalesce(Next_Contact_Date, 99/99/9999)

날짜별로 주문하고 null이 마지막에 오도록 비용을 지불해야합니까? 데이터 유형은 smalldatetime입니다.


smalldatetime 2079 년 6 월 6 일까지 범위가 있으므로

ORDER BY ISNULL(Next_Contact_Date, '2079-06-05T23:59:00')

합법적 인 기록에 해당 날짜가없는 경우.

가정이 아니라면 더 강력한 옵션에 의존하는 것이 두 개의 열로 정렬하는 것입니다.

ORDER BY CASE WHEN Next_Contact_Date IS NULL THEN 1 ELSE 0 END, Next_Contact_Date

위의 두 제안 모두 색인을 사용하여 정렬을 피하고 추가 계획을 제공 할 수 없습니다.

여기에 이미지 설명 입력

미래의 계획가 존재한다면 또 다른 가능성은

SELECT 1 AS Grp, Next_Contact_Date 
FROM T 
WHERE Next_Contact_Date IS NOT NULL
UNION ALL
SELECT 2 AS Grp, Next_Contact_Date 
FROM T 
WHERE Next_Contact_Date IS NULL
ORDER BY Grp, Next_Contact_Date

계획


Itzik 벤 웨이 코 뮤니시의 저자에 따르면, MS SQL 서버 2012 T-SQL 기본 기본적으로, "SQL 서버는 정렬 NULL의 비 전에 마크를 NULL의 값. 얻으려면 NULL의 마크가 마지막으로 정렬, 당신은 사용할 수있는 사례 가 반환하는 식을 1 '경우 Next_Contact_Date 열은 NULL아닌 경우 0 " NULL 비. NULL의 -display가 발현 0 다시 얻기 때문에, 정렬 전에 그들은

부호 (어느 하나 얻기)이. CASE의 표현은 제로서 사용 열 정렬. " Next_Contact_Date 열"두 번째 정렬 열로 지정해야합니다. 이렇게하면 NULL아닌 마크가 서로 선택 정렬됩니다. " 다음은 MS SQL Server 2012 (및 SQL Server 2014)에 대한 예제에 대한 솔루션 쿼리입니다.

ORDER BY 
   CASE 
        WHEN Next_Contact_Date IS NULL THEN 1
        ELSE 0
   END, Next_Contact_Date;

IIF 구문을 사용하는 동등한 코드 :

ORDER BY 
   IIF(Next_Contact_Date IS NULL, 1, 0),
   Next_Contact_Date;

조금 늦었지만 유용하다고 생각할 수도 있습니다.

나에게 ISNULL은 테이블 스캔으로 인해 의문의 여지가 없었습니다. UNION ALL은 복잡한 쿼리를 반복해야하며 TOP X 만 선택하는 것이 매우 그렇습니다.

테이블 디자인을 사용할 수있는 경우 다음을 수행 할 수 있습니다.

  1. 정렬을 위해 Next_Contact_Date_Sort와 같은 다른 필드를 추가합니다.

  2. 필요한 항목에 따라 해당 필드를 큰 (또는 작은) 값으로 채우는 트리거를 만듭니다.

    CREATE TRIGGER FILL_SORTABLE_DATE ON YOUR_TABLE AFTER INSERT,UPDATE AS 
    BEGIN
        SET NOCOUNT ON;
        IF (update(Next_Contact_Date)) BEGIN
        UPDATE YOUR_TABLE SET Next_Contact_Date_Sort=IIF(YOUR_TABLE.Next_Contact_Date IS NULL, 99/99/9999, YOUR_TABLE.Next_Contact_Date_Sort) FROM inserted i WHERE YOUR_TABLE.key1=i.key1 AND YOUR_TABLE.key2=i.key2
        END
    END
    

order by -cast([Next_Contact_Date] as bigint) desc

당신의 SQL을 지원하지 않는 경우 NULLS FIRSTNULLS LAST,이 작업을 수행하는 가장 간단한 방법은 사용하는 것입니다 value IS NULL표현 :

ORDER BY Next_Contact_Date IS NULL, Next_Contact_Date

끝에 null을 넣으려면 ( NULLS LAST) 또는

ORDER BY Next_Contact_Date IS NOT NULL, Next_Contact_Date

널을 앞에 놓으십시오. 이것은 열의 유형을 알 필요가 없으며 CASE표현식 보다 읽기 쉽습니다 .

편집 : 아아, 이것은 PostgreSQL 및 MySQL과 같은 다른 SQL 구현에서 작동하지만 MS SQL Server에서는 작동하지 않습니다. 나는 테스트 할 SQL Server가 없었고 Microsoft의 문서와 다른 SQL 구현에 대한 테스트에 의존했습니다. Microsoft에 따르면 value IS NULL 다른 표현과 마찬가지로 사용할 수 있어야 하는 표현 입니다. 그리고 ORDER BY 표현을 취하는 다른 진술과 마찬가지로 표현을 취해야 합니다. 그러나 실제로 작동하지 않습니다.

따라서 SQL Server에 가장 적합한 솔루션은 CASE식인 것 같습니다.


desc를 사용하고 필요한 경우 -1을 곱합니다. 마지막에 null이있는 오름차순 int 순서의 예 :

select * 
from
(select null v union all select 1 v union all select 2 v) t
order by -t.v desc

나는 이것이 오래되었다는 것을 알고 있지만 이것이 나를 위해 일한 것입니다.

Order by Isnull(Date,'12/31/9999')

참고 URL : https://stackoverflow.com/questions/5886857/sql-server-order-by-date-and-nulls-last

반응형