2016-04-05 23 views
1

Merhaba arkadaşlar mevcut tarihi çıkarma tarihini sorgulamak ve uzunluğunu (geçerli uzunluk - önceki uzunluk) SQL kullanarak döndürmek istiyorum. Geçerli eksi önceki uzunluğunda aşağıdaki tabloda olduğu gibi değişikliklerin örnek bakRaporlamadan çıkarma sonucundan nasıl yararlanılır

Ben length_data DAN tarih, uzunluk SEÇ nasıl sorgunun düşünemedim

date     length   changes 
------------------- -------------- ------------ 
2000-08-29 10:30:00   147.98 147.98 
2000-08-30 00:00:00   147.98 0 
2000-09-02 10:30:00   156.51 8.53 
2000-09-04 00:00:00   156.51 .... 
2000-09-04 04:30:00   156.51 .... 
2000-09-04 06:30:00   156.51 .... 
2000-09-05 21:00:00   156.51 
2000-09-06 03:00:00   156.51 
2000-09-07 09:30:00   204.06 
2000-09-07 10:30:00   204.06 
2000-09-08 00:00:00   339.09 
2000-09-08 12:30:00   395.78 
2000-09-09 09:30:00   477.77 
2000-09-10 02:30:00   737.77 
+1

Bu çok kolaydır. RDBMS 'LAG/LİAD'e bağlı olarak veya bir önceki sırasına kendi kendine katılır. – lad2025

+0

Ne RDBMS (SQL Server, MySQL, Oracle ...)? – KenD

+0

@KenD the RDBMS, MySQL –

cevap

3

Sen simüle etmek için değişken kullanabilirsiniz LAG pencereli fonksiyonu:

SELECT `date`, `length`, 
     `length` - @prev AS changes, 
     @prev := `length` 
FROM length_data, (SELECT @prev := 0) AS a 
ORDER BY `date`; 

SqlFiddleDemo

date'un PRIMARY KEY/UNIQUE olduğunu varsayalım, aksi halde kararlı olmayacaktır.

DÜZENLEME:

Eğer alt sorgu kullanabilirsiniz ek sütunu kaldırmak için.

SELECT `date`, `length`, `changes` 
FROM (SELECT `date`, `length`, 
     `length` - @prev AS changes, 
     @prev := `length` 
     FROM length_data,(SELECT @prev := 0) as a 
     ORDER BY `date`) AS sub 
ORDER BY `date`; 

SqlFiddleDemo2

Çıkış:

╔══════════════════════════════╦═════════╦═════════╗ 
║   date    ║ length ║ changes ║ 
╠══════════════════════════════╬═════════╬═════════╣ 
║ August, 29 2000 10:30:00  ║ 147.98 ║ 147.98 ║ 
║ August, 30 2000 00:00:00  ║ 147.98 ║ 0  ║ 
║ September, 02 2000 10:30:00 ║ 156.51 ║ 8.53 ║ 
║ September, 04 2000 00:00:00 ║ 156.51 ║ 0  ║ 
║ September, 04 2000 04:30:00 ║ 156.51 ║ 0  ║ 
║ September, 04 2000 06:30:00 ║ 156.51 ║ 0  ║ 
║ September, 05 2000 21:00:00 ║ 156.51 ║ 0  ║ 
║ September, 06 2000 03:00:00 ║ 156.51 ║ 0  ║ 
║ September, 07 2000 09:30:00 ║ 204.06 ║ 47.55 ║ 
║ September, 07 2000 10:30:00 ║ 204.06 ║ 0  ║ 
║ September, 08 2000 00:00:00 ║ 339.09 ║ 135.03 ║ 
║ September, 08 2000 12:30:00 ║ 395.78 ║ 56.69 ║ 
║ September, 09 2000 09:30:00 ║ 477.77 ║ 81.99 ║ 
║ September, 10 2000 02:30:00 ║ 737.77 ║ 260  ║ 
╚══════════════════════════════╩═════════╩═════════╝ 

DÜZENLEME 2:

yalnızca bir sütun kullanarak hesaplamak için Jean Doux's idea kullanarak:

SELECT `date`, length, 
    CAST((-IF(@prev IS NULL,0,@prev) + (@prev := length)) AS DECIMAL(10,4)) AS changes 
FROM length_data,(SELECT @prev := NULL) AS a 
ORDER BY `date`; 

SqlFiddleDemo2

veya en kolay yolu, uygulama katmanında ek sütun atlamak için.

+0

Bu hile mükemmel bir şekilde yapılır, ancak sonuçtan fazla olan sütun #prev: = 'length' i nasıl kaldırabilirim? –

+1

size çok teşekkür ederim, benim görevimden biriyle ilerleyebilirim. –

+0

Gerçek tabloya başvurduğumda sorgu, bazen geri dönüş sonucu olmadan oldukça yükleniyor gibi görünüyor ve yüklemeyi sürdürürken, en iyi yükleme hızında çalışmasını sağlamak için bir şey eksik miyim? –

1
SELECT 
date, 
length, 
@prevLength - (@prevLength:= length) as changes 
FROM 
test, (SELECT @prevLength:= 0) as a 
ORDER BY account_id ASC, value ASC 
+0

Neredeyse doğru. Ama şimdiki haliyle '@prevLength - (@prevLength: = length) olarak değiştirirsiniz, her zaman sıfır alırsınız. – lad2025

+0

Evet haklısınız, bir alt sorgu kullanmalıyız, cevabımı silmeli miyim? –

+0

Ve eğer SELECT tarihini yaparsam, @prevLength - değişiklik olarak uzunluk, (@prevLength: = length) uzunluk olarak ... Tamam olacak, değil mi? Sadece aynı sütun sırası değil mi? –