Verificando seqüência com consulta SQL
-
03-07-2019 - |
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?
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".
(), 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.