2017-03-27 12 views
-1

J'ai une table comme ceci:MS SQL 2012: trouver des séquences de nombres

WITH S AS (
    SELECT 'B' type, 1 number 
UNION SELECT 'B', 2 
UNION SELECT 'B', 3 
UNION SELECT 'B', 4 
UNION SELECT 'B', 5 
UNION SELECT 'A', 6 
UNION SELECT 'A', 7 
UNION SELECT 'B', 8 
UNION SELECT 'B', 9 
UNION SELECT 'B', 10 
UNION SELECT 'C', 11 
UNION SELECT 'A', 12 
UNION SELECT 'B', 13 
UNION SELECT 'B', 14 
UNION SELECT 'B', 15 
UNION SELECT 'B', 16 
UNION SELECT 'B', 17 
UNION SELECT 'A', 18 
UNION SELECT 'C', 19 
UNION SELECT 'B', 20 
UNION SELECT 'B', 21 
    ) 

Comment puis-je obtenir des séquences de nombres qui distinctives viennent dans une rangée (disons, 3 ou plus) pour chaque type? E.g. pour B 1 ~ 5, il y aura quelque chose comme 'B1', pour B 8 ~ 10 - 'B2' etc. Je suppose qu'il devrait y avoir quelque chose comme la combinaison de LEAD/LAG et DENSE_RANK(), mais ne peut pas comprendre comment appliquer. Les chiffres sont uniques, si cela compte.

Le résultat devrait ressembler à:

Type Number Sequence 
----------------------- 
B  1  B1 
B  2  B1 
B  3  B1 
B  4  B1 
B  5  B1 
A  6  NULL 
...................... 
B  8  B2 
B  9  B2 
B  10  B2 
C  11  NULL 
A  12  NULL 
B  13  B3 
.................... 
B  17  B3 
+2

Je ne comprends pas ce que vous essayez de faire ici. Pouvez-vous expliquer les exigences? –

Répondre

1

Une façon serait d'utiliser une combinaison de DENSE_RANK() et une différence de row numbers.

WITH S AS (
    SELECT 'B' type, 1 number 
UNION SELECT 'B', 2 
UNION SELECT 'B', 3 
UNION SELECT 'B', 4 
UNION SELECT 'B', 5 
UNION SELECT 'A', 6 
UNION SELECT 'A', 7 
UNION SELECT 'B', 8 
UNION SELECT 'B', 9 
UNION SELECT 'B', 10 
UNION SELECT 'C', 11 
UNION SELECT 'A', 12 
UNION SELECT 'B', 13 
UNION SELECT 'B', 14 
UNION SELECT 'B', 15 
UNION SELECT 'B', 16 
UNION SELECT 'B', 17 
UNION SELECT 'A', 18 
UNION SELECT 'C', 19 
UNION SELECT 'B', 20 
UNION SELECT 'B', 21 
    ) 
SELECT type, 
     number, 
     sequence = CASE 
      WHEN type = 'B' 
      THEN 'B' + CAST(DENSE_RANK() OVER (ORDER BY CASE WHEN type = 'B' THEN 0 ELSE 1 END, RN) AS VARCHAR(10)) 
      END 
FROM (
    SELECT *, RN = ROW_NUMBER() OVER (ORDER BY number) - ROW_NUMBER() OVER (PARTITION BY type ORDER BY number) 
    FROM S 
    ) AS T 
ORDER BY number; 
0

Il y avait une réponse, juste pour quelques minutes et il contenait la solution exactement que je veux (le reste, je peux comprendre):

SELECT type, R1 = min(number), R2 = max(number) FROM (
SELECT *, number - ROW_NUMBER() OVER (PARTITION BY type ORDER BY number) Grp From S 
) A 
GROUP BY type 

Impossible évaluer la réponse - il était déjà supprimé d'ici là. La solution consiste à trouver "Gaps and Islands" - maintenant je sais.