Aşağıdaki dizeleri 1,2,3,6,10,10A, 10B, 11 şeklinde sıralamak için bir karşılaştırma var mı?


12

Değişen uzunlukta tamsayılar içeren bir VARCHAR sütun ile bir veritabanı var. Onları 10'dan sonra değil 9'dan sonra gelir, 70A 70'den sonra gelir. Bunu PATINDEX () , bir CTE ve WHERE yan tümcesinde CASE deyimleriyle yapabildim .

Ancak, bunun gereksiz olacağı bir harmanlama olup olmadığını merak ediyordum.


: İşte Microsoft UserVoice Bağlan göç henüz ortaya URI'ları vermedi ettiğini artık öneri için yeni link bir Harmanlama seçeneği olarak Desteği "doğal sıralamayı" / DIGITSASNUMBERS
Solomon Rutzky

2
Microsoft, yeterli oy alırlarsa bunu SQL Server'da yerleşik bir özellik olarak uygulayacaklarını söyledi. Buraya gidin ve oy düğmesine tıklayın .
Peter Aylett

Yanıtlar:


8

Hayır. Harmanlama, kod sayfasına, aksan, büyük / küçük harf, genişlik, kana bağlı olarak alfabetik sıralama ile ilgilidir. Sayı karakterlerinin (0-9) hiçbir özelliği yoktur.

Yani 9sonra her zaman 10Biçinde herhangi bir tür.

Belirttiğiniz gibi bölmeniz veya şu şekilde sıralamanız gerekir:

ORDER BY
    RIGHT('                              ' + MyColumn, 30)

Sağdaki uzunluk kaç boşluğa sahip olduğunuzu belirler.

