Dada la siguiente tabla de ejemplo:

+-----------+
| Id | Name |  
+----+------+
| 1  | A    |
| 2  | B    |
| 3  | B    |
| 4  | C    |
| 5  | A    |
| 6  | B    |
| 7  | B    |
| 8  | B    |
| 9  | B    |
| 10 | X    |
+----+------+
 

Me gustaría una consulta para obtener el siguiente resultado:

+----+------+
| 6  | B    |
| 7  | B    |
| 8  | B    |
| 9  | B    |
+----+------+

La mejor consulta que pude hacer fue:

SELECT * FROM 
 (SELECT id, name, LEAD(id) OVER (ORDER BY id) t 
  FROM test WHERE name = 'B' ORDER BY id) 
WHERE ID <> t-1;

sqlfiddle aquí

1
dellasavia 29 jul. 2020 a las 22:10

1 respuesta

La mejor respuesta

Si quieres la longitud y dónde comienza:

select min(id), max(id)
from (select t.*,
             row_number() over (order by id) as seqnum,
             row_number() over (partition by name order by id) as seqnum_1
      from test t
     ) t
where name = 'B'
group by (seqnum - seqnum_1)
order by min(id) desc
fetch first 1 row only;

Puede volver a unirse a la tabla para obtener las filas originales.

Otro método que usa funciones de ventana para contar el número de no-B después de una fila determinada. . . y luego elige el primero:

select t.*
from (select t.*,
             dense_rank() over (order by nonbs_after asc) as grp
      from (select t.*, 
                   sum(case when name <> 'B' then 1 else 0 end) over (order by id desc) as nonbs_after
            from test t
           ) t
      where name = 'B'
     ) t
where grp = 1;

Aquí hay un violín <> db.

1
Gordon Linoff 29 jul. 2020 a las 20:56