IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Tri alphabetique dans une representation intervallaire


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 23
    Points : 19
    Points
    19
    Par défaut Tri alphabetique dans une representation intervallaire
    bonjour,

    J'ai un modele de donnée representant un arbre de categorie qui reprends le principe de representation intervallaire énoncé dans le cours http://sqlpro.developpez.com/cours/arborescence/.

    L'avantage de ce modele est la possibilité de recuperer les elements parents/enfant/etc très facilement.

    En revanche je n'arrive pas a trouver une solution pour pouvoir ordonner les libellés de mes categories par ordre alphabetique, et garder une disposition arborescente.

    Ma table categorie ressemble a ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CATEGORIE
    -----------
    BORNE_GAUCHE
    BORNE_DROITE
    LIBELLE
    NIVEAU
    Si je fait simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM CATEGORIE
    j'ai mon arbre complet, mais pas par ordre alphabetique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CategorieB
    ss-categorieA2
    ss-categorieA1
      ...
    CategorieA
    ss-categorieA1
    ss-categorieA2
      ...
    Un tri sur le libellé donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM CATEGORIE ORDER BY LIBELLE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CategorieA
    CategorieB
    ss-categorieA1
    ss-categorieA2
    ss-categorieB1
    ss-categorieB2
    Ce qui n'est pas du tout le resultat que je recherche.

    Je voudrai donc arriver a ce resultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CategorieA
      ss-categorieA1
      ss-categorieA2
      ...
    CategorieB
      ss-categorieB1
      ss-categorieB2
      ...
    Une idée?

    Merci d'avance

  2. #2
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    A mon avis pour que tu puisses les grouper par catégorie tu dois avoir une table catégorie et une table sous catégorie, si tes données sont dans la même table je doutes que tu puisses grouper.

    Table Catégorie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Categorie
    -----------
    1 | CategorieA
    2 | CategorieB
    Table ss_categorie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ss_categorie
    ------------
    1|ss_catea|1
    2|ss_cateb|1
    3|ss_catec|2
    4|ss_cated|2
    Là tu utilises GROUP BY, mais si ils sont dans la même table je doutes que sa fonctionne.

  3. #3
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Non il utilise une arborescence intervallaire ! Donc il n'a pas besoin de plusieurs tables. Il faut trier par borne gauche. Sinon regarder la vue à la fin, V_NOMENCLATURE_NMC, elle va vous aider à réaliser une présentation "plus propre".
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Alexandre T
    Je réfléchis à la solution, mais je crois qu'elle est notée dans le tutoriel, car j'ai eu le même problème pour mon site / annuaire.
    Je viens de relire rapidement le tutoriel, mais je n'ai rien vu qui peut répondre à mon probleme.

    Mais bon j'ai peut etre raté quelque chose je continue de chercher...

    merci

  5. #5
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    J'avais fait un multiposte. Et j'avais effacer le mauvais message... Regarde ci dessus
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Dans le tutoriel, la vue permet seulement de créer les indentations et de connaitre le nombre de descendants.

    Par contre pas la moindre piste pour un tri alphabetique. Et je n'arrive pas a réaliser une vue triée correctement.

    Avez vous une idée?

    merci.

  7. #7
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Avez-vous fait un tri par borne gauche ?
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Alexandre T
    Avez-vous fait un tri par borne gauche ?
    Non, pourquoi? Ce tri ne m'apporterai rien pour faire un tri sur le libellé?

  9. #9
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    J'aurais mieux fait de me taire en effet...
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 15
    Points : 13
    Points
    13
    Par défaut Gestion du tri dans une arborescence par intervalle
    Bonjour,

    Moi j'ai trouvé une solution adapté à mes contraintes. Je met à jour les bornegauche et bornedroite par l'intermédiaire d'un script en PHP et donc dans le script je trie sur le champ que je veux.
    Cette technique peut être utilisée si vous n'avez pas beaucoup de mise à jour de votre arborescence.

    Dans l'exemple si dessous j'utilise une borne gauche et la taille de l'élément. La borne droite est égale à borne gauche + taille. La fonction n'est pas optimisée et le nombre de requête est très important. Il dépend du nombre de niveau et du nombre d'élément dans l'arborescence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    //Mise a jour des themes (non optimise) :
    	function mise_a_jour_theme()
    	{
    	    //initialisation des variables globales:
    		global $langue;
     
    		//Creation d'une variable temporaire de classe theme :
    		require_once($_SERVER["DOCUMENT_ROOT"].dirname($_SERVER['PHP_SELF']).'/scripts/php/class.theme.php');
     
    		$vtemp=new theme();
     
    		//mise a jour du niveau des themes :
    		$update_niveaumin="UPDATE ".$vtemp->table." SET niveau=1 WHERE idtheme_rel=0";
    		$update_niveaumin=requete_sql($update_niveaumin);
    		$dernierniveau=1;
    		$select_niveau="SELECT T1.* FROM ".$vtemp->table." AS T1, ".$vtemp->table." AS T2 WHERE T2.niveau=$dernierniveau AND T1.idtheme_rel=T2.idtheme AND T1.langue='$langue' AND T2.langue='$langue';";
    		$select_niveau=requete_sql($select_niveau);
    		while(compte_sql($select_niveau)>0)
    		{
    			$vniveau=$dernierniveau+1;
    			$update_niveau="UPDATE ".$vtemp->table." SET niveau=$vniveau WHERE idtheme";
    			$update_niveau.=" IN (";
    	    	while($vtheme=tableau_sql($select_niveau))
    	    	{
    	    		$update_niveau.="'".$vtheme['idtheme']."',";
    	    	}
    	    	$update_niveau=substr($update_niveau,0,-1).")";
    			$update_niveau=requete_sql($update_niveau);
    			$dernierniveau=$dernierniveau+1;
    			$select_niveau="SELECT T1.* FROM ".$vtemp->table." AS T1, ".$vtemp->table." AS T2 WHERE T2.niveau=$dernierniveau AND T1.idtheme_rel=T2.idtheme AND T1.langue='$langue' AND T2.langue='$langue';";
    			$select_niveau=requete_sql($select_niveau);	
    		}
     
    		//2 boucles sur les niveaux pour mettre a jour la taille et la borne gauche:
    		$select_niveaumax="SELECT MAX(niveau) FROM ".$vtemp->table." WHERE visible=1 AND langue='$langue';";
    		$select_niveaumax=requete_sql($select_niveaumax);
    		$niveaumax=tableau_sql($select_niveaumax);
    		$niveaumax=$niveaumax[0];
    		//mise a jour de la taille des themes
    		for($i=$niveaumax;$i>0;$i--) 
    		{
    			$select_suivante="SELECT T2.".$vtemp->champ_identifiant.", SUM(T1.taille+1)+1 AS vtaille FROM ".$vtemp->table." AS T1 RIGHT JOIN ".$vtemp->table." AS T2 ON T1.".$vtemp->champ_identifiant."_rel=T2.".$vtemp->champ_identifiant." WHERE T2.niveau=$i AND T2.visible=1 AND T1.visible=1 AND T1.langue='$langue' AND T2.langue='$langue' GROUP BY T1.".$vtemp->champ_identifiant."_rel ORDER BY T1.titre ASC";
    			$select_suivante=requete_sql($select_suivante);
    			while($noeud=tableau_sql($select_suivante)) 
    			{
    				$update_taille="UPDATE $vtemp->table SET taille=".$noeud['vtaille']." WHERE $vtemp->champ_identifiant=".$noeud['idtheme'].";";
    				requete_sql($update_taille);
    			}
    		}
    		//mise a jour de la bornegauche des themes 
    		require_once($_SERVER["DOCUMENT_ROOT"].dirname($_SERVER['PHP_SELF']).'/scripts/php/class.regle.php');
     
    		$ordre_tri= new regle("0","tri_theme");
    		for($i=0;$i<$niveaumax+1;$i++) 
    		{
    			//mise a jour des racines de l'arborescence
    			if ($i==0)
    			{
    				$select_borne="SELECT T1.".$vtemp->champ_identifiant.", T1.taille, T2.bornegauche AS vborne, T2.idtheme AS vidtheme_pere FROM ".$vtemp->table." AS T1 LEFT JOIN ".$vtemp->table." AS T2 ON T1.".$vtemp->champ_identifiant."_rel=T2.".$vtemp->champ_identifiant." WHERE T2.niveau IS NULL AND T1.idtheme IS NOT NULL AND T1.visible=1 AND T1.langue='$langue' AND T2.langue='$langue' ORDER BY T1.idtheme_rel ASC, T1.$ordre_tri->valeur ASC";
    			}
    			//mise a jour des autres elements de l'arborescence
    			else
    			{
    				$select_borne="SELECT T1.".$vtemp->champ_identifiant.", T1.taille, T2.bornegauche AS vborne, T2.idtheme AS vidtheme_pere FROM ".$vtemp->table." AS T1 RIGHT JOIN ".$vtemp->table." AS T2 ON T1.".$vtemp->champ_identifiant."_rel=T2.".$vtemp->champ_identifiant." WHERE T2.niveau=$i AND T1.idtheme IS NOT NULL AND T2.visible=1 AND T1.visible=1 AND T1.langue='$langue' AND T2.langue='$langue' ORDER BY T1.idtheme_rel ASC, T1.$ordre_tri->valeur ASC";
    			}
    			$select_borne=requete_sql($select_borne);
    			$nombre_ligne=compte_sql($select_borne);
    			for($j=1;$j<=$nombre_ligne;$j++) 
    			{
    				$element=tableau_sql($select_borne);
    				//si l'on change de pere la borne se calcul par rapport a la borne du pere :
    				if ($element['vidtheme_pere']!=$pere_prec)
    				{
    					$borne_prec=$element['vborne']+1;
    					$update_borne="UPDATE $vtemp->table SET bornegauche=".$borne_prec." WHERE $vtemp->champ_identifiant=".$element['idtheme'].";";
    					$taille_prec=$element['taille'];
    					requete_sql($update_borne);
    					$pere_prec=$element['vidtheme_pere'];
    				}
    				//si l'on ne change pas de pere la borne se calcul par rapport a la derniere borne :
    				else
    				{
    					$borne_prec=$taille_prec+1+$borne_prec;
    					$update_borne="UPDATE $vtemp->table SET bornegauche=".$borne_prec." WHERE $vtemp->champ_identifiant=".$element['idtheme'].";";
    					$taille_prec=$element['taille'];
    					requete_sql($update_borne);
    					$pere_prec=$element['vidtheme_pere'];
    				}
    			}
    		}
    	}

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 115
    Points : 73
    Points
    73
    Par défaut Une autre solution...
    Ma solution ne nécessite pas de mises à jour de la base.
    Par contre elle utilise la récursivité.
    J'ai une nomenclature liée à des articles. Je veux trier par référence article un sous-ensemble. Je génère une requête triée par référence article et je recalcule les bords droits(BG) et gauches(BD).(sans modifier la base) Lorsque je rencontre un sous-ensemble je rappel la même procédure. (récursivité)
    Voici le code en firebird:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    COMMIT WORK;
    SET AUTODDL OFF;
    SET TERM ^ ;
     
    /* Stored procedures */
     
    CREATE PROCEDURE "SP_TREE_SORT_VIEW_ANM" 
    (
      "BG_SUIV" INTEGER,
      "BG_P" INTEGER,
      "BD_P" INTEGER,
      "NIVEAU_P" INTEGER,
      "RECURS" SMALLINT
    )
    RETURNS
    (
      "ID_S" INTEGER,
      "BG_S" INTEGER,
      "BD_S" INTEGER,
      "NIVEAU_S" INTEGER,
      "REF_ID_S" INTEGER,
      "QTE_S" DOUBLE PRECISION,
      "REF_ART_S" VARCHAR(32),
      "ANM_DATE_VALIDITE" TIMESTAMP
    )
    AS
    BEGIN EXIT; END ^
     
     
    ALTER PROCEDURE "SP_TREE_SORT_VIEW_ANM" 
    (
      "BG_SUIV" INTEGER,
      "BG_P" INTEGER,
      "BD_P" INTEGER,
      "NIVEAU_P" INTEGER,
      "RECURS" SMALLINT
    )
    RETURNS
    (
      "ID_S" INTEGER,
      "BG_S" INTEGER,
      "BD_S" INTEGER,
      "NIVEAU_S" INTEGER,
      "REF_ID_S" INTEGER,
      "QTE_S" DOUBLE PRECISION,
      "REF_ART_S" VARCHAR(32),
      "ANM_DATE_VALIDITE" TIMESTAMP
    )
    AS
    --declare variable BG_Suiv integer;
     declare variable BG integer;
     declare variable BD integer;
     declare variable Niveau integer;
    -- declare variable REF_ART varchar(32);
    -- declare variable BD_P integer;
    -- declare variable BG_P integer;
    -- declare variable Niveau_P integer;
     declare variable ID integer;
     declare BD_Suiv integer;
      declare Ecart  integer;
     declare Deplacement integer;
     declare REF_ID integer;
     declare Qte  double precision;
     declare Ref varchar(32);
    begin
     -- BG_Suiv=BG_P;
      for select ANM_ID,ANM_BG,ANM_BD,REF_ART,ANM_QTE,ANM_NIVEAU,ANM_REF_ID,ANM_DATE_VALIDITE
       from Art_Nomenclature  inner join Article on Article_ID=ANM_REF_ID
       where ANM_BD<:BD_P and ANM_BG>:BG_P and ANM_Niveau=:Niveau_P+1
       order by REF_ART
       into :ID,:BG,:BD,:REF,:QTE,:NIVEAU,:REF_ID,:ANM_DATE_VALIDITE
      do
       begin
          Ecart=BD-BG;
           BG_Suiv=BG_Suiv+1;
           Deplacement=BG-BG_Suiv;
           REF_ID_S= REF_ID;
           NIVEAU_S=NIVEAU;
           QTE_S=QTE;
           REF_ART_S=REF;
           BG_S=BG_SUIV;
           BD_Suiv=BG_Suiv+Ecart;
           BD_S=BD_SUIV;
           ID_S=ID;
           suspend;
              if (Ecart>1) then
              begin
                if (RECURS=1) then
                 for select ID_S,BG_S,BD_S,Niveau_S,REF_ID_S,QTE_S,REF_ART_S,:ANM_DATE_VALIDITE
                     from SP_TREE_SORT_VUE_ANM(:BG_SUIV,:BG,:BD,:NIVEAU_S,:RECURS)
                     into :ID_S,:BG_S,:BD_S,:Niveau_S,:REF_ID_S,:QTE_S,:REF_ART_S,:ANM_DATE_VALIDITE
                 do
                 begin
                  suspend;
                 end
              end --end Ecart>1
            BG_Suiv=BD_Suiv;
       end --end for
    end
     ^
     
    SET TERM ; ^
    COMMIT WORK;
    SET AUTODDL ON;

Discussions similaires

  1. Try/ catch dans une fonction ActionPerformed
    Par thomas2929 dans le forum Langage
    Réponses: 13
    Dernier message: 09/06/2008, 12h06
  2. Comment effectuer un tri alphabetique avec une macro
    Par alexistak dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 14/02/2008, 18h32
  3. Try catch dans une dll - possible ?
    Par Pendary dans le forum C++Builder
    Réponses: 1
    Dernier message: 02/03/2007, 16h48
  4. [Access] Tri limitatif dans une sélection
    Par fpouget dans le forum Langage SQL
    Réponses: 2
    Dernier message: 30/01/2007, 17h26
  5. [VBA-E]tri/sélection dans une feuille
    Par philpommé dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 20/04/2006, 20h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo