Pergunta

I created a database for a hostel, I've built all tables in SQL Server, now I'm trying to write sine queries. I want to get room numbers with available free seats in them.

I have tables Students, Contracts, Rooms.

Contracts has a column Student which references the StudentId in Students and Contracts has the column Room which references the RoomId of the Rooms table. RoomId is a room number.

Room also has a column NumberSeats which is a total number of seats in the room. So I think that's enough for understanding my problem and writing a query.

I want to get room numbers with available free seats in them. I don't know how to implement this, I'm new in SQL, so all I try goes to nothing. Do you have any ideas? Thanks.

Foi útil?

Solução

If you have all the Students mentioned by their ID in your Contracts table, you can extract data by referring just Contracts and Rooms. You can try by joining two tables, counting the number of students per room and adding a condition into the having clause:

SELECT b.RoomId,
  b.NumberSeats,
  COUNT(a.Student)
FROM Rooms b
LEFT JOIN Contracts a
ON a.Room=b.RoomId
GROUP BY b.RoomId,
  b.NumberSeats
HAVING b.NumberSeats>COUNT(a.Student);

Outras dicas

I've prepared this example for you. ddl + query -->

create table student
(id number,
name varchar2(100));

create table room
(id  number,
name varchar2(100));

create table contract
(student_id number,
room_id number);

create table number_seats
(room_id number,
number_seats number);

insert into student values(1, 'Jon');
insert into student values(2, 'George');
insert into student values(3, 'Ian');
insert into student values(4, 'Alex');
insert into student values(5, 'Mary');

insert into room values(1, 'room1');
insert into room values(2, 'room2');
insert into room values(3, 'room3');
insert into room values(4, 'room4');
insert into room values(5, 'room5');

insert into number_seats values(1, 1);
insert into number_seats values(2, 2);
insert into number_seats values(3, 3);
insert into number_seats values(4, 2);
insert into number_seats values(5, 1);

insert into contract values(1, 1);
insert into contract values(2, 2);
insert into contract values(3, 3);
insert into contract values(4, 4);
insert into contract values(5, 4);

select * from room;
select * from student;
select * from contract;
select * from number_seats;


select cont.room_id, num_seats.number_seats - count(*)
from student st 
join contract cont on st.id=cont.student_id
join room ro on ro.id=cont.room_id
join number_seats num_seats on num_seats.room_id=ro.id
group by cont.room_id, num_seats.number_seats 
union
select ro.id, num_seats.number_seats
from room ro left join contract co on ro.id=co.room_id
join number_seats num_seats on num_seats.room_id=ro.id
where co.room_id is null
order by 1;

Result is

|roomNumber|freeSeats|
|    1     |  0      |
|    2     |  1      |
|    3     |  2      |
|    4     |  0      |
|    5     |  1      |
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top