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

Développement SQL Server Discussion :

tranformer des quantités en lignes


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Profil pro
    Retraité
    Inscrit en
    Avril 2004
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2004
    Messages : 74
    Points : 69
    Points
    69
    Par défaut tranformer des quantités en lignes
    Bonjour,

    J'ai un fichier d'articles dont une des colonnes correspond à la quantité d'articles.
    Est-il possible et comment procéder pour obtenir une vue qui me duplique les articles en fonction de leur quantité respective par une requête SQL ?
    (l'objectif est d'éditer des étiquettes.)

    Merci.
    j'aimerai savoir ...

  2. #2
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Pour l'avoir déja fait ... il vous faut une table de nombre supplémentaire pour réaliser cela.

    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
    -- Table des nombres
    CREATE TABLE number
    (
     idNumber INT PRIMARY KEY
    );
     
    -- Remplissage table des nombres
    DECLARE @i INT = 1;
     
    WHILE @i < 10000
    BEGIN
     INSERT number VALUES (@i);
     
     SET @i += 1;
    END
     
    -- Table des articles
    CREATE TABLE article
    (
     code_article INT,
     description VARCHAR(50),
     qte INT
    );
     
    INSERT article VALUES (1, 'article1', 4);
    INSERT article VALUES (2, 'article2', 3);
     
    -- Duplication des lignes
    SELECT A.*
    FROM article AS A
    INNER JOIN number AS NB
     ON NB.idNumber <= A.qte
    ++

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    à partir de la version 2005, avec une CTE recursive :

    Code SQL : 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
     
    ;WITH T AS( --jeu d'essai
    	SELECT 'Article A' AS Art, 3 as Qte
    	UNION ALL
    	SELECT 'Article B' , 5
    	UNION ALL
    	SELECT 'Article C', 2
    ),
    Res AS (
    	SELECT Art, Qte - 1 AS Qte
    	FROM T
    	WHERE Qte > 0
    	UNION ALL
    	SELECT Art, Qte - 1
    	FROM Res
    	WHERE Qte > 0
    )
    SELECT Art
    FROM Res
    ORDER BY Art

  4. #4
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Effectivement j'ai pensé à la méthode des CTE récursives mais je pense que si le nombre de lignes à traiter est important la méthode non récursive sera moins performante vu que l'on force un traitement ligne à ligne ... Après les performances ne sont pas forcément un problème dans ce contexte.

    A voir



    ++

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    oui c'est vrai.

    A tester en effet, l'idée étant d'avoir tout ça en une seule requête. mais un mix des deux serait :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    WITH Number(IdNumber) AS (
        SELECT MAX(Qte) 
        FROM Article
        UNION ALL
        SELECT IdNumber - 1
        FROM Number
        WHERE IdNumber > 1
    )
    SELECT A.*
    FROM article AS A
    INNER JOIN number AS NB
     ON NB.idNumber <= A.qte

    Niveau perf, ça doit commencer à être pas mal

  6. #6
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Citation Envoyé par mikedavem Voir le message
    Pour l'avoir déja fait ... il vous faut une table de nombre supplémentaire pour réaliser cela.
    Pour des raisons d'optimisation, Je propose de remplacer le code ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- Remplissage table des nombres
    DECLARE @i INT = 1;
     
    WHILE @i < 10000
    BEGIN
     INSERT number VALUES (@i);
     
     SET @i += 1;
    END
    ++
    Par celui-ci :

    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
    WITH NombreCTE(N)
    AS
    (
        SELECT 0
        UNION SELECT 1
        UNION SELECT 2
        UNION SELECT 3
        UNION SELECT 4
        UNION SELECT 5
        UNION SELECT 6
        UNION SELECT 7
        UNION SELECT 8
        UNION SELECT 9
    )
     
    insert into number
    SELECT 1000*M.N + 100*C.N + 10*D.N + U.N
    FROM NombreCTE U 
    				CROSS JOIN NombreCTE D
    				CROSS JOIN NombreCTE C
    				CROSS JOIN NombreCTE M
    WHERE 1000*M.N + 100*C.N + 10*D.N + U.N BETWEEN 1 AND 9999
    L'objectif est d'éviter les boucles et donc un gain de performances.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  7. #7
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Vous chipotez les gars là

    La table number ne sera générée qu'une seule fois ici et sera utilisée par la suite pour dupliquer les lignes de la table cible. C'est juste une table de travail.

    Mais tu as raison tant qu'à faire allons y jusqu'au bout :

    Je propose encore plus simple pour créer la table des nombres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT IDENTITY(INT, 1,1) AS number INTO dbo.numbers
    FROM master.dbo.spt_values
    CROSS JOIN master.sys.objects
    ++

  8. #8
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Mikedavem, j'applique juste la théorie de Goering :
    Il est mieux de faire de la pub sur les bonnes manières afin que tout le monde s'y habitue même s'ils vont le comprendre plus tard.

    Par exemple je ne connaissais pas ta méthode plutôt très simple.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  9. #9
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Personnellement je créerais la table de nombre et éviterez de faire des traitements répétitif inutile, qui plus est récursif...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  10. #10
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Au passage, CROSS JOIN, en terme de performances, c'est pas terrible ...

    @++

  11. #11
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Elsuket je t'ai rien d....................

    ++

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Points : 1 234
    Points
    1 234
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Au passage, CROSS JOIN, en terme de performances, c'est pas terrible ...

    @++
    Je pense le contraire donc quelle est votre réflexion ?
    Most Valued Pas mvp

  13. #13
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Personnellement je créerais la table de nombre et éviterez de faire des traitements répétitif inutile, qui plus est récursif...
    On peut même se passer de la table des nombres ET d'une CTE :


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT A.*
    FROM Article A
    CROSS APPLY (
        SELECT TOP(A.qte) NULL AS X
        FROM Article B --ou n'importe quelle table qui contient des lignes
        CROSS JOIN Article C -- au grand dam d'Elsuket mais uniquement necessaire si COUNT(*) FROM Article < MAX(Qte)
        CROSS JOIN Article D --uniquement necessaire si count(*) ² < MAX(Qte)
        CROSS JOIN Article E --uniquement necess.. ok j'arrete ;)
        CROSS JOIN Article F -- ceinture et bretelles
    ) Z

  14. #14
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Au passage, CROSS JOIN, en terme de performances, c'est pas terrible ...

    @++
    Tu sais bien que c'est discutable et que nous n'allons pas nous affronter pour cela.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  15. #15
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Points : 1 234
    Points
    1 234
    Par défaut
    Citation Envoyé par WOLO Laurent Voir le message
    Tu sais bien que c'est discutable et que nous n'allons pas nous affronter pour cela.
    Sans affrontement, je suis curieux de l'alternative (bonne ou moins bonne) qu'y voyait Elsuket.
    Most Valued Pas mvp

Discussions similaires

  1. tranformer des colonnes en lignes
    Par panpan75 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 01/07/2008, 11h10
  2. la moyen des champs sur ligne
    Par nah_wah dans le forum MS SQL Server
    Réponses: 13
    Dernier message: 04/08/2005, 11h45
  3. remplacer des sauts de ligne par '\n'
    Par Miksimus dans le forum Général Python
    Réponses: 5
    Dernier message: 18/07/2005, 10h01
  4. transformer des colonnes en lignes
    Par flonardi dans le forum Oracle
    Réponses: 13
    Dernier message: 28/10/2004, 12h43
  5. Zoom sur des vecteurs ou lignes
    Par mat.M dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 25/11/2002, 10h40

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