Eu tenho essa coluna de entradas que representam a ocorrência de um sinal e estou tentando adicionar uma coluna que mostra a contagem de linhas consecutivas
Se meus dados forem assim
724
727
728
733
735
737
743
747
749
os dados resultantes com uma coluna consecutiva de contagem de linhas ficariam assim
724 1
727 1
728 2
729 3
735 1
737 1
743 1
744 2
748 1
Eu fiz isso usando uma função de loop, mas estou tentando descobrir usando um cte. Aqui está uma amostra da minha última tentativa
DECLARE @d TABLE ( signal INT )
INSERT INTO @d
SELECT 724
UNION
SELECT 727
UNION
SELECT 728
UNION
SELECT 729
UNION
SELECT 735
UNION
SELECT 737
UNION
SELECT 743
UNION
SELECT 744
UNION
SELECT 748 ;
WITH a AS ( SELECT signal,
ROW_NUMBER() OVER ( ORDER BY signal ) AS marker
FROM @d
) ,
b AS ( SELECT a1.signal,
CASE ( a1.signal - a2.signal )
WHEN 1 THEN 1
ELSE 0
END consecutiveMarker
FROM a a1
INNER JOIN a a2 ON a2.marker = a1.marker - 1
)
SELECT *
FROM b
Produz esses resultados
signal consecutiveMarker
727 0
728 1
729 1
735 0
737 0
743 0
744 1
748 0
A primeira questão óbvia está faltando o primeiro sinal de uma série. Exceto isso, pensei que poderia passar isso para outro cte com um particionamento row_number no consecutivoMarker. Isso não funcionou porque o particionou como uma partição. Não consegui encontrar uma maneira de indicar ao método de particionamento que uma série é separada da próxima
Qualquer ajuda é apreciada.
fonte
Respostas:
O nome geral para esse tipo de consulta é "lacunas e ilhas". Uma abordagem abaixo. Se você puder ter duplicatas nos dados de origem, poderá precisar, em
dense_rank
vez derow_number
Devoluções
fonte
No SQL 2012, você também pode fazer isso usando o LAG e as funções da janela, por exemplo
fonte
Como de costume com esses problemas, é muito fácil realizar em Java ou C ++ ou C #.
Se você realmente precisar fazer isso no banco de dados, poderá usar um RDBMS com cursores rápidos, como Oracle, escrever um cursor simples e desfrutar de um desempenho rápido sem precisar escrever nada complexo.
Se você precisa fazer isso no T-SQL e não pode alterar o design do banco de dados, Itzik Ben-Gan escreveu várias soluções no "MVP Deep Dives vol 1" e algumas novas soluções usando as funções OLAP em seu novo livro sobre funções de janela no SQL 2012.
Como alternativa, você pode adicionar outra coluna consecutiveMarker à sua tabela e armazenar valores pré-calculados nela. Podemos usar restrições para garantir que os dados pré-calculados sejam sempre válidos. Se alguém estiver interessado, eu posso explicar como.
fonte