1
votes

MySQL sélectionne une plage d'entiers groupés

J'ai stocké dans une base de données certains numéros de clients, l'adresse IP attribuée, le routerIP, le vlan et la zone

 from  |    to   |     router     |   zone   |  vlan
-----------------------------------------------------
16090  |  16095  |  10.10.10.25   |     1    |   103   |

J'ai besoin de présenter les numéros de clients déjà utilisés regroupés par routeur , zone et vlan pour obtenir quelque chose comme ceci:

 from  |    to   |     router     |   zone   |  vlan
--------------------------------------------------------
16090  |  16093  |  10.10.10.25   |     1    |   103   |
16095  |  16095  |  10.10.10.25   |     1    |   103   |

les numéros de client sont uniques, en ce moment Ma requête est quelque chose comme ceci:

SELECT
    MIN( no ) AS start_no,
    MAX( no ) AS end_no,
    router,
    idZone,
    vlan
FROM
    address
GROUP BY
    router,
    idZone,
    vlan 


3 commentaires

Ah, un problème de lacunes et d'îles assez standard


Quelle version de mysql utilisez-vous? Parce que si vous regardez ce db <> fiddle , vous verrez que votre requête renvoie les données exactes que vous vouliez


@IgorIlic Non, cela ne donne pas les données qu'il veut.


3 Réponses :


-1
votes

Votre requête est correcte, mais il peut y avoir un espace vide dans l'un des champs du pivot, ce qui rend le regroupement difficile. Par exemple, l'une des colonnes pivot de la clause group by, disons que router pourrait être "10.10.10.25" ou "10.10.10.25". Essayez donc de couper les espaces.

SELECT
    MIN( no ) AS `from`,
    MAX( no ) AS `to`,
    trim(router) router,
    trim(idZone) zone,
    trim(vlan) vlan
FROM
    address
GROUP BY
    trim(router),
    trim(idZone),
    trim(vlan);


0 commentaires

1
votes

La requête suivante devrait fonctionner pour tous les scénarios:

(SELECT
    MIN( no ) AS start_no,
    MAX( no ) AS end_no,
    router,
    idZone,
    vlan
FROM
    address a1
    where exists (SELECT a2.no FROM address a2 WHERE a2.no = a1.no + 1) or
          exists (SELECT a2.no FROM address a2 WHERE a2.no = a1.no - 1)
GROUP BY
    router,
    idZone,
    vlan 
)
union
(select no as_no, no as end_no, router,idzone,vlan
from address a1
where not exists (SELECT a2.no FROM address a2 WHERE a2.no = a1.no + 1) and
      not exists (SELECT a2.no FROM address a2 WHERE a2.no = a1.no - 1)
GROUP BY
    router,
    idZone,
    vlan 
 )
   ORDER BY vlan

DEMO

La partie de la requête avant union retournera tous les groupes qui ont un client no continu et l'autre partie de la requête renverra les autres groupes uniques.


0 commentaires

0
votes

Vous pouvez commencer ici:

SELECT no
     , CASE WHEN no = @prev+1 THEN @i:=@i ELSE @i:=@i+1 END i
     , @prev := no
  FROM my_table
     , (SELECT @prev:=null, @i:=0) vars
 ORDER
    BY no;


0 commentaires