SQL Query em relacionamento N - N

Ola Pessoal,

Estou enfrentando um problema para realizar uma query, ja procurei em varios lugares e não descubro como fazer isso.

Tenho três tabelas, ofertas, horarios, e horarios_ofertas.

Por exemplo:
ofertas horarios_ofertas horarios
id | nome oferta_id | horario_id id | dia

1 | Matematica 1 | 1 1 | Seg
2 | Quimica 1 | 2 2 | Qua
3 | Historia 1 | 3 3 | Sex
4 | Geografia 2 | 1
2 | 2
3 | 1

Aí a query que eu preciso fazer, é, por exemplo, uma query que me retorne somente as ofertas que são ministradas na Segunda, e somente na Segunda. Por exemplo, uma materia que é ministrada na segunda e na quarta não deve ser retornada.
Então no exemplo acima, a query deve me retornar somente Historia, pois é a unica oferta que esta ligada somente a Segunda.

SELECT ofertas.id
FROM ofertas
INNER JOIN horarios_ofertas ON horarios_ofertas.oferta_id = ofertas.id
INNER JOIN horarios ON horarios_ofertas.horario_id = horarios.id
AND horarios.dia = ‘Seg’

Usando a query acima por exemplo, ela me retorna todas as ofertas que possuem segunda, e não somente as que são só na segunda.

Alguem aí tem alguma ideia para realizar essa busca?

Muito obrigado,

Fernando

Já tentou assim?

Não entendi…

História está ligada apenas a segunda :?: eu vi so sexta…

Coloca mais dados ai…

olha este topico aki
http://www.guj.com.br/java/225552-tabelas-no-banco#1155581
talvez te ajude!
ja tive este mesmo problema

E se vc fizer uma consulta buscando as materias que tem nos outros dias e entao vc faz a consulta das materias do dia q vc deseja exceto as materias que estao na primeira consulta.

E ae,

Perdão, é que eu escrevi de um jeito e no post saiu de outro… as tabelas são assim ó:

Tabela ofertas:
id| nome
1 | Matematica
2 | Quimica
3 | Historia

Tabela ofertas_horarios:
oferta_id | horario_id
1 | 1
1 | 2
1 | 3
2 | 1
2 | 2
3 | 1

Tabela horarios:
id | dia
1 | Seg
2 | Qua
3 | Sex

A tabela horarios_ofertas é só uma tabela join.

Aí fazendo essa query abaixo, ela me retorna todas as ofertas que possuem aula na segunda feira, e eu quero as que são SOMENTE na segunda feira.

SELECT ofertas.id
FROM ofertas
INNER JOIN horarios_ofertas ON horarios_ofertas.oferta_id = ofertas.id
INNER JOIN horarios ON horarios_ofertas.horario_id = horarios.id
where horarios.dia = ‘Seg’

Aí eu já tentei fazer algo parecido com o que raposo.leandro falou, ficou ± assim:

SELECT ofertas.*
FROM ofertas
INNER JOIN horarios_ofertas ON horarios_ofertas.oferta_id = ofertas.id
INNER JOIN horarios ON horarios_ofertas.horario_id = horarios.id
where horarios.dia = ‘Seg’ and ofertas.id
NOT IN (
SELECT ofertas.id
FROM ofertas
INNER JOIN horarios_ofertas ON horarios_ofertas.oferta_id = ofertas.id
INNER JOIN horarios ON horarios_ofertas.horario_id = horarios.id
where horarios.dia != ‘Seg’
)

Essa query acima funciona, porém ela demora uns 30 segundos pra me retornar o resultado, provavelmente pq as minhas tabelas tem mts registros… ( 8 mil (ofertas), 13mil (ofertas_horarios) e 400 (horarios))

Aí o meu problema é esse, achar uma outra forma de fazer essa query, que seja mais eficiente…

Alguem tem alguma sugestão?

Obrigado pelas respostas,

Fernando

coloca tipo

