Pergunta

Eu tenho ordens de mesa que mantém toda a ordem de todas as nossas lojas. Eu escrevi uma consulta para verificar as ordens de sequência para cada loja. Parece que isso.

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

posso verificar que todos os pedidos estão presentes com esta consulta. web ORDERNUMBER é número de 1 ... n.

Como posso escrever consulta para encontrar ordens faltando sem aderir a tabela temporária / diferente?

Foi útil?

Solução

Você poderia juntar-se à mesa em si para detectar linhas que não têm linha 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

Este seria detectar as lacunas na 1 ... n seqüência, mas não seria detectar duplicatas.

Outras dicas

Gostaria de fazer uma tabela auxiliar de "todos os inteiros de 1 a n" (ver http://www.sql-server-helper.com/functions/integer-table.aspx para algumas maneiras de fazer isso com uma função de SQL Server, mas já que é algo que você vai precisar de mais e mais eu tinha que fazer isso em uma mesa real de qualquer maneira, e com qualquer motor de SQL é fácil fazer isso, apenas uma vez), em seguida, usar uma consulta aninhada, SELECT value FROM integers WHERE value NOT IN (SELECT webordernumber FROM orders) & c. Veja também http://www.sqlmag.com/Article/ArticleID/99797/ sql_server_99797.html para um problema semelhante ao seu, "detectar lacunas em uma sequência de números".

Se você tem o posto de função

(), mas não a função de atraso () (em outras palavras, SQL Server), você pode usar este (sugerido por http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming / 10594 / retorno lacunas-em-um-sequência ):

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

... ou, para incluir os "limites 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)

Se o seu banco de dados suporta funções analíticas seguida, você poderia usar um algo consulta como:

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

A saída mostrará as lacunas por exemplo.

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

significaria que os números de 3 a 7 inclusive estão faltando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top