2009-03-11 23 views
44

bir tablo, bu gibi olması:Bir sütun alanı için iki satır arasındaki fark nasıl alınır?

rowInt Value 
2  23 
3  45 
17  10 
9  0 
.... 

kolon rowInt değerleri aynı artım sahip bir dizi tamsayı ancak değildir. Ben rowInt değerleri listelemek için aşağıdaki sql kullanabilirsiniz:

SELECT * FROM myTable ORDER BY rowInt; 

Bu irade liste değerlerini rowInt tarafından. Nasıl böyle sonuçla iki sıra arasındaki Değerinin farkını almak alabilirsiniz:

rowInt Value Diff 
2  23 22 --45-23 
3  45 -35 --10-45 
9  0  -45 --0-45 
17  10 10 -- 10-0 
.... 

tablo SQL 2005'te ise (Miscrosoft)

+0

İkinci sırada 10-45 olması mı öngörülüyor? Nereden 10 tane alırsın? – Quassnoi

+0

Bazı calcs tutarlı değil ... row2's (45-23) row3-row2, ama row9 's (0-45) row9-row3 olduğunu, row17-row9 olan (10-0) olmamalıdır? – MatBailie

+0

Orijinal satır grubunuzdaki bitişik değerler arasındaki farkı (2, 3, 17, 9) saymak istediğiniz görülüyor. O zaman size sormam gerekecek: ORİJİNAL dizininiz hangi sütunda sıralanır? SQL'de 'varsayılan sipariş' diye bir şey olmadığını unutmayın. – Quassnoi

cevap

46
SELECT 
    [current].rowInt, 
    [current].Value, 
    ISNULL([next].Value, 0) - [current].Value 
FROM 
    sourceTable  AS [current] 
LEFT JOIN 
    sourceTable  AS [next] 
     ON [next].rowInt = (SELECT MIN(rowInt) FROM sourceTable WHERE rowInt > [current].rowInt) 

DÜZENLEME: Düşünüyorum kullanarak Seçimdeki bir alt sorgu (ala Quassnoi'nin cevabı) daha verimli olabilir. Farklı sürümleri denemek ve hangi veri kümesinin boyutunda en iyi performans göstereceğini görmek için yürütme planlarına bakıyorum ...

+0

Eğer rowInt üzerinde bir dizin varsa (ki bence o yapar), o zaman sorgum daha verimlidir. Eğer yapmazsa, o zaman sizinki (eğer bu durumda etkinlik hakkında konuşmak mümkün ise). Ayrıntılar için buraya bakın: http: // stackoverflow.com/questions/590079/autoincrement-fields-maxid-vs-top-1-id-order-by-id-desc – Quassnoi

+0

1 milyon rastgele oluşturulmuş kayıtla kukla bir tablo oluşturdum ve her iki sorgunun da aynı zamana sahip olduğunu buldum . Aslında, icra planlarındaki tek fark, bir SORT fonksiyonunun pozisyonuydu (son çıktıyı sıraladım) – MatBailie

+0

Metodunu beğendim. Davamla iyi çalışıyor. –

21
SELECT rowInt, Value, 
     COALESCE(
     (
     SELECT TOP 1 Value 
     FROM myTable mi 
     WHERE mi.rowInt > m.rowInt 
     ORDER BY 
      rowInt 
     ), 0) - Value AS diff 
FROM myTable m 
ORDER BY 
     rowInt 
10

Siparişlerden gerçekten emin olmak istiyorsanız, "Row_Number()" komutunu kullanın. temelde "min" belirterek ya da "top" yapmadan, mevcut satır ile bir sonraki satır birleşiyor

T1.ID + 1 = T2.ID 

ve mevcut kaydın sonraki kaydını karşılaştırmak (fıkra "açık" yakından bakmak). Eğer az sayıda kayıt varsa, "Dems" veya "Quassanoi" ile başka çözümler iyi çalışır.

with T2 as (
    select ID = ROW_NUMBER() over (order by rowInt), 
      rowInt, Value 
    from myTable 
) 
select T1.RowInt, T1.Value, Diff = IsNull(T2.Value, 0) - T1.Value 
from ( SELECT ID = ROW_NUMBER() over (order by rowInt), * 
      FROM myTable) T1 
     left join T2 on T1.ID + 1 = T2.ID 
ORDER BY T1.ID 
2

SQL Server, analitik işlevleri destekliyor mu?

select rowint, 
     value, 
     value - lag(value) over (order by rowint) diff 
from  myTable 
order by rowint 
/
+0

Msg 195, Düzey 15, Durum 10, Satır 3 'gecikme' tanınmış bir yerleşik işlev adı değil. – Sung

+0

Bunu bir noktaya verdim, çünkü evet Denali yapıyor ... her ne kadar belki de bu sunucu gönderildiyse sql sunucusu hiç cevap vermedi – Pixelated

+1

@FairFunk Soru işaretlendiğinden dolayı bir noktayı çıkardım yani Denali işlevselliği alakasız. –

0
select t1.rowInt,t1.Value,t2.Value-t1.Value as diff 
from (select * from myTable) as t1, 
    (select * from myTable where rowInt!=1 
     union all select top 1 rowInt=COUNT(*)+1,Value=0 from myTable) as t2 
where t1.rowInt=t2.rowInt-1 
0

Sorgu önceki veya sonraki satır erişmek için tek bir sütunda

SELECT 
Column name, 
DATEDIFF(
(SELECT MAX(date) FROM table name WHERE Column name < b. Column name), 
Column name) AS days_since_last 
FROM table name AS b 
+0

Bu çok eski bir soru ve cevabınız aynı soruyu gerçekten yanıtlamıyor. – shawnt00

2

SQL Server 2012 2 sıra ve destek kadar LAG/LEAD fonksiyonları arasındaki tarih farkı bul. SQL Server 2005 bunu desteklemiyor (SQL2005'te bir katılmaya veya başka bir şeye ihtiyacınız var). Bu verilere

/* Prepare */ 
select * into #tmp 
from 
(
    select 2 as rowint,  23 as Value 
    union select 3,  45 
    union select 17,  10 
    union select 9,  0 
) x 


/* The SQL 2012 query */ 
select rowInt, Value, LEAD(value) over (order by rowInt) - Value 
from #tmp 

KURŞUN (değer) üzerine

Bir SQL 2012 örneği maddesi "üzerinde" verilen sıraya göre bir sonraki satırın değerini döndürecektir.

+1

LAG. LAD değil. Düzenlememe izin vermiyor çünkü 6 karakteri değiştirmeniz gerekiyor – danmiser

İlgili konular