Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Reservar vários equipamentos simultaneamente


Weiller Schepis

Pergunta

Olá galera,

Estou desenvolvendo um sistema de reserva de equipamentos institucionais ex: Data Show , Caixa de som e etc...

Dessa forma me encontrei em uma situação bem difícil e gostaria de pedir a ajuda de vocês, pois estou á vários dias pensando na solução, mas sem sucesso upset.gif .

Possuo uma tabela chamada Equipamentos

create table equipamentos(

id_equipamento INT NOT NULL PRIMARY KEY,

nome_equipamento VARCHAR(60)

)

E outra tabela chamado Reserva

create table reserva(

id_reserva INT NOT NULL PRIMARY KEY,

id_equipamento INT NOT NULL,

FOREIGN KEY(id_equipamento)references equipamento(id_equipamento)

);

No momento de reservar o equipamento estou enviando o id do equipamento para a tabela "Reserva" que possui todas as informações da reserva(id da reserva, nome do usuário, id do equipamento, e etc...). Até ai tudo bem, está tudo funcionando corretamente smile.png.

O PROBLEMA

No momento de reservar deve haver a possibilidade do usuário reservar um ou mais equipamentos, ou seja, ele pode reservar um Data Show e uma Caixa de Som simultaneamente.

Com essa demanda eu não estou conseguindo pensar em uma maneira de fazer isso, pois na tabela "Reserva" eu possuo um campo id_equipamento que é foreign key da tabela de equipamentos(id_equipamentos é chave primária da tabela equipamentos).

O que eu devo fazer para registrar vários equipamentos(id_equipamento, nome do equipamento) na mesma reserva?

Exemplo:

Reserva 1 , deve haver o Id do equipamento 1 ,2 e 3

Reserva 2 , deve haver o Id do equipamento 2, 3 e 6

e assim sucessivamente....

Desde já agradeço amigos!! yes.gif

Link para o comentário
Compartilhar em outros sites

9 respostass a esta questão

Posts Recomendados

  • 0

Pelo que entendi, você tem duas tabelas (pessoas e equipamentos) e o relacionamento entre elas deverá ser Muitos para Muitos (um equipamento pode estar reservado por várias pessoas e uma pessoa pode reservar vários equipamentos).

Neste caso, reserva é a tabela de relacionamentos M:N entre pessoas e equipamentos.

Seus atributos básicos devem ser:

id Pessoa

id Equipamento

dt reserva

Poderão haver outros atributos, mas dependerá do que você está planejando.

A chave primária da tabela reserva é a tupla(id Pessoa, id Equipamento).

Com este arranjo você conseguira solucionar os problemas que está enfrentando.

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite Denis,

Antes de mais nada, agradeço por se disponibilizar a me ajudar =)

Estou fazendo o relacionamento exatamente da forma que você citou.

Na minha tabela reserva eu tenho os campos:

Id_reserva(chave primária)

id_usuario (foreign key da tabela pessoa)

id_equipamento (foreign key da tabela equipamento)

quando eu insiro uma reserva fica desse jeito:

id_reserva = 1

id_usuario = 1

id_equipamento = 1

O que não estou conseguindo pensar é como fazer para que caiba vários equipamentos no campo id_equipamento , exemplo:

id_reserva = 1

id_usuario = 1

id_equipamento = 1,2,3...

Pois estou querendo que na reserva 1 realizada pelo usuário 1 tenha os equipamentos 1 2 e 3.

Desde já agradeço amigo :D

Link para o comentário
Compartilhar em outros sites

  • 0


id_equipamento = 1,2,3...

Pois estou querendo que na reserva 1 realizada pelo usuário 1 tenha os equipamentos 1 2 e 3.

Não cometa este erro.

coloque uma chave única para a tupla (id_usuario, id_equipamento) e tenha um registro para cada reserva.

Para demosntrar a reserva do jeito que você quer use o sql abaixo:

SELECT id_usuario, GROUP_CONCAT(id_equipamento) as reservas
FROM reserva
GROUP BY id_usuario

O resultado, para o usuário 1; com a reserva dos equipamentos 2,3,4; será


id_usuario, reservas

"1" , "2,3,4"

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite Denis,

Realizei os testes conforme sua orientação no post anterior, porém encontrei encontrei alguns problemas, conforme explicado abaixo.

