requète sql [RESOLUT]

requète sql [RESOLUT] - SQL/NoSQL - Programmation

Marsh Posté le 05-07-2010 à 09:20:04    

Bonjour.  
J'ai un problème avec une requête :  
On cherche à obtenir tous les numéros de chambre qui sont libres, ainsi que le nombre de place qu'il y a dedans.  
Il y a donc la table cl_chambre et la table eleves.
 
la requete :  
 
SELECT ch.nochambre,2-count(e1.nochambre)  
FROM cl_chambre AS ch
LEFT JOIN eleves AS e1  
ON e1.nochambre=ch.nochambre
WHERE ch.etat=0
AND
(
 (
  ch.type_chambre=1  
  AND ch.nochambre NOT IN (SELECT e2.nochambre FROM eleves AS e2)
 )
 OR
 (
  ch.type_chambre=2  
  AND(SELECT count(e3.nochambre)  
   FROM eleves AS e3  
   WHERE e3.nochambre=ch.nochambre
   ) < 2
 )
)
 
 
Cela retourne NULL pour ch.nochambre.
Je suis débutant et donc j'ai du mal avec les jointures. Si quelqu'un pourrait me débloquer, ça serait bien cool !

Message cité 1 fois
Message édité par anartetsuo le 05-07-2010 à 12:26:01
Reply

Marsh Posté le 05-07-2010 à 09:20:04   

Reply

Marsh Posté le 05-07-2010 à 09:50:21    

Si y'a des trucs que je dois préciser dites le moi.

Reply

Marsh Posté le 05-07-2010 à 10:16:48    

Mwais, c'est trop tot le matin pour réfléchir, le premier truc qui vient à l'esprit c'est:
- ca renvoie tout le temps NULL ou juste pour quelques lignes?
- est-ce que t'aurais pas des étudiants sans chambre, ce qui avec le LEFT join amènerait les NULLs?
- donc essaies avec un RIGHT join à la place du LEFT


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 05-07-2010 à 10:17:32    

Oui, seulement quelques étudiants sont affectés à des chambres, j'essaye ça tout de suite.  
 
Sinon, d'accord avec toi, c'est trop tôt pour réfléchir, et je rajouterais qu'il fait trop beau pour travailler.


Message édité par anartetsuo le 05-07-2010 à 10:18:34
Reply

Marsh Posté le 05-07-2010 à 10:21:26    

Aucun changement.  
Pour répondre à la première question : Ça ne renvoi qu'une ligne, donc NULL.
 
En gros :  
nochambre      2-count(e1.nochambre)  
NULL               2  

Reply

Marsh Posté le 05-07-2010 à 10:43:15    

anartetsuo a écrit :

Bonjour.  
J'ai un problème avec une requête :  
On cherche à obtenir tous les numéros de chambre qui sont libres, ainsi que le nombre de place qu'il y a dedans.  
Il y a donc la table cl_chambre et la table eleves.
 
la requete :  
 
SELECT ch.nochambre,2-count(e1.nochambre)  
FROM cl_chambre AS ch
LEFT JOIN eleves AS e1  
ON e1.nochambre=ch.nochambre
WHERE ch.etat=0
AND
(
 (
  ch.type_chambre=1  
  AND ch.nochambre NOT IN (SELECT e2.nochambre FROM eleves AS e2)
 )
 OR
 (
  ch.type_chambre=2  
  AND(SELECT count(e3.nochambre)  
   FROM eleves AS e3  
   WHERE e3.nochambre=ch.nochambre
   ) < 2
 )
)
 
 
Cela retourne NULL pour ch.nochambre.
Je suis débutant et donc j'ai du mal avec les jointures. Si quelqu'un pourrait me débloquer, ça serait bien cool !


 
 
c'est quel sgbd? Une opération sur des null c'est pas une bonne idée...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 05-07-2010 à 10:49:36    

Mysql 5.1.36
 
Je n'essaye pas de faire d'opération avec des NULL, ce n'est pas volontaire d'avoir des NULL...
 
