Je pense que votre modèle de données est défectueux. Actuellement, votre modèle a plusieurs enregistrements par pièce, un par emplacement. Parce que votre requête limite uniquement les Etudiants aux Chambres et non aux Machines à sous, elle produit une jointure croisée, ce qui est le mauvais résultat.
Il est possible de clarifier votre requête pour pallier les défauts du modèle. Le mot-clé DISTINCT est l'instrument contondant de choix dans ces scénarios:
SQL> select *
2 from (select DISTINCT dorm_building, dorm_room from webRooms) wR
3 LEFT JOIN residency R
4 on wR.dorm_building = r.dorm_building
5 and wr.dorm_room = r.dorm_room
6/
DORM_BUILDING DORM_ROOM STUDENT_ID DORM_BUILDING DORM_ROOM
-------------------- ---------- ---------- -------------------- ----------
my_dorm 1 123 my_dorm 1
my_dorm 1 345 my_dorm 1
my_dorm 2
SQL>
Une meilleure façon d'aborder ce serait avec une table SLOTS. Cela supprime le besoin d'avoir plusieurs enregistrements WEBROOMS pour représenter une seule pièce physique. Vous dites qu'il est "inconséquent" auquel un étudiant est assigné, mais il est essentiel pour le bon fonctionnement de l'application qu'un étudiant soit affecté à un emplacement spécifique.
Voici une preuve de tables concept:
create table webrooms
(dorm_building varchar2(20)
, dorm_room number)
/
create table slots
(dorm_building varchar2(20)
, dorm_room number
, occupant_num number)
/
create table residency
(student_id number
, dorm_building varchar2(20)
, dorm_room number
, occupant_num number)
/
Comme vous pouvez le voir, la requête révisée fournit des indications claires dont emplacements sont occupés et qui reste libre:
SQL> select wr.*, s.occupant_num, r.student_id
2 from webrooms wr
3 INNER JOIN slots s
4 on wr.dorm_building = s.dorm_building
5 and wr.dorm_room = s.dorm_room
6 LEFT JOIN residency r
7 on s.dorm_building = r.dorm_building
8 and s.dorm_room = r.dorm_room
9 and s.occupant_num = r.occupant_num
10 order by 1, 2, 3, 4
11/
DORM_BUILDING DORM_ROOM OCCUPANT_NUM STUDENT_ID
-------------------- ---------- ------------ ----------
my_dorm 1 1 123
my_dorm 1 2 345
my_dorm 2 1 678
my_dorm 2 2
my_dorm 2 3 890
my_dorm 3 1
my_dorm 3 2
my_dorm 3 3
my_dorm 4 1
my_dorm 4 2 666
9 rows selected.
SQL>
Ou, si nous avons une base de données qui prend en charge les requêtes PIVOT (j'utilise Oracle 11g ici):
SQL> select * from (
2 select wr.dorm_building||' #'||wr.dorm_room as dorm_room
3 , num_gen.num as slot_number
4 , case
5 when r.student_id is not null then r.student_id
6 when s.occupant_num is not null then 0
7 else null
8 end as occupancy
9 from webrooms wr
10 CROSS JOIN (select rownum as num from dual connect by level <= 4) num_gen
11 LEFT JOIN slots s
12 on wr.dorm_building = s.dorm_building
13 and wr.dorm_room = s.dorm_room
14 and num_gen.num = s.occupant_num
15 LEFT JOIN residency r
16 on s.dorm_building = r.dorm_building
17 and s.dorm_room = r.dorm_room
18 and s.occupant_num = r.occupant_num
19 )
20 pivot
21 (sum (occupancy)
22 for slot_number in (1, 2, 3, 4)
23 )
24 order by dorm_room
25/
DORM_ROOM 1 2 3 4
---------- ---------- ---------- ---------- ----------
my_dorm #1 123 345
my_dorm #2 678 0 890
my_dorm #3 0 0 0
my_dorm #4 0 666
SQL>
@davemackey Qu'est-ce que vous utilisez actuellement pour votre requête – msarchet
@msarchet: select * from webRooms wR LEFT JOIN R sur RÉSIDENTS wR.dorm_building = r.DORM_BUILDING et wr.dorm_room = r.DORM_ROOM – davemackey
avez-vous vérifié vos données ? peut-être que vous avez deux fois le même enregistrement dans la table 'Residency'. –