Elbette şunları yapabilirsiniz:

  • bunu gereksiz kılmak için 2 sütuna (ve çok daha hızlı) ve bunları birleştirmek için hesaplanmış bir sütuna sahip olmak
  • önde gelen sıfırlar konusunda ısrar ediyorlar
  • bir karakterde sağa yasla (yukarıdaki RIGHT'ımın depolanmış bir sürümü)

Son 2 öneri yukarıdaki benim SAĞ gibi ve biraz farklı. Daha hızlı sıralama (colukmn işlemeye gerek yoktur) ancak daha fazla depolama alanı gerekir


bunun nasıl çalıştığını anlamıyorum. 2, 2a, 3, vb. İçin
kırılıyor

@Mladen Prajdic: haklısın ayy. Sondaki alfabeleri unuttum
gbn

" Yani 9her zaman 10Bherhangi bir tür sonra " ile ilgili: SQL Server'da sadece bu şekilde çünkü "DigitsAsNumbers" işlemek için temel sıralama seçeneği bir Harmanlama seçeneği olarak maruz bırakılmadı. Hala ;-). Bu, Windows 7'den başlayarak, özellikle Dosya Gezgini'nde Windows tabanlı uygulamalar için kullanılabilir hale geldi. Ve eğer bir gün fikri destekliyorsa, bir gün SQL Server'a maruz kalabilir. Aşağıdaki Connect önerisini sunarak topu yuvarlamaya çalıştım: Harmanlama seçeneği olarak "doğal sıralama" / DIGITSASNUMBERS desteği .
Solomon Rutzky

8

Ben kurulum bir olur sütunu hesaplanan buna dayanarak sıralama sonra. Gibi bir şey

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

Ardından, şimdi sütunu dizine ekleyebileceğiniz gibi sıralamak için bu sütunu kullanın.


Benzer problemleri bilmek gerçekten yararlı. Ancak, bu durumda şemayı değiştiremiyorum.
Justin Dearing

Şemaya ekleyebilir misiniz? Hesaplanmış bir sütunu kısıtlamak için her zaman bir görünüm oluşturabilirsiniz - ancak bu hesaplanmış bir sütun gibi gerçekten optimize edilemez.
Aaron Bertrand

Dizine alınmış bir görünüm yaparsanız ve Enterprise sürümünüz varsa, ne yapmaya çalıştığınızı anlayabiliyorsa sorgunuz dizine eklenen görünümü otomatik olarak kullanır. Standart sürümde, dizine alınan görünümün kullanılmasını tetiklemek için WITH (NOEXPAND) kullanmanız gerekir. Bu durumda, vaka ifadesini siparişinize göre almanız gerekir, ancak işe yarayacağını düşünüyorum.
mrdenny

Hesaplanmış bir sütun oluşturmanız gerekmez. Sen fıkra ORDER BY doğrudan bu ifade kullanabilirsiniz
a_horse_with_no_name

Bir dizin veya tablo taraması garanti etmek istiyorsanız bunu yapabilirsiniz. Değeri dizine ekleyebilmek istiyorsanız, hesaplanmış bir sütun veya dizine alınmış görünüm gerekir.
mrdenny

5

@Gbn'nin ne söylediğini kanıtlamanın acı verici bir yolunu istiyorsanız (aslında alt dizeleri farklı bir şekilde sipariş etmek için bir harmanlama söyleyemiyorsanız), beklediğiniz sipariş için katsayısı olan hızlı bir #temp tablosu oluşturabilir ve herhangi bir harmanlama ile sipariş vermek aynı sırayı döndürür:

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;

Bu benim için yaklaşık 10 saniye içinde çalışır ve 0 satır verir - yani SQL Server (en azından 2008 R2, Denali denemedim) için hiçbir harmanlama beklediğiniz şekilde sıralanır. Sıralama tanımlamak için farklı bir yol gerekir.


2

Dizelerdeki sayıları gerçek sayılar olarak sıralamak için mantıklı ve etkili bir araç mı istiyorsunuz? Microsoft Connect önerim için oy vermeyi düşünün: Harmanlama seçeneği olarak "doğal sıralama" / DIGITSASNUMBERS desteği


Bu soru SQL Server'a özgü olsa da ve bu cevap açık olmasa da, bu bilgiyi sadece farkındalığı arttırmak ve diğer cevapların hiçbirine karşı çıkmamak için göndermem gerektiğini hissettim.

Bununla birlikte, SQL Server dışında, belirli ortamlarda bu tür bir sıralama yapmak mümkündür. En azından Unicode belgelerinde belirtilen bir şeydir. In UNICODE LOCALE VERİ ANLAMLANDIRMA DİL (LDML) BÖLÜM 5: COLLATION standart / raporda, bir grafik var Harmanlama Ayarları sıralama davranışını dikme için çeşitli seçenekler açıklanmıştır. Seçeneklerden biri -kn-trueveya [numericOrdering on]:

Grubu Varsa ilgili , ondalık hane her dizisi ([olarak General_Category = Nd UAX44 ]) kendi sayısal değerle primer düzeyde sıralanır. Örneğin, "A-21" <"A-123". Hesaplanan birincil ağırlıkları başlangıcında hepsi basamaklı yeniden sıralama grubu. Böylece, uyarlanmamış bir UCA tablosu ile, "a $" <"a0" <"a2" <"a12" <"a⓪" <"aa".

Ancak, bu belge bir "teknik standart" tır ve temel Unicode spesifikasyonunun bir parçası değildir. Belgenin üstündeki bir not şunları belirtir:

Unicode Teknik Standardı (UTS) bağımsız bir özelliktir. Unicode Standardına uygunluk, herhangi bir UTS'ye uygunluk anlamına gelmez.

Bu nedenle, bu özel davranış, her ikisi de temel Unicode belirtimine uysa bile, SQL Server'da veya .NET'te (en azından yerel olarak) kullanılamaz.

Yoğun bakım projesi (Unicode için Uluslararası Bileşenler) uygular bu işlevsellik ve bunun bile bir online demo olduğu C / C ++ ve Java kütüphaneleri kümesidir. Ve "ilgili projeler" altında, ICU kütüphanesi için bu işlevselliğin yönetilen koda maruz kalmasına izin verecek bir COM nesne sarmalayıcısı gibi görünen bir .NET projesine bağlantı vardır. Ancak bu .NET projesinin hala etkin olup olmadığı açık değildir.

Ancak bu davranışı çalışırken görmek için YBÜ Harmanlama Demosuna gidin .

Aşağıdakileri sol taraftaki Girdi metin alanına yapıştırın :

1
2
10B
6
11
10A
3
10

Tüm seçenekleri "varsayılan" olarak ayarlayın. sortDüğmenin sağındaki "giriş satırı numaraları" seçeneğini işaretleyin ve "fark güçlü yanları" seçeneğinin işaretli olmadığından emin olun.

Click sortdüğmesi ve aşağıdakileri geri almalısınız:

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

Bu tipik bir dize sıralaması yaparken beklenen ve SQL Server'da gördüğünüz şeydir.

Şimdi, düğmenin hemen üzerindeki radyo düğmesi serisinde sort, ikinci sıra "sayısal" olarak etiketlenir. "Açık" radyo düğmesini seçin.

sortDüğmeyi tekrar tıklayın ve aşağıdakileri geri almalısınız:

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

Sayısal bölüm dizenin ortasındayken bunun işe yarayıp yaramadığını sorguluyor musunuz? Tamam, aşağıdakileri sol taraftaki Giriş metin alanına yapıştırın (önceki listenin yerini alarak):

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

Sayısal ayarın "açık" olarak ayarlandığından emin olun . sortDüğmeyi tekrar tıklayın ve aşağıdakileri geri almalısınız:

[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

Bunu başka bir yerde görmek ister misiniz? Sabit sürücünüzde C: \ temp \ sorting \ gibi bir klasör oluşturun ve aynı "Script -..." adlarında boş dosyalar oluşturun. Bir Do DIRbir komut penceresinde ve standart sıralamayı göreceksiniz. Ancak Windows Gezgini'nde dosya listesine bakarken listenin "sayısal" seçeneği kullanılarak sıralanmış olduğunu göreceksiniz :-).


FYI, Postgres 10 YBÜ harmanlamaları için destek kazanıyor. Peter Eisentraut tarafından yazılmış bu blog gönderisine bakın .
Basil Bourque

@BasilBourque PG10 hakkında bahsettiğiniz için teşekkür ederiz. Bu blog gönderisi, sonunda, "ICU, henüz PostgreSQL aracılığıyla ortaya koymadığımız pek çok işlevsellik sunuyor. Büyük / küçük harfe duyarlı olmayan sıralama, aksan duyarsız sıralama ve bir harmanlamayı tamamen özelleştirme seçenekleri vardır. Gelecek PostgreSQL sürümlerinde olanlar için. " Yani ilk / şimdiki uygulamasında cevabımdaki hiçbir bilgiyi değiştirmiyor. Gelecekteki bir teklif sayısal sıralama izin veriyorsa, o zaman cevabımda, ancak bu soru SQL Server'a özgü olduğundan dipnot olarak bahsedeceğim.
Solomon Rutzky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.