Pregunta

Tengo una tabla de pedidos que mantiene todos los pedidos de todas nuestras tiendas. Escribí una consulta para verificar las órdenes de secuencia para cada tienda. Se parece a eso.

select WebStoreID, min(webordernumber), max(webordernumber), count(webordernumber) 
from orders
where ordertype = 'WEB' 
group by WebStoreID

Puedo verificar que todas las órdenes están presentes con esta consulta. El número de pedido web es el número de 1 ... n.

¿Cómo puedo escribir una consulta para encontrar pedidos faltantes sin unirme a una tabla temporal / diferente?

¿Fue útil?

Solución

Puedes unirte a la tabla en sí misma para detectar filas que no tienen una fila anterior:

select cur.*
from orders cur
left join orders prev 
    on cur.webordernumber = prev.webordernumber + 1
    and cur.webstoreid = prev.webstoreid
where cur.webordernumber <> 1
and prev.webordernumer is null

Esto detectaría huecos en la secuencia 1 ... n, pero no detectaría duplicados.

Otros consejos

Haría una tabla auxiliar de " todos los enteros de 1 a n " (consulte http://www.sql-server-helper.com/ functions / integer-table.aspx para algunas formas de hacerlo con una función de SQL Server, pero como es algo que necesitarás una y otra vez, lo convertiré en una tabla real de todos modos, y con cualquier motor SQL es fácil de hacer eso, solo una vez) luego use una consulta anidada, SELECCIONE el valor DE los enteros CUANDO el valor NO ESTÁ (SELECCIONE el número web DE las órdenes) & amp; c. También vea http://www.sqlmag.com/Article/ArticleID/99797/ sql_server_99797.html para un problema similar al suyo, " detectando huecos en una secuencia de números " ;.

Si tiene la función rank () pero no la función lag () (en otras palabras, SQL Server), puede usar esto (sugerido por http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / Return-gaps-in-a-sequence ):

create table test_gaps_in_sequence (x int)
insert into test_gaps_in_sequence values ( 1 )
insert into test_gaps_in_sequence values ( 2 )
insert into test_gaps_in_sequence values ( 4 )
insert into test_gaps_in_sequence values ( 5 )
insert into test_gaps_in_sequence values ( 8 )
insert into test_gaps_in_sequence values ( 9 )
insert into test_gaps_in_sequence values ( 12)
insert into test_gaps_in_sequence values ( 13)
insert into test_gaps_in_sequence values ( 14)
insert into test_gaps_in_sequence values ( 29)

...

 select lower_bound
         , upper_bound
      from (select upper_bound
                 , rank () over (order by upper_bound) - 1 as upper_rank
              from (SELECT x+n as upper_bound
                      from test_gaps_in_sequence
                         , (SELECT 0 n
                            UNION
                            SELECT -1
                           ) T
                     GROUP BY x+n
                    HAVING MAX(n) = -1
                    ) upper_1
            ) upper_2
         , (select lower_bound
                 , rank () over (order by lower_bound) as lower_rank
              from (SELECT x+n as lower_bound
                      from test_gaps_in_sequence
                         , (SELECT 0 n
                            UNION
                            SELECT 1
                           ) T
                     GROUP BY x+n
                    HAVING MIN(n) = 1
                    ) lower_1
            ) lower_2
      where upper_2.upper_rank = lower_2.lower_rank
      order by lower_bound

... o, para incluir los " límites externos " ;:

select lower_bound
     , upper_bound
  from (select upper_bound
             , rank () over (order by upper_bound) - 1 as upper_rank
          from (SELECT x+n as upper_bound
                  from test_gaps_in_sequence
                     , (SELECT 0 n
                        UNION
                        SELECT -1
                       ) T
                 GROUP BY x+n
                HAVING MAX(n) = -1
                ) upper_1
        ) upper_2
   full join (select lower_bound
             , rank () over (order by lower_bound) as lower_rank
          from (SELECT x+n as lower_bound
                  from test_gaps_in_sequence
                     , (SELECT 0 n
                        UNION
                        SELECT 1
                       ) T
                 GROUP BY x+n
                HAVING MIN(n) = 1
                ) lower_1
        ) lower_2
   on upper_2.upper_rank  = lower_2.lower_rank
     order by coalesce (lower_bound, upper_bound)

Si su base de datos admite funciones analíticas, podría utilizar una consulta similar a la siguiente:

select prev+1, curr-1 from
( select webordernumber curr,
         coalesce (lag(webordernumber) over (order by webordernumber), 0) prev
  from   orders
)
where prev != curr-1;

La salida mostrará las brechas, por ejemplo,

prev+1 curr-1
------ ------
     3      7

significaría que faltan los números 3 a 7 inclusive.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top