Pilih baris mulai dari nilai yang ditentukan hingga nilai yang ditentukan lainnya

8

Saya memiliki tabel yang berisi beberapa kolom dan ingin memeriksa nilai kolom, pilih baris setelah nilai kolom sampai nilai kolom terpisah muncul. Saya telah mencoba menggunakan BETWEEN, tetapi jika nilai kolom bilangan bulat itu hanya mencari angka antara bilangan bulat.

Misalnya, jika saya memiliki tabel seperti ini:

nilai waktu id 
t1 12:00 PM 15
t1 12:02 PM 4
t1 12:03 PM 7
t1 12:05 16
t5 12:10 PM 250
t5 12:15 PM 15
t8 11:00 15:00
t8 15:00 2
t8 15:05 100
t2 19:00 15
t2 19:01 16
t15 5:00 pagi 35 

Saya ingin mendapatkan baris antara nilai 15 dan 16. Pada dasarnya, jika saya bisa mengurutkan berdasarkan id, kemudian time, dan mengumpulkan baris setelah 15 muncul sampai ada nilai 16 di dalam yang sama id. Jika tidak ada nilai 16, saya ingin 100 baris berikutnya misalnya dan kemudian mencari nilai 15 berikutnya.

Saya ingin kueri mengembalikan ini:

nilai waktu id 
t1 12:00 PM 15
t1 12:02 PM 4
t1 12:03 PM 7
t1 12:05 16
t2 19:00 15
t2 19:01 16
t5 12:15 PM 15
t8 11:00 15:00
t8 15:00 2
t8 15:05 100

Itu mungkin membingungkan. Saya sudah mencoba:

SELECT * FROM table WHERE value BETWEEN '15' AND '16' ORDER BY id, time

sebagai titik awal, tetapi itu hanya mengembalikan baris dengan nilai 15 atau 16 karena mereka bilangan bulat.

Saya ingin menyortir meja idsaat itu time. Entri ini ditambahkan secara otomatis melalui sistem lain jadi saya mencoba untuk menanyakan tabel untuk rentang nilai tertentu.

Ada ide?

Klarifikasi:

Jika saya harus baris dengan 15, 1, 16, 7, 15, 2, 16yang sama id, saya ingin kedua "pulau": 15, 1, 16, 15, 2, 16.

Tautan
sumber
Bagaimana Anda ingin solusi menangani kasus di mana angka 15 ditemukan dan setelah beberapa nilai yang bukan 16, ada nilai 15 lainnya?
David Markovitz
@ DuduMarkovitz Setelah 100 nilai jika tidak ada nilai 16 ditemukan, saya ingin memulai dari 15 nilai berikutnya. Jika ada nilai lain 15 setelah kurang dari 100 nilai, itu harus mulai lagi. Untuk tujuan saya, ini seharusnya jarang terjadi sama sekali. Ini adalah pertanyaan yang valid.
Tautan
Terima kasih. untungnya ini adalah cara yang sudah ditangani oleh solusi saat ini.
David דודו Markovitz

Jawaban:

7

Saran yang seharusnya berfungsi dalam versi 2008.

Diuji di rextester.com :

with 
  end_points as                       -- find start and end points
    ( select id, time, value
      from table_x
      where value in (15, 16)
    ), 
  start_points as                     -- only the start points
    ( select id, time, value
      from end_points
      where value = 15
    )
select 
    t.id, t.time, t.value
from
    start_points as s
  outer apply                         -- find where each island ends
    ( select top (1) ep.* 
      from end_points as ep
      where s.id   = ep.id
        and s.time < ep.time
      order by ep.time
    ) as e
  cross apply                         -- and run through each island
    ( select p.id, p.time, p.value, 
             rn = row_number() over (order by p.time) 
      from table_x as p
      where s.id   = p.id
        and s.time <= p.time
        and         ( p.time < e.time
                   or p.time = e.time and e.value = 16
                   or          e.time is null)
    ) as t
where 
    t.rn <= 100
order by
    t.id, t.time  ;

Info lebih lanjut:

ypercubeᵀᴹ
sumber
1
select id,time,value

from   (select  *
               ,min (case when value = 16 then rn end) over 
                (
                    partition by    id,grp_id
                ) as min_rn_16

        from   (select  *
                       ,row_number () over 
                        (
                            partition by    id,grp_id 
                            order by        time
                        ) as rn

                from   (select      *
                                   ,count (case when value = 15 then 1 end) over 
                                    (
                                        partition by    id 
                                        order by        time 
                                        rows            unbounded preceding
                                    ) as grp_id

                        from        mytab
                        ) t

                where   grp_id > 0
                ) t

        where   rn <= 100
        ) t

where   rn <= coalesce (min_rn_16,100)
David Markודו Markovitz
sumber
2
Ini dalam versi 2008. Tidak COUNT(*) OVER (ORDER BY ..)diizinkan
ypercubeᵀᴹ
Terlihat hebat dan membuat saya sadar bahwa saya perlu membaca sedikit lebih banyak untuk memahami apa semua ini. Terima kasih atas masukannya.
Hubungkan