Saya memiliki tabel yang memiliki ID, nilai, dan tanggal. Ada banyak ID, Nilai, dan tanggal dalam tabel ini.
Catatan dimasukkan ke dalam tabel ini secara berkala. ID akan selalu tetap sama tetapi kadang-kadang nilainya akan berubah.
Bagaimana saya bisa menulis kueri yang akan memberi saya ID plus waktu terakhir nilai telah berubah? Catatan: nilainya akan selalu meningkat.
Dari data sampel ini:
Create Table Taco
( Taco_ID int,
Taco_value int,
Taco_date datetime)
Insert INTO Taco
Values (1, 1, '2012-07-01 00:00:01'),
(1, 1, '2012-07-01 00:00:02'),
(1, 1, '2012-07-01 00:00:03'),
(1, 1, '2012-07-01 00:00:04'),
(1, 2, '2012-07-01 00:00:05'),
(1, 2, '2012-07-01 00:00:06'),
(1, 2, '2012-07-01 00:00:07'),
(1, 2, '2012-07-01 00:00:08')
Hasilnya harus:
Taco_ID Taco_date
1 2012-07-01 00:00:05
(Karena 00:05 adalah waktu terakhir Taco_Value
berubah.)
sql-server
sql-server-2008-r2
t-sql
SqlSandwich
sumber
sumber
taco
tidak ada hubungannya dengan makanan?Jawaban:
Dua pertanyaan ini bergantung pada asumsi yang
Taco_value
selalu meningkat dari waktu ke waktu.Alternatif dengan kegilaan fungsi jendela yang lebih sedikit:
Contoh di SQLfiddle
Memperbarui
Bagi mereka yang melacak, ada pertentangan tentang apa yang terjadi jika
Taco_value
bisa diulang. Jika bisa dari 1 ke 2 dan kemudian kembali ke 1 untuk yang diberikanTaco_ID
, kueri tidak akan berfungsi. Berikut adalah solusi untuk kasus itu, bahkan jika itu bukan teknik kesenjangan & kepulauan yang orang seperti Itzik Ben-Gan mungkin bisa impikan, dan bahkan jika itu tidak relevan untuk skenario OP - mungkin saja relevan dengan pembaca masa depan. Ini sedikit lebih kompleks, dan saya juga menambahkan variabel tambahan -Taco_ID
yang hanya pernah memiliki satuTaco_value
.Jika Anda ingin memasukkan baris pertama untuk ID mana pun yang nilainya tidak berubah sama sekali di seluruh rangkaian:
Jika Anda ingin mengecualikan baris itu, itu sedikit lebih kompleks, tetapi masih sedikit perubahan:
Diperbarui contoh SQLfiddle
sumber
value
muncul kembali: FiddlePada dasarnya, ini adalah saran @ Taryn "terkondensasi" untuk SELECT tunggal tanpa tabel turunan:
Catatan: solusi ini memperhitungkan ketentuan itu
Taco_value
hanya bisa bertambah. (Lebih tepatnya, ini mengasumsikan bahwaTaco_value
tidak dapat mengubah kembali ke nilai sebelumnya - sama dengan jawaban yang terhubung, pada kenyataannya.)Demo SQL Fiddle untuk kueri: http://sqlfiddle.com/#!3/91368/2
sumber
Anda harus dapat menggunakan keduanya
min()
danmax()
fungsi agregat mendapatkan hasilnya:Lihat SQL Fiddle dengan Demo
sumber
Satu lagi jawaban yang didasarkan pada asumsi bahwa nilai-nilai tidak muncul kembali (ini pada dasarnya adalah permintaan @ Aaron 2, diringkas dalam satu sarang kurang):
Tes di: SQL-Fiddle
Dan jawaban untuk masalah yang lebih umum, di mana nilai dapat muncul kembali:
(atau menggunakan
CROSS APPLY
semua baris terkait, termasukvalue
, ditampilkan):Tes di: SQL-Fiddle-2
sumber
dbo.Taco UNION ALL SELECT DISTINCT Taco_ID, NULL AS Taco_value, '19000101' AS Taco_date
).FYI +1 untuk menyediakan struktur sampel dan data. Satu-satunya hal yang bisa saya minta adalah output yang diharapkan untuk data itu.
EDIT: Yang ini akan membuatku gila. Saya baru tahu ada cara "sederhana" untuk melakukan ini. Saya menyingkirkan solusi yang salah dan menempatkan yang saya yakini benar. Berikut adalah solusi yang mirip dengan @bluefeets tetapi mencakup pengujian yang diberikan @AaronBertrand.
sumber
value
perubahannya.Mengapa tidak mendapatkan perbedaan nilai lag dan nilai memimpin? jika perbedaannya nol, itu tidak berubah, itu bukan nol, maka itu berubah. Ini dapat dilakukan dalam permintaan sederhana:
sumber
lag...
analitis hanya "baru" yang diperkenalkan di SQL Server 2012. Pertanyaan aslinya adalah meminta solusi pada SQL Server 2008 R2. Solusi Anda tidak akan berfungsi untuk SQL Server 2008 R2.Mungkinkah ini sesederhana yang berikut ini?
Mengingat taco_value selalu meningkat?
id Saya pemula SQL sendiri, namun, belajar dengan lambat tapi pasti.
sumber
Cannot perform an aggregate function on an expression containing an aggregate or a subquery