A imagem posterior mostra como está estruturado a minha tabela equipamentos e reservas, repare que na tabela reservas, eu criei uma chave primária id_reserva auto_increment, e logo após os campos id_usuario e id_equipamento que são foreing key da tabela pessoa e da tabela equipamento.

uOf5r3.jpg

Após realizar os testes, a consulta retornou os seguintes resultados

Vide imagem abaixo.

RV5beW.jpg

Aparentemente o resultado fornecido ficou da maneira que eu desejo, porém por trás do id_reserva 18 existe o id 19 e 20, como mostrado na primeira imagem, se caso eu fizer uma busca colocando como condição where id_reserva = 18, a consulta é toda desfeita, retornando apenas a reserva de número 18 e equipamento 3, conforme imagem abaixo.

UbqItR.jpg

Diante do problema relatado, lhe pergunto, como ficaria estruturado a chave primária da tabela reservas, fazendo com que os equipamentos 1,2 e 3 , fiquem atrelados a apenas uma reserva?

Link para o comentário
Compartilhar em outros sites

  • 0

Para filtrar um elemento em um GROUP use HAVING.

SELECT id_usuario, GROUP_CONCAT(id_equipamento) as reservas
FROM reserva
GROUP BY id_usuario
HAVING 18 IN GROUP_CONCAT(id_equipamento)
A explicação é simples: A cláusula WHERE é executada ANTES de processar o agrupamento. A cláusula HAVING é executada APÓS o processamento do agrupamento e somente se ele existir.

HAVING só existe se existir GROUP BY

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite Denis,

Muito obrigado, funcionou da maneira que você me falou, a única diferença, foi que eu trabalhei com chave composta na tabela reserva, sendo elas(id_reserva,id_equipamento).

Muito obrigado mesmo Dênis, me ajudou em um problemão, e me ajudou a adquirir experiência para esse tipo de demanda ^^

Segue como a minha tabela ficou estruturada para quem estiver com o mesmo problema:

CREATE TABLE reserva (
id_reserva INT NOT NULL AUTO_INCREMENT,
id_equipamento INT NOT NULL,
id_usuario INT NOT NULL,
id_ambiente INT NOT NULL,
nome_usuario VARCHAR(50) NOT NULL,
equipamento VARCHAR(50) NOT NULL,
ambiente VARCHAR(50) NOT NULL,
data_reserva VARCHAR(45) NOT NULL,
turno VARCHAR(45) NOT NULL,
horario VARCHAR(45) NOT NULL,
status_reserva VARCHAR(45),
obs VARCHAR(350),
PRIMARY KEY(id_reserva,id_equipamento),
FOREIGN KEY (id_equipamento) REFERENCES equipamento(id_equipamento),
FOREIGN KEY (id_usuario) REFERENCES usuario(id_usuario),
FOREIGN KEY (id_ambiente) REFERENCES ambiente(id_ambiente)
);
a consulta realizei da seguinte maneira:
SELECT id_reserva, id_usuario, GROUP_CONCAT(id_equipamento) as id_equipamento, GROUP_CONCAT(equipamento) as equipamento
FROM reserva
GROUP BY id_usuario
HAVING
18 IN (GROUP_CONCAT(id_equipamento))
Link para o comentário
Compartilhar em outros sites

  • 0

Só para completar o tópico, se a tabela reservas ficar muito grande o tipo de pesquisa acima ficará lento.

Para melhorar a performance você deverá trabalhar com o filtro em outra posição.

Veja abaixo:

SELECT STRAIGHT_JOIN id_reserva, id_usuario, GROUP_CONCAT(id_equipamento) as id_equipamento,  GROUP_CONCAT(equipamento) as equipamento
FROM reserva r1
INNER JOIN reserva r2 ON r1.id_usuario = r2.id_usuario
WHERE r2.id_reserva = 18
GROUP BY id_usuario
Link para o comentário
Compartilhar em outros sites

  • 0

Exatamente. O inner join realiza uma intercessão de conjuntos. Então, criei um subconjunto da tabela reserva, com todos os elementos com id_reserva = 18; chamei este subconjunto de r2 e provoquei a intercessão com reserva r1 para todos os id_usuario iguais.

E, como estou usando os índices para os filtros, não corro o risco de um table scan.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.


  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...