En gros, ce que je veux :  
-première colonne, les numéro de chambres
-deuxième colonne, le nombre de place disponible. (qui dépend du type de chambre, de l'état qui doit être à 0 (qui correspond à un chambre en état de fonctionnement) et du nombre d'élèves affectés dans cette chambre

Reply

Marsh Posté le 05-07-2010 à 11:01:54    

anartetsuo a écrit :

Mysql 5.1.36
 
Je n'essaye pas de faire d'opération avec des NULL, ce n'est pas volontaire d'avoir des NULL...


 
Ta colonne e1.nochambre peut être null.[:skeye]
ils veulent dire quoi tes champs cl_chambre.etat et cl_chambre.type_chambre?


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 05-07-2010 à 11:09:55    

Faut pas chercher trop loin, si ca renvoie qu'une ligne, c'est que ta clause where filtre trop.
Commence par la virer et regarde si ca te ramène un truc cohérent déjà.
 
Sinon pour Skeye, j'ai fait des suppositions:
chambre.etat c'est si elle est occupable ou pas
chambre.type c'est le nombre de places
 
anartetsuo confirmera ou infirmera.


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 05-07-2010 à 11:12:40    

Hum, tu penses qu'il faudrait enmpecher d'avoir un champs e1.nochambre null ?  
genre dans le where :
e1.nochambre != ''
 
 
cl_chambre.etat : il y a trois état :  en etat, vip, ou en réparations. On ne veut pas affecter d'élève si la chambre n'est pas en état, donc si cl_chambre.etat est différent de 0.  
 
cl_chambre.type_chambre : définit le type de chambre : vaut 0 (pour une chambre simple) ou 1 (pour une chambre double)  
 
Edit : nan, type_chambre vaut bien 1 ou 2, toutes mes excuses
 
On veut donc dans la première colonne le numéro des chambres en état, dont le type est simple et qu'il n'y à pas d'élèves, ou dont le type est double et il n'y à pas plus de 1 élève affecter dans la chambre. Dans la deuxième colonne, on veut le nombre de place disponible pour la chambre, soit 1 pour une chambre simple, et pour une chambre double cela dépend.


Message édité par anartetsuo le 05-07-2010 à 13:12:58
Reply

Marsh Posté le 05-07-2010 à 11:12:40   

Reply

Marsh Posté le 05-07-2010 à 11:13:45    

Lasnoufle : ouai en gros tes suppositions étaient bonnes.  
 
Pour le where, je test ça.
 
Edit : sans le where, toujours une seule ligne :cry:  
 
la requête est alors :  
        SELECT ch.nochambre, 2 - count( e1.nochambre )  
         FROM cl_chambre AS ch
         RIGHT JOIN eleves AS e1 ON e1.nochambre = ch.nochambre


Message édité par anartetsuo le 05-07-2010 à 11:15:22
Reply

Marsh Posté le 05-07-2010 à 11:19:29    

Allez je tente, fait à l'arrache (et oui, moi j'adooooore les sous-requetes).
Bon pas certain à 100% que la syntaxe soit bonne, corriges si ca passe pas au premier coup bien sur.

SELECT ch1.nochambre "Numéro de chambre", (ch1.type + 1 - nvl(nbOccupants,0)) "Places libres"
FROM cl_chambre ch1
LEFT JOIN
(SELECT ch2.nochambre,count(e1.nochambre) nbOccupants
FROM cl_chambre ch2
JOIN eleves e1
ON ch2.nochambre=e1.nochambre
GROUP BY ch2.nochambre) temp
ON ch1.nochambre = temp.noChambre
WHERE ch.etat=0;


Edit: ha j'avais pas vu que type vaut 0 ou 1 et non 1 ou 2, corrigé
Re-edit: je précise que j'avais dit de la merde pour le left/right join, le fait que tu aies "inversé" les tables dans la clause ON m'a induit en erreur.


Message édité par lasnoufle le 05-07-2010 à 11:23:13

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 05-07-2010 à 11:23:41    

Je vais tester ce que ça rend, mais là, si je suis bien, même les chambres indisponibles vont s'afficher, avec 0 dans la deuxième colonne, c'est ça ?  
 
PS : c'est quoi pour afficher du code ici ?

Reply

Marsh Posté le 05-07-2010 à 11:26:24    

