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   -
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 :
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:

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
1
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
Je te remercie beaucoup yg_be, tu as solutionné mon problème avec une requête de la mort qui tue !
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 !



0
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?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
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
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
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


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
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention  
 
il suffit peut-être d'ajouter
AS X
en ligne 13.
0

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.
0
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?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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...
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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é !)
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention  
 
Je suppose qu'un bâtiment est associé à chaque contrat.
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
Oui, c'est ça....
1 - Village
2 - Jardin

3 - pour les contrats table d'hôtes donc pas proprement parlé de bâtiment mais de contrat
4 - Non utilisé comme contrat
5 - Chambres individuelles
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
Donc ce serait une base de données MySQL?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
Oui, une bdd MySQL
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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 !
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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 ?
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
Je peux difficilement t'aider si tu ne testes pas mes suggestions.
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
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...
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention  
 
Dans ce cas-ci, je pense que nous trouverons une solution simple.
Sinon, je suggérerais plutôt d'adapter la structure de la base de données.
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
Table compositions


Table contrats
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
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

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
Tu fais des suggestions de solution. S'agit-il de résoudre le problème initial, ou suggères-tu d'adapter le problème pour pouvoir le résoudre plus facilement?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 



Nettement mieux !
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
Par contre des contrats ressortent complètement vide comme le 60 et 61 ?
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
Il devrait y avoir REPAS ou TS1 pour les contrats 60 ou 61?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
60 ne contient qu'une chambre
et 61 1 chambre et des taxes de séjour
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention  
 
donc la requête est correcte, non?
0
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
oui, excuse moi, tu as raison, nous sommes en présence d'une chambre dont le prix intègre la taxe de séjour, il ne devrait pas y en avoir une en plus sur le contrat....
il faut que je bloque ça pour éviter que l'utilisateur le fasse, moi je l'ai fait juste pour le test, d'où ma confusion, désolé
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention  
 
Comme la requête est écrite, c'est normal.
1
emrh Messages postés 427 Date d'inscription   Statut Membre Dernière intervention   20
 
0