SQL

2015-04-17 20 views
12

içinde hiyerarşik metin sıralama varchar alanı olan bir tablo var. Bu alan, sipariş etmek istediğim hiyerarşik numaraları saklar. Ben T-SQL ile aşağıdaki sonucu elde edebilirsiniz nasılSQL

1 
1.1 
1.1.1 
1.1.2 
1.1.3. 
1.1.4 
1.1.5 
1.1.6. 
1.1.7 
10. 
10.1 
10.2 
10.3 
11. 
11.1 
11.2 
2. 
2.1 
1.2.2 
1.2.2.1 
1.2.2.2 

: Burada

verilerim örneğidir

1 
1.1 
1.1.1 
1.1.2 
1.1.3 
1.1.4 
1.1.5 
1.1.6 
1.1.7 
1.2.2 
1.2.2.1 
1.2.2.2 
2. 
2.1 
10. 
10.1 
10.2 
10.3 
11. 
11.1 
11.2 
aşağıdaki SQL ile parçaları bölmek çalıştı

, ama bu zarif değil.

SELECT CASE WHEN CHARINDEX('.',SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','')) = 0 
    THEN SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','') 
    ELSE REPLACE(SUBSTRING(SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.',''),1, CHARINDEX('.',SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.',''))),'.','') 
    END AS FIRST_PART 
,CASE WHEN CHARINDEX('.',SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','')) > 0 
     THEN SUBSTRING( 
SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','') 
    ,CHARINDEX('.',SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','')) +1 
    ,LEN(SUBSTRING(LTRIM(RTRIM(NR)),1,LEN(NR)-1)+REPLACE(SUBSTRING(LTRIM(RTRIM(NR)),LEN(NR),1),'.','') ) 
    ) 
    ELSE '0' 
    END AS SECOND_PART 
FROM TEST_TABLE 

Bunu yapmak için daha iyi bir yolu var mı?

+0

Onun yerine ilişkileri yerine saklayın. öğeleri sütun değerleri olarak ayırdınız? – jarlh

+0

Yalnızca SELECT gerçekleştirebilir ve ilişkileri saklayabilmem mümkün – h0mebrewer

+2

http://stackoverflow.com/questions/6446000/properly-sorting-dotted-numbers-stored-as-character-in-sql-server – niyou

cevap

6

bu deneyin:

DECLARE @DataSource TABLE 
(
    [Value] VARCHAR(12) 
); 

INSERT INTO @DataSource ([Value]) 
VALUES ('1') 
     ,('1.1') 
     ,('1.1.1') 
     ,('1.1.2') 
     ,('1.1.3.') 
     ,('1.1.4') 
     ,('1.1.5') 
     ,('1.1.6.') 
     ,('1.1.7') 
     ,('10.') 
     ,('10.1') 
     ,('10.2') 
     ,('10.3') 
     ,('11.') 
     ,('11.1') 
     ,('11.2') 
     ,('2.') 
     ,('2.1') 
     ,('1.2.2') 
     ,('1.2.2.1') 
     ,('1.2.2.2'); 

SELECT * 
FROM @DataSource 
ORDER BY CAST('/' + IIF(RIGHT([Value],1) = '.', LEFT([Value], LEN([Value]) - 1), [Value]) + '/' AS HIERARCHYID); 

daha fazla detay için hierarchyid kontrol edebilirsiniz. ORDER BY maddesindeki denetim, . değerini değerin sonunda kaldırır (eğer varsa).


Böyle basit CASE WHEN ile IIF işlevini değiştirebilirsiniz:

SELECT * 
FROM @DataSource 
ORDER BY CAST('/' + CASE WHEN RIGHT([Value],1) = '.' THEN LEFT([Value], LEN([Value]) - 1) ELSE [Value] END + '/' AS HIERARCHYID); 
+0

Yalnızca SQL Server 2012 ve üstü. IIF, SQL Server 2008 – h0mebrewer

+0

@ h0mebrewer'da mevcut değildir. IIF'yi kolayca 'CASE WHEN' ile değiştirebilirsiniz - düzenlemeyi kontrol edin. – gotqn

-1

noktalar ve düzeni kaldırmak:

select column from table order by replace(column,'.','') 

Ve eğer numaraya varchar dönüştürmek için gerek yoktur Daha önce 10'un gelmesini isteyin. 2.

+0

Ben 2 için 10 istemiyorum. – h0mebrewer