2009-01-29 31 views
18

bir satır sayacı ile sorgu:SQLServer SQL satır bir dizi döner bir SQL sorgusu

SELECT id, name FROM users where group = 2 

ihtiyacım da artan bir tamsayı değerine sahip olan bir sütun içerir, böylece ilk satır gerekiyor sayaç sütununda 1, ikincisi 2, üçüncü 3 3

Burada gösterilen sorgu, basitleştirilmiş bir örnektir, gerçekte sorgu, birkaç birleştirmeler ve iç içe geçmiş sorgularla rasgele karmaşık olabilir. Bunu biliyorum

bir otomatik numara alanı ile geçici tablosu kullanılarak elde edilebilir, ama sorguda kendi içinde bunu yapmanın bir yolu var mı?

cevap

24

, çizgisinde bir şey:

SELECT my_first_column, my_second_column, 
    ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter 
FROM my_table 

Ancak ROW_NUMBER() OVER (ORDER BY ...) yapı sadece Row_Counter değerlerini belirleyen dikkat etmek önemlidir, öyle sonuçlarının sırasını garanti etmez.

'un kendisi bir ORDER BY belirtecine sahip olmadıkça, SQL Server'ın sorguyu optimize etmeye nasıl karar verdiğine bağlı olarak sonuçlar herhangi bir sırayla iade edilebilir. (. See this article for more info)

sonuç hepRow_Counter amacıyla iade edileceğini garanti etmenin tek yolu hem SELECT için tam olarak aynı sıralamayı uygulamaktır ve ROW_NUMBER():

SELECT my_first_column, my_second_column, 
    ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter 
FROM my_table 
ORDER BY my_order_column -- exact copy of the ordering used for Row_Counter 

yukarıdaki desen her zaman doğru sırayla sonuçları döndürür ve basit sorgular için iyi çalışır, ancak ORDER BY maddesinde belki de düzinelerce ifade ile "rasgele karmaşık" bir sorgu hakkında ne? iç içe sorgu kullanma

SELECT t.* 
FROM 
(
    SELECT my_first_column, my_second_column, 
     ROW_NUMBER() OVER (ORDER BY ...) AS Row_Counter -- complex ordering 
    FROM my_table 
) AS t 
ORDER BY t.Row_Counter 

az dağınıklığı ve daha kolay bakım anlamına karmaşık ORDER BY maddesini, çoğaltmak gerek yok anlamına gelir: Bu tür durumlarda ben şöyle bir şey yerine tercih ederim. Dış ORDER BY t.Row_Counter ayrıca sorgulama amacınızı diğer geliştiricilerinize daha açık hale getirir.

+0

İç içe geçmiş sorgu neden? ROW_NUMBER() hızlı testim ile sonuçta oluşan sorgu zaten satır sayacı değerine göre sıralandı. – andynormancx

+1

Yukarıdaki iç içe geçmiş sorgu gereksizdir, ancak bazen "SELECT t. * FROM (...)" yazısını t.Row_Counter 20 ve 30 BEWEEN olarak sayfa verilerinin etkili bir yolu olarak yazmak için yararlı olabilir. – Juliet

+0

İç içe geçmiş sorgu *, * sonuçların her zaman "rasgele karmaşık" sorgular için Row_Counter düzeninde döndürüleceğini garanti etmek istiyorsanız gereklidir. (Daha fazla bilgi için bkz. Http://blogs.msdn.com/queryoptteam/archive/2006/05/02/588731.aspx.) – LukeH

10

SQL Server 2005 ve sonraki sürümlerde, sıralama düzeni ve sayımların yapıldığı (ve sıfırlama) grupların seçeneklerini içeren ROW_NUMBER() işlevini kullanabilirsiniz. Yeni başlayanlar için

-2

Heres farklı bir yaklaşım. Birden çok veri tablosuna katılabilir olmayan veya herhangi bir nedenle tüm satırları aynı anda saymak istemiyorsanız, ancak yine de aynı satır sayısından ayrılmasını istiyorsanız, bunu yapan bir tablo oluşturabilirsiniz. iş senin için.

Örnek:

create table #test (
     rowcounter int identity, 
     invoicenumber varchar(30) 
     ) 

insert into #test(invoicenumber) select [column] from [Table1] 

insert into #test(invoicenumber) select [column] from [Table2] 

insert into #test(invoicenumber) select [column] from [Table3] 

select * from #test 

drop table #test 
+0

tarafından desteklenir. Özgün soruda özellikle geçici bir tabloyla yapılabileceğini bildiğim belirtildi, ancak bunu önleyen bir çözüm arıyordum. – andynormancx

2

en basit yolu, değişken bir satır sayacı kullanmaktır. Ancak iki gerçek SQL komutu olacaktır. aşağıdaki gibi bir o sorguyu değişkeni ayarlayın ve: Eğer katılır vb Genellikle bu bir saklı yordam yapmak ile istediğiniz gibi

SET @n=0; 
SELECT @n:[email protected]+1, a.* FROM tablename a 

Sorgunuzda olarak karmaşık olabilir. Değişkenle her türlü eğlenceye sahip olabilirsiniz, hatta alan değerlerine karşı hesaplamak için kullanabilirsiniz.Anahtar, :=

+0

Bu SQL Server hakkında emin değilim, MySQL için çalışır –