Et bin il connait pas nvl (et moi non plus d'ailleur ^^)

 

Sinon ta seule erreur de syntaxe, c'est type_chambre au lieu de type :)

 

#1305 - FUNCTION epb.nvl does not exist
SELECT ch1.nochambre "Numéro de chambre", (
ch1.type_chambre +1 - nvl(
nbOccupants, 0
)
) "Places libres"
FROM cl_chambre ch1
LEFT JOIN (

 

SELECT ch2.nochambre, count( e1.nochambre ) nbOccupants
FROM cl_chambre ch2
JOIN eleves e1 ON ch2.nochambre = e1.nochambre
GROUP BY ch2.nochambre
)temp ON ch1.nochambre = temp.noChambre
WHERE ch.etat =0
LIMIT 0 , 30

   

Si je me trompe pas, nvl c'est pour oracle.


Message édité par anartetsuo le 05-07-2010 à 11:27:30
Reply

Marsh Posté le 05-07-2010 à 11:37:00    

Ha ouai possible, bah y doit y avoir un truc équivalent pour ce que tu utilises, NVL(nbOccupants,0) renvoie nbOccupants si non nul, ou 0 si nbOccupants est nul. J'connais pas MySQL mais y a forcément quelque chose d'équivalent.
Sinon si tu veux filtrer les chambres pleines, tu rajoutes juste dans la clause where:
AND (ch1.type_chambre +1 - nvl(nbOccupants, 0)) <> 0

 

Pour afficher du code t'as des balises fixed ou cpp et d'autres je crois. Réponds à un message qui se sert de ces balises si tu veux voir.


Message édité par lasnoufle le 05-07-2010 à 11:48:17

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 05-07-2010 à 12:07:00    

Pas testé, mais un truc de ce genre devrait te donner quelque chose :

Code :
  1. SELECT c.no_chambre, places - occupees
  2. FROM
  3. (SELECT c.nochambre, c.type_chambre  + 1 AS places, count(*) AS occupees
  4. FROM cl_chambre c
  5.    JOIN eleves e ON e.nochambre = c.nochambre
  6. WHERE c.etat = 0
  7. GROUP BY c.nochambre, c.type_chambre
  8. union
  9. SELECT c.nochambre, c.type_chambre  + 1 AS places, 0 AS occupees
  10. FROM cl_chambre c
  11.    LEFT OUTER JOIN eleves e ON e.nochambre = c.nochambre
  12. WHERE c.etat = 0
  13. AND e.nochambre IS NULL
  14. )



Message édité par skeye le 05-07-2010 à 12:08:03

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 05-07-2010 à 12:16:09    

(la première sous-requête s'occupe des chambres qui ont des occupants, la seconde de celles qui n'en ont pas. Il y aurait surement moyen de faire le paquet en une seule fois, mais flemme de chercher ce que propose mysql là-dessus)


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 05-07-2010 à 12:21:59    

Bon, j'ai réussi à obtenir quelque chose avec la requète de lasnoufle :  
 
Requête :  


SELECT ch1.nochambre "Numéro de chambre", (
ch1.type_chambre - IFNULL( nbOccupants, 0 )  
) "Places libres"
FROM cl_chambre ch1
LEFT JOIN (
 
SELECT ch2.nochambre, count( e1.nochambre ) nbOccupants
FROM cl_chambre ch2
JOIN eleves e1 ON ch2.nochambre = e1.nochambre
GROUP BY ch2.nochambre
)temp ON ch1.nochambre = temp.noChambre
WHERE ch1.etat =0
ORDER BY ch1.nochambre ASC  


 
Faut encore que je teste en enlevant les chambres pleines dans le where
 
Désolé d'avoir mis du temps à répondre, pause déjeuner.

Reply

Marsh Posté le 05-07-2010 à 12:25:21    

Ok, c'est nickel !  
Requête :  


SELECT ch1.nochambre "Numéro de chambre", (
ch1.type_chambre - IFNULL( nbOccupants, 0 )  
) "Places libres"
FROM cl_chambre ch1
LEFT JOIN (
 
SELECT ch2.nochambre, count( e1.nochambre ) nbOccupants
FROM cl_chambre ch2
JOIN eleves e1 ON ch2.nochambre = e1.nochambre
GROUP BY ch2.nochambre
)temp ON ch1.nochambre = temp.noChambre
WHERE ch1.etat =0
AND (
ch1.type_chambre - IFNULL( nbOccupants, 0 )  
) <>0
ORDER BY ch1.nochambre ASC  


 
Cela retourne bien le numéro des chambres dont il reste des places, et le nombre de place.  
 
Merci beaucoup à tous les deux.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed