1,2,3,6,10,10A, 10B, 11 순서로 다음 문자열을 정렬하는 데이터 정렬이 있습니까?


12

가변 길이의 정수를 포함하는 VARCHAR 열이있는 데이터베이스가 있습니다. 10을 1이 아닌 9 뒤에, 70A를 70 뒤에 오도록 정렬하고 싶습니다 . WHERE 절의 PATINDEX () , CTE 및 CASE 문 으로이 작업을 수행 할 수있었습니다 .

그러나 이것이 불필요 한 데이터 정렬이 있는지 궁금합니다.


다음은 Microsoft가 Connect에서 UserVoice로 마이그레이션했지만 아직 URI를 전달하지 않았 음을 제안하는 새로운 링크입니다 . 조합 옵션으로 "자연 정렬"/ DIGITSASNUMBERS 지원
— Solomon Rutzky

2
Microsoft는 충분한 투표를 받으면 SQL Server의 기본 제공 기능으로이 기능을 구현할 것이라고 말했습니다. 여기로 가서 투표 버튼을 클릭하십시오 .
— 피터 Aylett

답변:


8

데이터 정렬은 코드 페이지, 악센트, 대소 문자, 너비, 가나에 따라 알파벳순으로 정렬됩니다. 숫자 문자 (0-9)에는 속성이 없습니다.

따라서 9항상 모든 종류의 후 10B입니다 .

다음과 같이 언급 하거나 정렬 하면 분할해야합니다 .

ORDER BY
    RIGHT('                              ' + MyColumn, 30)

오른쪽의 길이는 사용 가능한 공간 수를 결정합니다.

물론 가능합니다 :

  • 이 열을 불필요하게 (더 빨리) 만들려면 열을 결합하고 계산 열을 결합하십시오
  • 선행 0을 고집
  • char (위의 내 오른쪽의 저장된 버전)에서 정당화

후자의 두 가지 제안은 위의 오른쪽과 같으며 약간 다릅니다. 빠른 정렬 (필요한 대량 처리 필요 없음)이지만 더 많은 스토리지 필요


어떻게 작동하는지 모르겠습니다. 그것은 2, 2a, 3 등을 위해 휴식을 취합니다.
— Mladen Prajdic

@Mladen Prajdic : 맞습니다. 죄송합니다. 알파벳 순으로 잊어 버린
— gbn

"에 관한 그래서 9후에 항상 10B어떤 종류의. "는 SQL Server의 방법은 핸들 "DigitsAsNumbers"에 기본 정렬 옵션은 정렬 옵션으로 노출되지 않았기 때문에 단지이다. 그러나 ;-). 이 기능은 Windows 7부터 Windows 탐색기부터 가장 많이 사용되었으며, 특히 파일 탐색기에서 사용할 수있게되었습니다. 그리고 충분한 사람들이 아이디어를지지한다면 언젠가는 SQL Server에 노출 될 수 있습니다. 다음 Connect 제안을 제출하여 볼 롤링을 얻으려고했습니다 . Collation 옵션으로 "natural sorting"/ DIGITSASNUMBERS를 지원 하십시오 .
— Solomon Rutzky

8

계산 열 을 설정 한 다음 그에 따라 정렬합니다. 같은 것

CAST( 
     CASE WHEN IS_NUMERIC(left(OtherColumn, 2) = 1) then 
         left(OtherColumn,2) 
     else 
         left(otherColumn, 1)  
AS INT)

그런 다음 열을 색인화 할 수 있으므로이 열을 사용하여 정렬하십시오.


비슷한 문제에 대해 아는 것이 정말 유용합니다. 그러나이 경우 스키마를 변경할 수 없습니다.
— 저스틴 친애하는

스키마에 추가 할 수 있습니까? 계산 열을 제한하면 항상 뷰를 만들 수 있습니다. 비록 계산 열처럼 최적화 할 수는 없지만.
— Aaron Bertrand

인덱싱 된 뷰를 수행하고 Enterprise Edition이있는 경우 쿼리는 수행하려는 작업을 파악할 수있는 경우 인덱싱 된 뷰를 자동으로 사용합니다. 표준형의 경우 WITH (NOEXPAND)를 사용하여 인덱싱 된 뷰를 사용하도록해야합니다. 그 시점에서 당신은 순서대로 사례 진술을해야하지만 그것이 효과가 있어야한다고 생각합니다.
— mrdenny

계산 열을 만들 필요가 없습니다. ORDER BY 절에서 해당 표현식을 직접 사용할 수 있습니다.
— a_horse_with_no_name

인덱스 또는 테이블 스캔을 보장하려면 가능합니다. 값을 인덱싱하려면 계산 열 또는 인덱싱 된 뷰가 필요합니다.
— mrdenny

5

@gbn이 말하는 것을 입증하는 고통스러운 방법을 원한다면 (기본적으로 데이터 정렬에 부분 문자열을 다르게 주문할 수는 없음) 원하는 순서에 대한 계수가있는 빠른 #temp 테이블을 만들 수 있는지 확인하십시오. 데이터 정렬로 정렬하면 동일한 순서가 반환됩니다.

CREATE TABLE #foo(id INT, n NVARCHAR(10));

CREATE TABLE #bar(collation SYSNAME);

SET NOCOUNT ON;

INSERT #foo SELECT 1,'1'
UNION SELECT 2,'2'
UNION SELECT 3,'3'
UNION SELECT 4,'6'
UNION SELECT 5,'10'
UNION SELECT 6,'10A'
UNION SELECT 7,'10B'
UNION SELECT 8,'11';

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'
    WITH x AS 
    (
        SELECT n, rn = ROW_NUMBER() OVER 
        (ORDER BY n COLLATE ' + name + ') FROM #foo
    ) 
    INSERT #bar 
    SELECT TOP (1) ''' + name + ''' FROM x
    WHERE NOT EXISTS
    (
        SELECT COUNT(*) FROM #foo AS f
        WHERE f.id = x.rn
        AND f.n <> x.n
    );' FROM sys.fn_helpcollations();

EXEC sp_executesql @sql;

SELECT collation FROM #bar;

GO
DROP TABLE #foo, #bar;

이것은 약 10 초 만에 실행되며 0 행을 생성합니다. 즉, SQL Server에서 사용할 수있는 데이터 정렬이 없습니다 (최소한 2008 R2, Denali를 시도하지 않은 경우) 예상대로 정렬됩니다. 정렬을 정의하는 다른 방법이 필요합니다.


2

문자열에서 숫자를 실제 숫자로 정렬하는 현명하고 효율적인 방법을 원하십니까? Microsoft Connect 제안에 대한 투표를 고려하십시오 . 데이터 정렬 옵션으로 "자연 정렬"/ DIGITSASNUMBERS 지원


이 질문은 SQL Server에만 해당되는 것이지만이 답변은 아닙니다. 정보에 대한 인식을 높이고 다른 답변에 반대하지 않도록이 정보를 게시해야한다고 생각했습니다.

그러나 SQL Server 외부에서는 특정 환경에서 이러한 유형의 정렬을 수행 할 수 있습니다. 그것은 적어도 유니 코드 문서에 명시된 것입니다. 에서 유니 코드 LOCALE 데이터 마크 업 언어 (LDML) PART 5 : 대조 표준 / 보고서에 차트가 정렬 설정 정렬 동작을 조정하는 다양한 옵션에 대해 설명합니다. 옵션 중 하나는 -kn-true또는 [numericOrdering on]:

on으로 설정하면 10 진수 숫자 시퀀스 ([ UAX44 ] 의 General_Category = Nd )가 기본 값에서 숫자 값으로 정렬됩니다. 예를 들어 "A-21"< "A-123"입니다. 계산 된 1 차 가중치는 모두 숫자 순서 변경 그룹 의 시작 부분에 있습니다. 따라서 조정되지 않은 UCA 테이블에서는 "a $"< "a0"< "a2"< "a12"< "a⓪"< "aa"입니다.

그러나이 문서는 "기술 표준"이며 핵심 유니 코드 사양의 일부가 아닙니다. 문서 상단의 메모는 다음과 같습니다.

UTS (Unicode Technical Standard) 는 독립적 인 사양입니다. 유니 코드 표준에 대한 적합성은 UTS에 대한 적합성을 의미하지 않습니다.

따라서이 특정 동작은 둘 다 핵심 유니 코드 사양을 준수하더라도 SQL Server 또는 .NET (적어도 기본적으로는 아님)에서는 사용할 수 없습니다.

ICU의 프로젝트 (유니 코드에 대한 국제 구성 요소) 구현이 기능, 그리고 심지어 온라인 데모가 있다고 C / C ++ 및 Java 라이브러리의 집합입니다. "관련 프로젝트"에는 ICU 라이브러리의 COM 객체 래퍼 인 .NET 프로젝트에 대한 링크가 있으며이 기능을 통해 관리되는 코드에이 기능을 제공 할 수 있습니다. 그러나 해당 .NET 프로젝트가 여전히 활성화되어 있는지 확실하지 않습니다.

그러나이 동작을 실제로 보려면 ICU Collation Demo 로 이동하십시오 .

왼쪽 의 입력 텍스트 영역에 다음을 붙여 넣습니다 .

1
2
10B
6
11
10A
3
10

모든 옵션을 "default"로 설정하십시오. sort버튼 오른쪽의 "입력 라인 번호"옵션을 확인하고 "diff strengths"옵션이 선택 해제되어 있는지 확인하십시오.

sort버튼을 클릭하면 다음과 같이 돌아옵니다.

[1] 1
[8] 10
[6] 10A
[3] 10B
[5] 11
[2] 2
[7] 3
[4] 6

이것은 일반적인 문자열 정렬을 수행 할 때 예상되는 것과 SQL Server에 표시되는 것입니다.

이제 버튼 바로 위의 일련의 라디오 버튼 sort에서 두 번째 행에는 "숫자"라는 레이블이 붙어 있습니다. "켜기"라디오 버튼을 선택하십시오.

sort버튼을 다시 클릭하면 다음과 같이 돌아옵니다.

[1] 1
[2] 2
[7] 3
[4] 6
[8] 10
[6] 10A
[3] 10B
[5] 11

숫자 부분이 문자열의 중간에있을 때 이것이 작동하는지 질문합니까? 다음을 왼쪽 의 입력 텍스트 영역에 붙여 넣습니다 (이전 목록 대체).

Script - 1.sql
Script - 2.sql
Script - 10B.sql
Script - 6.sql
Script - 11.sql
Script - 10A.sql
Script - 3.sql
Script - 10.sql

숫자 설정이 여전히 "on"으로 설정되어 있는지 확인하십시오 . sort버튼을 다시 클릭하면 다음과 같이 돌아옵니다.

[1] Script - 1.sql
[2] Script - 2.sql
[7] Script - 3.sql
[4] Script - 6.sql
[8] Script - 10.sql
[6] Script - 10A.sql
[3] Script - 10B.sql
[5] Script - 11.sql

다른 곳에서 이것을보고 싶습니까? 하드 드라이브에 C : \ temp \ sorting \ 과 같은 폴더를 만들고 동일한 "Script -..."이름의 빈 파일을 만듭니다. 를 수행 DIR명령 창에서 당신은 표준 정렬을 볼 수 있습니다. 그러나 Windows 탐색기에서 파일 목록을 볼 때 "숫자"옵션 (-)을 사용하여 정렬 된 목록을 볼 수 있습니다.


참고로 Postgres 10은 ICU 데이터 정렬을 지원합니다. Peter Eisentraut 의이 블로그 게시물 을 참조하십시오 .
— Basil Bourque

@BasilBourque PG10에 대해 언급 해 주셔서 감사합니다. 마지막으로이 블로그 포스트는 "ICU는 PostgreSQL을 통해 아직 노출하지 않은이 영역에서 많은 기능을 제공합니다. 대소 문자를 구분하지 않는 정렬, 악센트를 구분하지 않는 정렬 및 데이터 정렬을 완전히 사용자 정의하는 옵션이 있습니다. 향후 PostgreSQL 릴리스의 사용자에게 적합합니다. " 따라서 첫 번째 / 현재 구현에서는 내 답변의 정보가 변경되지 않습니다. 향후 제공이 숫자 정렬을 허용하는 경우 대답에서 언급하지만이 질문은 SQL Server 관련이므로 각주로 언급됩니다.
— Solomon Rutzky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.