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 :

Appareillage de tables et comparaison


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 48
    Points : 30
    Points
    30
    Par défaut Appareillage de tables et comparaison
    j'ai trois tables
    tbl_ReferenceCapacity
    RCCycleName
    RCBD
    RCStep
    RCSite
    RCAsset

    RCQuantity

    La clé unique est composé des 5 premiers champs

    tbl_SommeCapacityIncrements

    CICycleName
    CIBD
    CIStep
    CISite
    CIAsset
    CIYear
    CIQuantity
    La clé unique est composée des 6premiers champs (l'année en plus)

    tbl_StandStills
    STCycleName
    STBD
    STStep
    STSite
    STAsset
    STQuantity
    La clé unique est composée des 6premiers champs (l'année en plus)

    les deux tables qui comprennent l'année peuvent toutes deux avoir la même année ou bien l'une peut avoir une année et pas l'autre et vice versa

    le résultat attendu est d'avoir une table (ou un formulaire) avec tous les enregistrement de tbl_ReferenceCapacity et le resultat du calcul
    RCQuantity = RCQuantity + Quantity SommeCapacityIncrements d'une année - Quantity SommeCapacityStandstills
    Si pas d'enregistrement année ni pour une table ni pour l'autre donc pas de changement et année en "blanc" sinon résultat du calcul pour l'année considérée.

    Comment pourrait on faire cela ? j'ai bien pensé aux requêtes union mais je séche, une petite piste svp

  2. #2
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Hmm, a mon avis, le faire avec des UNION est bien la seule méthode, mais vue le nombre de combinatoire, c'est pas forcément évident...

    Petite question pour bien être sur de ce qu'il faut faire :

    J'ai bien compris que je pouvais avoir une ligne pour une année dans tbl_StandStills et pas dans tbl_SommeCapacityIncrements et inversement.
    Par contre, est ce que je peux avoir dans tbl_SommeCapacityIncrements une ligne pour une année, et aussi une ligne sans année ?
    J'entends par là : est ce que votre année peut etre null ?

    (la question sousjacente est : quel est votre SGBD?, car certain SGBD acceptent une clef composée de valeure nulle, et d'autre non.)

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    la table standstills et la table capacityincrements peuvent avoir la même année
    la table standstills peut avoir des années qui ne sont pas dans la table capacityincrements
    la table capacityincrements peut avoir des années qui ne sont pas dans la table standstills
    Les trois cas peuvent donc exister.
    J'utilise Access
    je continue à chercher de mon côté, tuto et essais, mais toute aide est la bienvenue.
    Merci

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Euh...

    Pour moi, il suffit de faire deux bêtes jointures ouvertes. Avec quelques COALESCE, et le tour est joué !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select rc.RCCycleName, rc.RCBD, rc.RCStep, rc.RCSite, rc.RCAsset, coalesce(ci.CIYear, st.STYear) Year, rc.RCQuantity, rc.RCQuantity + coalesce(ci.CIQuantity, 0) - coalesce(st.STQuantity, 0) qty
    from  tbl_ReferenceCapacity rc
    left outer join tbl_SommeCapacityIncrements ci on ci.CICycleName = rc.RCCycleName and ci.CIBD = rc.RCBD and ci.CIStep = rc.RCStep and ci.CISite = rc.RCSite and ci.CIAsset = rc.RCAsset
    left outer join tbl_StandStills st on st.STCycleName = rc.RCCycleName and st.STBD = rc.RCBD and st.STStep = rc.RCStep and st.STSite = rc.RCSite and st.STAsset = rc.RCAsset
    where coalesce(st.STYear, ci.CIYear) = coalesce(ci.CIYear, st.STYear) or (st.STYear is null and ci.CIYear is null)

    J'ai un léger doute sur le WHERE ceci dit...
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    COALESCE() sous Access, ça s'appelle peut-être ISNULL()
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Pour moi, il suffit de faire deux bêtes jointures ouvertes. Avec quelques COALESCE, et le tour est joué !


    Ca ne fonctionnera pas je pense...
    si vous avez 2014 d'un coté et 2013 de l'autre, ca va tester l'égalité car aucun n'est null et donc ca ne fera aucune des jointures.


    Voici une facon de le faire avec des unions :

    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
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		ci.CIYear	AS	Year, 
    		rc.RCQuantity, 
    		rc.RCQuantity + ci.CIQuantity	AS	qty
    from  tbl_ReferenceCapacity rc
    inner join tbl_SommeCapacityIncrements ci	on ci.CICycleName = rc.RCCycleName 
    											and ci.CIBD = rc.RCBD 
    											and ci.CIStep = rc.RCStep 
    											and ci.CISite = rc.RCSite 
    											and ci.CIAsset = rc.RCAsset
    AND NOT EXISTS	(	SELECT 1
    					FROM	tbl_StandStills st
    					WHERE	st.STCycleName = rc.RCCycleName 
    					and st.STBD = rc.RCBD 
    					and st.STStep = rc.RCStep 
    					and st.STSite = rc.RCSite 
    					and st.STAsset = rc.RCAsset
    					AND ci.CIYear = st.STYear
    				)
     
    UNION ALL
     
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		st.STYear	AS	Year, 
    		rc.RCQuantity, 
    		rc.RCQuantity - st.STQuantity	AS	qty
    from  tbl_ReferenceCapacity rc
    inner join tbl_StandStills st	on st.STCycleName = rc.RCCycleName 
    								and st.STBD = rc.RCBD 
    								and st.STStep = rc.RCStep 
    								and st.STSite = rc.RCSite 
    								and st.STAsset = rc.RCAsset
    AND NOT EXISTS	(	SELECT 1
    					FROM	tbl_SommeCapacityIncrements ci
    					WHERE	ci.CICycleName = rc.RCCycleName 
    					and ci.CIBD = rc.RCBD 
    					and ci.CIStep = rc.RCStep 
    					and ci.CISite = rc.RCSite 
    					and ci.CIAsset = rc.RCAsset
    					AND ci.CIYear = st.STYear
    				)
     
    UNION ALL
     
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		st.STYear	AS	Year, 
    		rc.RCQuantity, 
    		rc.RCQuantity + ci.CIQuantity - st.STQuantity	AS	qty
    from  tbl_ReferenceCapacity rc
    inner join tbl_StandStills st	on st.STCycleName = rc.RCCycleName 
    								and st.STBD = rc.RCBD 
    								and st.STStep = rc.RCStep 
    								and st.STSite = rc.RCSite 
    								and st.STAsset = rc.RCAsset
    inner join tbl_SommeCapacityIncrements ci	on ci.CICycleName = rc.RCCycleName 
    											and ci.CIBD = rc.RCBD 
    											and ci.CIStep = rc.RCStep 
    											and ci.CISite = rc.RCSite 
    											and ci.CIAsset = rc.RCAsset
    WHERE ci.CIYear = st.STYear
     
    UNION ALL
     
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		null	AS	Year, 
    		rc.RCQuantity, 
    		rc.RCQuantity 	AS	qty
    from  tbl_ReferenceCapacity rc
    WHERE NOT EXISTS	(	SELECT 1
    						FROM	tbl_StandStills st
    						WHERE	st.STCycleName = rc.RCCycleName 
    						and st.STBD = rc.RCBD 
    						and st.STStep = rc.RCStep 
    						and st.STSite = rc.RCSite 
    						and st.STAsset = rc.RCAsset
    					)
    AND NOT EXISTS	(	SELECT 1
    					FROM	tbl_SommeCapacityIncrements ci
    					WHERE	ci.CICycleName = rc.RCCycleName 
    					and ci.CIBD = rc.RCBD 
    					and ci.CIStep = rc.RCStep 
    					and ci.CISite = rc.RCSite 
    					and ci.CIAsset = rc.RCAsset
    				)
    ;

    Et une autre facon de le faire, plus astucieuse je trouve ^^ mais pas forcément ce qui est attendu car ca affiche toute les anées :

    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
    select  RCCycleName,
           RCBD, 
           RCStep, 
           RCSite, 
           RCAsset, 
           RCYear,
           sum(QTY)
    FROM (
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		RCYear, 
    		rc.RCQuantity as QTY
    from  tbl_ReferenceCapacity rc
    cross join	(	select ci.CIYear as RCYear from tbl_SommeCapacityIncrements ci
    				UNION
    				SELECT st.STYear as RCYear from tbl_StandStills st
    			)
    UNION ALL 
     
    SELECT	st.STCycleName 	AS RCCycleName, 
    		st.STBD       	AS RCBD, 
    		st.STStep     	AS RCStep, 
    		st.STSite     	AS RCSite, 
    		st.STAsset    	AS RCAsset, 
    		st.STYear		AS RCYear,
    		-1 * st.STQuantity as QTY
    from tbl_StandStills st
     
    UNION ALL
     
    SELECT	ci.CICycleName AS RCCycleName,
    		ci.CIBD       AS RCBD, 
    		ci.CIStep     AS RCStep, 
    		ci.CISite     AS RCSite, 
    		ci.CIAsset    AS RCAsset, 
    		ci.CIYear     AS RCYear,
    		ci.CIQuantity as QTY
    FROM	tbl_SommeCapacityIncrements ci
     
    ) 
    group by RCCycleName,
           RCBD, 
           RCStep, 
           RCSite, 
           RCAsset, 
           RCYear
    ;

    Et le même que précédement mais avec des jointures plutot qu'un group by


    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
    select	rc.RCCycleName, 
    		rc.RCBD, 
    		rc.RCStep, 
    		rc.RCSite, 
    		rc.RCAsset, 
    		RCYear, 
    		rc.RCQuantity + ci.CIQuantity - st.STQuantity as QTY
    from  tbl_ReferenceCapacity rc
    cross join	(	select ci.CIYear as RCYear from tbl_SommeCapacityIncrements ci
    				UNION
    				SELECT st.STYear as RCYear from tbl_StandStills st
    			)
    left outer join tbl_StandStills st on st.STCycleName = rc.RCCycleName 
    								and st.STBD = rc.RCBD 
    								and st.STStep = rc.RCStep 
    								and st.STSite = rc.RCSite 
    								and st.STAsset = rc.RCAsset
    								AND RCYear = st.STYear
    left outer join tbl_SommeCapacityIncrements ci on ci.CICycleName = rc.RCCycleName 
    											and ci.CIBD = rc.RCBD 
    											and ci.CIStep = rc.RCStep 
    											and ci.CISite = rc.RCSite 
    											and ci.CIAsset = rc.RCAsset
    											AND RCYear = ci.CIYear

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    Bonjour et merci à tous ceux qui m'ont répondu.
    Tout d'abord je me suis débrouillé seul en faisiant une bête requête union et ensuite une requête regroupement avec une somme (j'ai préalablement multiplié par moins 1 la valeur à soustraire) et puis une jointure avec ReferenceCapacity.
    Ok c'est moins beau mais j'étais pressé.
    Vous m'avez appris beaucoup.
    je ne connaissais pas coalesce je vais tester cela dès que j'ai un moment mais en effet je ne pense pas que ça marche dans mon cas.
    Je vais regarder ce qu'a écrit bstevy cela a l'air plus joli que ce que j'ai fait.

  8. #8
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par cobaye13 Voir le message
    une bête requête union et ensuite une requête regroupement avec une somme (j'ai préalablement multiplié par moins 1 la valeur à soustraire) et puis une jointure avec ReferenceCapacity.
    Votre solution à l'air très bien.

    A mon avis, vous n'avez pas besoin de vous plonger dans mes requetes.
    Il y a plein de facon de traiter un cas en général, j'en ai cité 3, vous en avez cité une 4 eme, il en existe sans doute d'autre. Et je pense que votre facon de faire est très élégante

    Le seul cas où vous auriez à vous penchez sur une de mes requête, c'est si vous avez des problèmes de perf : une autre écriture peut parfois résoudre bien des problèmes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Script PHP + Table MySQL (comparaison de date)
    Par laztog dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 16/06/2014, 17h22
  2. Table de comparaison
    Par MaitrePylos dans le forum Développement de jobs
    Réponses: 2
    Dernier message: 02/10/2013, 17h04
  3. Comparaison Table Excel table Mssql
    Par k-lendos dans le forum MS SQL Server
    Réponses: 16
    Dernier message: 01/06/2005, 14h56
  4. comparaison entre 2 tables
    Par halina dans le forum Requêtes
    Réponses: 10
    Dernier message: 13/05/2005, 15h18
  5. comparaison de tables
    Par amelie15 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 14/04/2005, 10h37

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