where horarios.dia not in ( ‘Terça’ , ‘Quarta’ , ‘Quinta’ , ‘Sexta’ )

Hum… testei aqui…

SELECT ofertas.*
FROM ofertas
INNER JOIN horarios_ofertas ON horarios_ofertas.oferta_id = ofertas.id
INNER JOIN horarios ON horarios_ofertas.horario_id = horarios.id
where horarios.dia = ‘Seg’ and horarios.dia
NOT IN (‘Ter’, ‘Qua’, ‘Qui’, ‘Sex’, ‘Sab’, ‘Dom’)

Fiz isso mas tipo, isso é da no mesmo que não colocar esse finalzinho do "and horarios.dia NOT IN (‘Ter’, ‘Qua’, ‘Qui’, ‘Sex’, ‘Sab’, ‘Dom’) ", porque quando ele seleciona um horario que é igual a ‘Seg’, esse mesmo horario com certeza ja vai ser diferente de Ter, Qua, Qui, Sex… entendeu?

o problema esta na seleção que ele faz na horarios_ofertas…

Cara ve se eu entendi corretamente pra poder te ajudar:

[code]
Materia - id_materia / nome
1 - Matematica
2 - Fisica
3 - Quimica
4 - Biologia

Horario - id_horario / nome
1 - Segunda
2 - Terca
3 - Quarta
4 - Quinta
5 - Sexta


HorarioMateria
id_horario_materia / id_materia / id_horario / descricao
1 - 1 - 1 - Matematica/Segunda  *
2 - 1 - 2 - Matematica/Terca
3 - 2 - 1 - Fisica/Segunda      *
4 - 3 - 1 - Quimica/Segunda     *
5 - 3 - 2 - Quimica/Terca
6 - 3 - 3 - Quimica/Quarta
7 - 4 - 3 - Biologia/Quarta
8 - 4 - 4 - Biologia/Quinta
9 - 4 - 5 - Biologia/Sexta

SELECT id_materia FROM HorarioMateria
WHERE id_horario <> 1 //selecionar id da materia, que esteja cadastrado em qualquer horário, menos de segunda

//Selecionar nome da materia que não esteja na subconsulta/ Obs.: o unico registro q nao consta na subconsulta é a materia 2 - Física
SELECT m.nome
FROM Materia m
WHERE m.id_materia NOT IN ( 
		//selecionar id da materia, que esteja cadastrado em qualquer horário, menos de segunda / resultado id_materia = {1,3,3,4,4,4} 
		SELECT id_materia FROM HorarioMateria
		WHERE id_horario <> 1
)
[/code]

Eu executei isso aqui e funcionou na boa.

Olá raposo,

Então, é basicamente isso mesmo que você falou, só que tipo, a diferença é que o meu banco é um pouco diferente.

Por exemplo, na verdade, a minha tabela de horarios tem dia, horario_inicio, horario_fim e são vários registros, então na minha busca, eu nao sei qual o id do horario que eu quero buscar, portanto nao tem como fazer isso WHERE id_horario <> 1 . O que eu tenho que fazer seria no caso dar um join em horarios e buscar WHERE horario.dia <> ‘Seg’, deu pra entender mais ou menos?

Mas mesmo fazendo isso, ele fez a busca dando resultados meio errados, acho que ele está incluindo no resultado, as ofertas que não tem referencia a horário, e além disso ele demora cerca de 30 segundos pra dar esse resultado…

Vou mandar em anexo aqui, um arquivo .sql com essas 3 tabelas do meu banco, ai acho que vai ficar mais facil de entender o problema.

Quando vc fizer essa query, ele vai demorar bem uns 30 segundos pra responder, mas acredite, ele está fazendo a busca…

SELECT m.*
FROM ofertas m
WHERE m.id NOT IN (
SELECT horarios_ofertas.oferta_id FROM horarios_ofertas
inner join horarios on horarios.id = horarios_ofertas.horario_id
WHERE horarios.dia <> 1
)

Obrigado,

Fernando