Saya memiliki beberapa tabel dengan angka seperti ini (statusnya GRATIS atau DITANDATANGANI)
status nomor id_set ----------------------- 1 000001 DITANDATANGANI 1 000002 GRATIS 1 000003 DITANDATANGANI 1 000004 GRATIS 1 000005 GRATIS 1 000006 DITANDATANGANI 1 000007 DITANDATANGANI 1 000008 GRATIS 1 000009 GRATIS 1 000010 GRATIS 1 000011 DITANDATANGANI 1 000012 DITANDATANGANI 1 000013 DITANDATANGANI 1 000014 GRATIS 1 000015 DITANDATANGANI
dan saya perlu menemukan angka berurutan "n", jadi untuk n = 3, kueri akan kembali
1 000008 GRATIS 1 000009 GRATIS 1 000010 GRATIS
Itu harus mengembalikan hanya kelompok pertama yang mungkin dari setiap id_set (pada kenyataannya, itu akan dieksekusi hanya untuk id_set per permintaan)
Saya sedang memeriksa fungsi WINDOW, mencoba beberapa pertanyaan seperti COUNT(id_number) OVER (PARTITION BY id_set ROWS UNBOUNDED PRECEDING)
, tapi hanya itu yang saya dapat :) Saya tidak bisa memikirkan logika, bagaimana melakukannya di Postgres.
Saya sedang berpikir tentang membuat kolom virtual menggunakan fungsi WINDOW menghitung baris sebelumnya untuk setiap nomor di mana status = 'GRATIS', lalu pilih angka pertama, di mana jumlah sama dengan nomor "n" saya.
Atau mungkin mengelompokkan nomor berdasarkan status, tetapi hanya dari satu yang DITANDATANGANI ke yang lain DITANDATANGANI dan pilih hanya grup yang mengandung setidaknya "n" angka
EDIT
Saya menemukan pertanyaan ini (dan mengubahnya sedikit)
WITH q AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY id_set, status ORDER BY number) AS rnd,
ROW_NUMBER() OVER (PARTITION BY id_set ORDER BY number) AS rn
FROM numbers
)
SELECT id_set,
MIN(number) AS first_number,
MAX(number) AS last_number,
status,
COUNT(number) AS numbers_count
FROM q
GROUP BY id_set,
rnd - rn,
status
ORDER BY
first_number
yang menghasilkan grup angka GRATIS / TANDA TANGAN, tetapi saya ingin memiliki semua angka dari hanya grup pertama yang memenuhi persyaratan
id_set
atau hanya satu? Harap perbarui pertanyaan Anda jika ini dimaksudkan sebagai bagian dari awal. (Agar orang lain dapat melihat persyaratan lengkap dan menawarkan saran mereka atau memperbarui jawaban mereka.)Varian sederhana dan cepat :
Membutuhkan urutan angka tanpa celah di
number
(seperti yang disediakan dalam pertanyaan).Bekerja untuk sejumlah nilai yang mungkin di
status
samping'FREE'
, bahkan denganNULL
.Fitur utama adalah untuk mengurangi
row_number()
darinumber
setelah menghilangkan non-kualifikasi baris. Nomor yang berurutan berakhir dengan angka yang samagrp
- dangrp
juga dijamin dalam urutan menaik .Kemudian Anda dapat
GROUP BY grp
dan menghitung anggota. Karena Anda tampaknya menginginkan kejadian pertama ,ORDER BY grp LIMIT 1
dan Anda mendapatkan posisi awal dan panjang urutan (bisa> = n ).Set baris
Untuk mendapatkan satu set angka yang sebenarnya, jangan mencari di tabel lain waktu. Jauh lebih murah dengan
generate_series()
:Jika Anda benar-benar menginginkan string dengan nol di depan seperti yang Anda tampilkan di nilai contoh Anda, gunakan
to_char()
denganFM
pengubah (mode isi):SQL Fiddle dengan test case yang diperluas dan kedua query.
Jawaban yang terkait erat:
sumber
Ini adalah cara yang cukup umum untuk melakukan ini.
Ingatlah bahwa itu tergantung pada
number
kolom Anda berturut-turut. Jika itu bukan fungsi Window dan / atau tipe-solusi CTE mungkin akan diperlukan:sumber
M.number-consec+1
(misalnya untuk 10 itu harus10-3+1=8
).number
bidang itu. Panggilan bagus pada matematika saya akan memperbaikinya.EXISTS
bisa disederhanakan. Karena kita hanya perlu memastikan setiap n baris sebelumnya ada, kita bisa dropAND status = 'FREE'
. Dan saya akan mengubah kondisi di 2EXISTS
untukstatus <> 'FREE'
mengeras itu terhadap pilihan ditambahkan di masa depan.Ini akan mengembalikan hanya yang pertama dari 3 angka. Itu tidak mengharuskan nilai-nilai
number
berturut-turut. Diuji di SQL-Fiddle :Dan ini akan menampilkan semua angka (di mana ada 3
'FREE'
posisi berturut-turut atau lebih ):sumber
Dalam hal ini 5 angka berurutan - oleh karena itu perbedaannya harus 4 atau dengan kata lain
count(r3.number) = n
danr2.number = r1.number + n - 1
.Dengan bergabung:
sumber
JOIN
sintaksis modern ?sumber
{ }
tombol pada editor. Nikmati!