Lier plusieurs requêtes imbriquées entre elles
Résolu
emrh
Messages postés
427
Date d'inscription
Statut
Membre
Dernière intervention
-
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
emrh Messages postés 427 Date d'inscription Statut Membre Dernière intervention -
Bonjour à tous,
J'ai écrit plusieurs requêtes qui fonctionnent bien indépendamment les unes des autres et j'aimerai
savoir comment faire pour les regrouper en une seule ? ou si je dois lancer 3 commandes séparées en php ?
(Je n'ai pas les connaissances suffisantes pour les regrouper sans tout faire planter)
Les voici :
1. Récupération du client, de la date de début de son contrat, son N° de contrat et du total de ses prestations restauration :
2. Récupération du n° de contrat et du total des prestations dans le bâtiment 1
3. Récupération du n° de contrat et du total des prestations dans le bâtiment 2
4. Récupération du n° de contrat et du total des taxes de séjour TS sur batiment 1
Etc.... avec Taxe de séjour TS sur batiment 2...
Merci d'avance pour votre aide !
L'idée c'est de remplir ensuite à l'aide d'une boucle ce tableau :

J'ai écrit plusieurs requêtes qui fonctionnent bien indépendamment les unes des autres et j'aimerai
savoir comment faire pour les regrouper en une seule ? ou si je dois lancer 3 commandes séparées en php ?
(Je n'ai pas les connaissances suffisantes pour les regrouper sans tout faire planter)
Les voici :
1. Récupération du client, de la date de début de son contrat, son N° de contrat et du total de ses prestations restauration :
SELECT CLIENT,T.date_debut,T.id_contrat, SUM(T.TABLE_HOTES) FROM (SELECT contrats.id_contrat, contrats.date_debut,CONCAT(clients.nom,' ',clients.prenom) AS CLIENT, compositions.prix*compositions.quantites AS TABLE_HOTES FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type = 3)AS T GROUP BY T.id_contrat
2. Récupération du n° de contrat et du total des prestations dans le bâtiment 1
SELECT contrats.id_contrat, compositions.prix*compositions.quantites AS VILLAGE FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type = 1 GROUP BY contrats.id_contrat
3. Récupération du n° de contrat et du total des prestations dans le bâtiment 2
SELECT contrats.id_contrat, compositions.prix*compositions.quantites AS JARDIN FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type = 2 GROUP BY contrats.id_contrat
4. Récupération du n° de contrat et du total des taxes de séjour TS sur batiment 1
SELECT contrats.id_contrat, batiments.id_batiment,compositions.prix*compositions.quantites AS TS FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation INNER JOIN batiments ON batiments.id_batiment = contrats.id_batiment WHERE prestations.id_prestation = 21 AND batiments.id_batiment = 1 GROUP BY contrats.id_contrat
Etc.... avec Taxe de séjour TS sur batiment 2...
Merci d'avance pour votre aide !
L'idée c'est de remplir ensuite à l'aide d'une boucle ce tableau :

Configuration: Linux / Chrome 99.0.4844.84
A voir également:
- Lier plusieurs requêtes imbriquées entre elles
- Lier calendrier outlook et gmail - Guide
- Lier une adresse mail à gmail - Guide
- Comment lier des pdf - Guide
- Lier au précédent word - Forum Word
- Lier deux tableaux excel - Guide
14 réponses
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
et ainsi?
SELECT CLIENT,date_debut,id_contrat, SUM( IF (PRESTTYP=3, PRIX, 0 ) ) AS REPAS, SUM( IF (PRESTID=21 and BAT=1, PRIX, 0 ) ) AS TS1 FROM (SELECT contrats.id_contrat, contrats.date_debut, CONCAT(clients.nom,' ',clients.prenom) AS CLIENT, compositions.prix*compositions.quantites AS PRIX, prestations.type as PRESTTYP, batiments.id_batiment as BAT, prestations.id_prestation as PRESTID FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation INNER JOIN batiments ON batiments.id_batiment = contrats.id_batiment ) AS X GROUP BY CLIENT,date_debut,id_contrat
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
bonjour,
peux-tu, pour chaque colonne du tableau, indiquer de quel champ et de quel table il s'agit?
peux-tu, pour chaque colonne du tableau, indiquer de quel champ et de quel table il s'agit?
Bonjour yg_be,
Tu as raison, ce sera plus clair...
Colonne 'NOM' : Table clients, champs CONCAT(clients.nom,' ',clients.prenom) AS CLIENT
Colonne DATES : Table contrats, champs : contrats.date_debut
Colonne VILLAGE : Table compositions + prestations, champs compositions.prix*compositions.quantites AS VILLAGE WHERE prestations.type = 1
Colonne TS(1°) : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TS_VILLAGE WHERE prestations.id_prestation = 21 AND batiments.id_batiment = 1
Colonne JARDIN : Table compositions + prestations, champs compositions.prix*compositions.quantites AS JARDIN WHERE prestations.type = 2
Colonne TS(2°) : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TS_JARDIN WHERE
prestations.id_prestation = 21 AND batiments.id_batiment = 2
Colonne CHAMBRES : Table compositions + prestations, champs compositions.prix*compositions.quantites AS CHAMBRES WHERE prestations.type = 5
Colonne REPAS : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TABLE_HOTES WHERE prestations.type = 3
compositions

prestations

Tu as raison, ce sera plus clair...
Colonne 'NOM' : Table clients, champs CONCAT(clients.nom,' ',clients.prenom) AS CLIENT
Colonne DATES : Table contrats, champs : contrats.date_debut
Colonne VILLAGE : Table compositions + prestations, champs compositions.prix*compositions.quantites AS VILLAGE WHERE prestations.type = 1
Colonne TS(1°) : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TS_VILLAGE WHERE prestations.id_prestation = 21 AND batiments.id_batiment = 1
Colonne JARDIN : Table compositions + prestations, champs compositions.prix*compositions.quantites AS JARDIN WHERE prestations.type = 2
Colonne TS(2°) : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TS_JARDIN WHERE
prestations.id_prestation = 21 AND batiments.id_batiment = 2
Colonne CHAMBRES : Table compositions + prestations, champs compositions.prix*compositions.quantites AS CHAMBRES WHERE prestations.type = 5
Colonne REPAS : Table compositions + prestations, champs compositions.prix*compositions.quantites AS TABLE_HOTES WHERE prestations.type = 3
compositions

prestations

Je suis sur la bonne voie ? :
SELECT th.id_contrat,SUM(th.TABLE_HOTES) AS TH, SUM(v.VILLAGE) AS VILLAGE FROM (SELECT contrats.id_contrat, (compositions.prix*compositions.quantites) AS TABLE_HOTES FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type=3)th LEFT JOIN(SELECT compositions.id_contrat ,(compositions.prix*compositions.quantites) AS VILLAGE FROM compositions INNER JOIN prestations ON prestations.id_prestation=compositions.id_prestation WHERE prestations.type=1)v ON v.id_contrat=th.id_contrat GROUP BY th.id_contrat
peut-être:
SELECT CLIENT,date_debut,id_contrat, SUM( IF (PREST=3, PRIX, 0 ) ) AS TABLE_HOTE, SUM( IF (PREST=21 and BAT=1, PRIX, 0 ) ) AS TS1 FROM (SELECT contrats.id_contrat, contrats.date_debut, CONCAT(clients.nom,' ',clients.prenom) AS CLIENT, compositions.prix*compositions.quantites AS PRIX, prestations.type as PREST, batiments.id_batiment as BAT FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation INNER JOIN batiments ON batiments.id_batiment = contrats.id_batiment ) GROUP BY CLIENT,date_debut,id_contrat
La réponse de PhpMyAdmin à ta requête : #1248 - Every derived table must have its own alias
Cela dit, tu as raison sur un point, il faut que mon GROUPBY se fasse sur les clients et non pas sur les
id_contrat comme je l'ai fait !
EDIT : Après test, le tri sur client est impossible car on fait 3 contrats par client par weekend :
un par bâtiment puis un autre pour les prestations table d'hôtes
ça semble fonctionner :
Le contrat 85 a bien de l'hébergement ET une prestation repas

Cela dit, tu as raison sur un point, il faut que mon GROUPBY se fasse sur les clients et non pas sur les
id_contrat comme je l'ai fait !
EDIT : Après test, le tri sur client est impossible car on fait 3 contrats par client par weekend :
un par bâtiment puis un autre pour les prestations table d'hôtes
SELECT th.id_client,th.id_contrat,SUM(th.TABLE_HOTES) AS TH, SUM(v.VILLAGE) AS VILLAGE FROM (SELECT clients.id_client,contrats.id_contrat, (compositions.prix*compositions.quantites) AS TABLE_HOTES FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type=3)th LEFT JOIN(SELECT compositions.id_contrat ,(compositions.prix*compositions.quantites) AS VILLAGE FROM compositions INNER JOIN prestations ON prestations.id_prestation=compositions.id_prestation WHERE prestations.type=1)v ON v.id_contrat=th.id_contrat GROUP BY th.id_contrat ORDER BY th.id_client ASC
ça semble fonctionner :

Le contrat 85 a bien de l'hébergement ET une prestation repas

Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
Je me demande si les tables sont bien structurées. Je crains qu'une structure incorrecte des tables te conduise à faire des requêtes excessivement compliquées.
Je suis étonné par la présence d'un prix dans la table compositions. Je trouve cela suspect.
Je suis étonné par la présence d'un prix dans la table compositions. Je trouve cela suspect.
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
Quel logiciel de base de données utilises-tu?
J'administre mes tables avec phpmyadmin en hébergement chez Ionos...
Les prix par défaut des prestations sont stockés dans la table prestations ils sont ainsi proposés à la réalisation du contrat mais comme l'utilisateur les adapte selon le client facturé (cas de remises par exemple) ces prix sont stockés avec la prestation, sin descriptif, son prix et les quantités...
Les prix par défaut des prestations sont stockés dans la table prestations ils sont ainsi proposés à la réalisation du contrat mais comme l'utilisateur les adapte selon le client facturé (cas de remises par exemple) ces prix sont stockés avec la prestation, sin descriptif, son prix et les quantités...
Le tarif par défaut de la chambre est proposé (table prestations)

Le tarif de la chambre peut être modifié, et ce chiffre modifié sera stocké dans la table compositions

La table compositions

Au même titre qu'un descriptif par défaut est proposé avec la fiche de la prestation mais qui peut être modifié
(exemple pour les prestations repas, dont le menu peut être changé selon les arrivages du marché !)

Le tarif de la chambre peut être modifié, et ce chiffre modifié sera stocké dans la table compositions

La table compositions

Au même titre qu'un descriptif par défaut est proposé avec la fiche de la prestation mais qui peut être modifié
(exemple pour les prestations repas, dont le menu peut être changé selon les arrivages du marché !)
SELECT th.id_client,th.id_contrat,SUM(th.TABLE_HOTES) AS TH, SUM(v.VILLAGE) AS VILLAGE,SUM(j.JARDIN) AS JARDIN FROM (SELECT clients.id_client,contrats.id_contrat, (compositions.prix*compositions.quantites) AS TABLE_HOTES FROM compositions INNER JOIN contrats ON contrats.id_contrat = compositions.id_contrat INNER JOIN clients ON clients.id_client = contrats.id_client INNER JOIN prestations ON prestations.id_prestation = compositions.id_prestation WHERE prestations.type=3)th LEFT JOIN(SELECT compositions.id_contrat ,(compositions.prix*compositions.quantites) AS VILLAGE FROM compositions INNER JOIN prestations ON prestations.id_prestation=compositions.id_prestation WHERE prestations.type=1)v ON v.id_contrat=th.id_contrat LEFT JOIN(SELECT compositions.id_contrat ,(compositions.prix*compositions.quantites) AS JARDIN FROM compositions INNER JOIN prestations ON prestations.id_prestation=compositions.id_prestation WHERE prestations.type=2)j ON j.id_contrat=th.id_contrat GROUP BY th.id_contrat ORDER BY th.id_client ASC
Ça ne fonctionne plus !

Pour bien faire il faudrait qu'à la création d'un contrat on ne puisse pas saisir de prestations repas sur le même contrat (cf mon #11)...
Mais si un client prend un chambre pour une nuit + une repas on regroupe tout sur le même....
il faut donc aller chercher les prestations non pas par leur rattachement à un contrat par bâtiment mais plutôt par leur type

Mais si un client prend un chambre pour une nuit + une repas on regroupe tout sur le même....
il faut donc aller chercher les prestations non pas par leur rattachement à un contrat par bâtiment mais plutôt par leur type

Compte tenu de la complexité, je me demande si je ne devrais pas remplir un array avec des requêtes successives avant de remplir ma table ?
Si Si, je teste ce que tu me proposes mais c'était juste une question...Je me demandais si dans le cas de requêtes complexes il n'arrivait pas des fois où il valait mieux essayer par plusieurs requêtes construire un array...
Ta requête donne donc : #1248 - Every derived table must have its own alias et ajouter AS X en ligne 13 donne ça :

Pour être sûr, j'ai ajouté des Taxes de Séjour dans les contrats 58 et 61 mais ils ne ressortent pas...
Ta requête donne donc : #1248 - Every derived table must have its own alias et ajouter AS X en ligne 13 donne ça :

Pour être sûr, j'ai ajouté des Taxes de Séjour dans les contrats 58 et 61 mais ils ne ressortent pas...
Table prestations

Comme il est possible qu'un contrat contienne :
- soit un gîte avec taxe séjour,
- soit une ou des chambres,
- soit un gîte ou des chambres avec prestations table d'hôtes,
- soit QUE de la table d'hôtes,
ne pourrait on pas imaginer des requêtes avec comme clause WHERE une ou des informations se basant sur le prestations.type de la prestation facturée ?
C'est à dire :
prestations.type (1) = Bâtiment "village" pour remplir la colonne VILLAGE
batiments.id_batiment (1) + prestations.id_prestation (21) - Taxe séjour pour remplir la colonne TS n°1
prestations.type (2) = Bâtiment "jardin" pour remplir la colonne JARDIN
batiments.id_batiment (2) + prestations.id_prestation (21) - Taxe séjour pour remplir la colonne TS n°2
prestations.type (5) = Bâtiment "chambres" pour remplir la colonne CHAMBRES
prestations.type (3) = Bâtiment "table d'hôtes" pour remplir la colonne REPAS


Comme il est possible qu'un contrat contienne :
- soit un gîte avec taxe séjour,
- soit une ou des chambres,
- soit un gîte ou des chambres avec prestations table d'hôtes,
- soit QUE de la table d'hôtes,
ne pourrait on pas imaginer des requêtes avec comme clause WHERE une ou des informations se basant sur le prestations.type de la prestation facturée ?
C'est à dire :
prestations.type (1) = Bâtiment "village" pour remplir la colonne VILLAGE
batiments.id_batiment (1) + prestations.id_prestation (21) - Taxe séjour pour remplir la colonne TS n°1
prestations.type (2) = Bâtiment "jardin" pour remplir la colonne JARDIN
batiments.id_batiment (2) + prestations.id_prestation (21) - Taxe séjour pour remplir la colonne TS n°2
prestations.type (5) = Bâtiment "chambres" pour remplir la colonne CHAMBRES
prestations.type (3) = Bâtiment "table d'hôtes" pour remplir la colonne REPAS

Par contre des contrats ressortent complètement vide comme le 60 et 61 ?
C'est génial les conditions dans le SELECT, du coup on peut écrire ce qu'on veut sans trop la rallonger !
Ce que j'ai fait pour détecter des erreurs dans mon programme avec la saisie de Taxes de séjour dans
des contrats TABLE D'HOTES uniquement !
Il faut maintenant que de mon côté je bloque ce type d'insertion !
Encore mille mercis !