Selezione Query con due relazione molti a molti

sabato 10 novembre 2007 - 21.01

illusione Profilo | Junior Member

Ciao

ho una tabella DVD con una relazione molti a molti con due tabelle attori_dvd e

sottotitoli_dvd

mentre le tabelle che contegono i nomi sono attori e sottotitoli.

Se faccio una ricerca solo per attore funziona

SELECT attori.Nome AS Attore, dvd.Titolo, audio.Nome AS Audio FROM attori INNER JOIN attori_dvd ON attori.ID = attori_dvd.ID_ATTORI INNER JOIN dvd ON attori_dvd.ID_DVD = dvd.ID INNER JOIN audio ON dvd.ID_Audio = audio.ID WHERE (attori.Nome LIKE :Nome)

ma vorrei aggiungere anche il campo sottotitoli

Ho provato cosi'

SELECT attori.Nome AS Attore, dvd.Titolo, audio.Nome AS Audio, dvd.ID, sottotitoli.Nome FROM attori INNER JOIN attori_dvd ON attori.ID = attori_dvd.ID_ATTORI INNER JOIN dvd ON attori_dvd.ID_DVD = dvd.ID INNER JOIN audio ON dvd.ID_Audio = audio.ID INNER JOIN sottotitoli_dvd ON dvd.ID = sottotitoli_dvd.ID_DVD INNER JOIN sottotitoli ON sottotitoli_dvd.ID_SOTTOTITOLI = sottotitoli.ID WHERE (attori.Nome LIKE :Nome)

ma non funziona.

Grazie!

alx_81 Profilo | Guru

>Ciao
Ciao!
>
>ho una tabella DVD con una relazione molti a molti con due tabelle
>attori_dvd e sottotitoli_dvd
>mentre le tabelle che contegono i nomi sono attori e sottotitoli.
>Se faccio una ricerca solo per attore funziona
>ma vorrei aggiungere anche il campo sottotitoli

Posta la CREATE TABLE di tutte le tabelle, posta qualche insert dei dati da utilizzare e poi provo a risponderti. Con i tuoi dati e con le create riesco a darti risposte più sicure..
Ciao!

Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

OK!

create table attori_dvd ( ID mediumint(5) not null auto_increment, ID_ATTORI mediumint(5) unsigned, ID_DVD mediumint(5) unsigned, primary key (ID)) type=MyISAM; #---------------------------- # Records for table attori_dvd #---------------------------- insert into attori_dvd values (1, 1, 3), (2, 1, 4), (3, 2, 5), (4, 3, 1), (5, 4, 2); create table attori ( ID mediumint(11) not null auto_increment, Nome char(30) not null, primary key (ID)) type=MyISAM; #---------------------------- # Records for table attori #---------------------------- insert into attori values (5, 'Ally Sheedy'), (1, 'Mark Rendall'), (4, 'Hannah Lochner'), (2, 'Michael Riley'), (3, 'Harrison Ford'); create table sottotitoli_dvd ( ID mediumint(5) unsigned not null auto_increment, ID_SOTTOTITOLI mediumint(5) unsigned, ID_DVD mediumint(5) unsigned, primary key (ID)) type=MyISAM; #---------------------------- # Records for table sottotitoli_dvd #---------------------------- insert into sottotitoli_dvd values (1, 1, 1), (2, 2, 1), (3, 3, 2), (4, 2, 3), (5, 1, 5); create table sottotitoli ( ID mediumint(5) not null auto_increment, Nome char(255) not null, primary key (ID)) type=MyISAM; #---------------------------- # Records for table sottotitoli #---------------------------- insert into sottotitoli values (1, 'Italiano'), (2, 'Inglese'), (3, 'Francese'), (4, 'Olandese'), (5, 'Spagnolo'); create table dvd ( ID mediumint(6) not null auto_increment, Titolo char(50) not null, Anno char(4) not null default '0', primary key (ID)) type=MyISAM; #---------------------------- # Records for table dvd #---------------------------- insert into dvd values (1, 'Il museo di Margaret', '1995'), (2, 'Voci di morte', '1999'), (3, 'Matrix', '2002'), (4, 'Apollo 13', '2003'), (5, 'Il signore degli anelli', '2002');

ciao

alx_81 Profilo | Guru

>OK!
manca audio ed il legame con dvd.. la tabella dvd non ha il campo ID_Audio che hai indicato nel post precedente (quello delle select).
Potresti aggiungere allo script anche audio? grazie.
Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

create table audio ( ID mediumint(6) not null auto_increment, Nome char(50) not null, primary key (ID)) type=MyISAM; #---------------------------- # Records for table audio #---------------------------- insert into audio values (1, 'Dolby Digital 5.1'), (2, 'Dolby Surround'), (3, 'Stereo'), (4, 'Mono'), (5, 'Dolby Digital 5.0'); create table dvd ( ID mediumint(6) not null auto_increment, Titolo char(50) not null, ID_Audio mediumint(6), primary key (ID)) type=MyISAM; #---------------------------- # Records for table dvd #---------------------------- insert into dvd values (1, 'Il museo di Margaret', '1'), (2, 'Voci di morte', '2'), (3, 'Matrix', '3'), (4, 'Apollo 13', '4'), (5, 'Il signore degli anelli', '5');

alx_81 Profilo | Guru

Dunque, con la select che hai tentato di scrivere ottieni tutti i dati che ti servono (sottotitoli compresi) in base al nome che passi, però utilizzando l'inner join, perdi il legame per ottenere effettivamente tutti gli audio del DVD.
Quando dici che non funziona, intendi proprio questo? Intendi che il numero di record non è quello che ti aspetti?
Se sì, eccoti una possibile soluzione:

SELECT A.Nome AS Attore , D.Titolo , AU.Nome AS Audio , D.ID , ISNULL(S.Nome, 'N/A') AS Sottotitolo FROM attori A INNER JOIN attori_dvd AD ON A.ID = AD.ID_ATTORI INNER JOIN dvd D ON AD.ID_DVD = D.ID INNER JOIN audio AU ON D.ID_Audio = AU.ID LEFT OUTER JOIN sottotitoli_dvd SD ON D.ID = SD.ID_DVD LEFT OUTER JOIN sottotitoli S ON SD.ID_SOTTOTITOLI = S.ID WHERE A.Nome LIKE 'M%'

Con questa query, se non hai i sottotitoli, vedi N/A ma non perdi l'informazione del record attore/dvd..
spero di aver capito, altrimenti, spiegami meglio cosa intendi con "non funziona" e cosa vorresti ottenere.
Inoltre ho notato una ulteriore differenza. Ho messo il % di fianco alla M per farti capire che è necessario per l'operatore LIKE. Comunque tu hai un parametro, e sicuramente, per dire che la prima query funziona, lo valorizzi dall'esterno . Volevo solo indicarlo come parte molto importante.
Se i legami ci sono, vedi i sottotitoli correttamente. Se non ci sono, la tua query elimina le righe dove non c'è il legame, la mia te li mostra ugualmente.
PS: La sintassi è SQL Server, ma è del tutto simile a MySQL.

Ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

gia è molto meglio della mia query..

ma io volevo che insieme all'attore

mi deve selezionare solo il sottotitolo che voglio.

Esempio:

Trovare l'attore Stallone che ha solo i sottotitoli Inglese.

Ho provato ad aggiungere

WHERE A.Nome LIKE 'M%' AND S.Nome Like 'Inglese'

ma va in tilt!

grazie sempre!

alx_81 Profilo | Guru

Con una query come la seguente ricavi tutti gli attori, il cui nome inizia per M e che hanno ANCHE i sottotitoli in inglese:

SELECT A.Nome AS Attore , D.Titolo , AU.Nome AS Audio , D.ID , ISNULL(S.Nome, 'N/A') AS Sottotitolo FROM attori A INNER JOIN attori_dvd AD ON A.ID = AD.ID_ATTORI INNER JOIN dvd D ON AD.ID_DVD = D.ID INNER JOIN audio AU ON D.ID_Audio = AU.ID LEFT JOIN sottotitoli_dvd SD ON D.ID = SD.ID_DVD LEFT JOIN sottotitoli S ON SD.ID_SOTTOTITOLI = S.ID WHERE A.Nome LIKE 'M%' AND S.Nome LIKE 'Inglese%'

Se vuoi ricavare quelli che hanno il nome che iniziano per M ma che dispongono SOLO dei sottotitoli in inglese, la cosa si complica..
Perchè aggiungendo l'AND nella where, ricavi solo gli attori con film sottotitolati in inglese, ma perdi la possibilità di controllare se ne esistono di altre lingue.
Infatti, per vedere se hanno SOLO quei sottotitoli, sei costretto a controllare che non siano presenti con tutti gli altri sottotitoli.
Non trovi sia più comodo ricavare comunque i film con i sottotitoli ricercati? Con la semplice where sopra indicata li ricavi..
Oppure hai proprio l'esigenza di ricavare i film con SOLO quei sottotitoli?

Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

ho provato la query ma si blocca per 30/40 secondi e poi

mi visualizza errore.

Togliendo AND (S.Nome Like 'Inglese%') funziona

(naturalmente senza considerare i sottotitoli). Come

mai?

A te funziona?

Il problema che sto facendo una ricerca avanzata

quindi ogni campo puo essere incrociato con gli altri.

alx_81 Profilo | Guru

>ho provato la query ma si blocca per 30/40 secondi e poi
>mi visualizza errore.
Quale errore? che messaggio?

>A te funziona?
Sì, mi funziona..

>Il problema che sto facendo una ricerca avanzata
>quindi ogni campo puo essere incrociato con gli altri.
quello è un problema sempre.. bisogna limitarle un po' ste ricerche . Ma di solito chi vuole il prodotto vuole poter fare tutto
Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

errore di esecuzione sql

Istruzione SQL eseguita: Select A.nome......

Origine errore: Corelab.Mysql

Messaggio di errore: Lost connection to MYSQL server
during query

Utilizzo MYSQL5 e ho provato la query in VB2005 in generazione query.

Utilizzo come data provider Corelab che è uno dei migliori

tra l'altro a pagamento.

alx_81 Profilo | Guru

>errore di esecuzione sql
>Istruzione SQL eseguita: Select A.nome......
>Origine errore: Corelab.Mysql
>Messaggio di errore: Lost connection to MYSQL serverduring query

>Utilizzo come data provider Corelab che è uno dei migliori
>tra l'altro a pagamento.

Sembra un errore di timeout:
http://dev.mysql.com/doc/refman/5.0/en/gone-away.html
http://dev.mysql.com/doc/refman/5.1/en/error-lost-connection.html

Conosco meglio sql server. Su mysql non mi spingo molto avanti..
Prova a vedere i link. Comunque credo che sia un problema di timeout magari impostato troppo basso ed in anteprima visual studio non ti consente attese elevate.. Quanti record hai in tutto sulle tabelle? Hai provato a lanciare la query direttamente dall'interfaccia (Query Browser se non erro) di mysql?
Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

In MYSQL Query Browser mi esegue la query..

il problema che ci sta solo 75 SECONDI!!!!!

I records delle tabelle sono: 13500 DVD
13000 Attori
35000 Attori_DVD
40 Sottotitoli
17000 Sottotitoli_DVD

Non credo sia un'enorme quantita di dati.

Tra l'altro pensavo di aggiungere ancha la Tabella Audio

come relazione molti a molti dato che possono esserci

piu audio in un dvd, ma a questo punto ci devo rinunciare?

Sbaglio nella progettazione del DB?

Che consigli mi dai?

alx_81 Profilo | Guru

>In MYSQL Query Browser mi esegue la query..
>
>il problema che ci sta solo 75 SECONDI!!!!!
>
>I records delle tabelle sono: 13500 DVD
> 13000 Attori
> 35000 Attori_DVD
>40 Sottotitoli
>17000 Sottotitoli_DVD
>
>Non credo sia un'enorme quantita di dati.
>
>Tra l'altro pensavo di aggiungere ancha la Tabella Audio
>
>come relazione molti a molti dato che possono esserci
>
>piu audio in un dvd, ma a questo punto ci devo rinunciare?
>
>Sbaglio nella progettazione del DB?
>
>Che consigli mi dai?
Non c'è proprio nulla di pesante nel tuo db.. deve volare quella query.. comunque, hai fatto chiavi primarie? hai fatto indici?
sennò sono tutti tablescan..

Alx81 =)

http://blogs.dotnethell.it/suxstellino

illusione Profilo | Junior Member

OK! CI SIAMO HO INDICIZZATO I CAMPI E' VOLA!!!

Per dirti la verità non ho mai capito bene gli indici ho

meglio quali sono i campi da indicizzare. Io ho indicizzato

il campo TITOLO della tabella dvd,

`ID_ATTORI`, `ID_DVD` della tabella attori

`ID_SOTTOTITOLI`, `ID_DVD` della tabella sottotitoli.

Secondo te è giusto?

Questa è l'ultima domanda poi chiudo il post!

Ciao e grazie del prezioso aiuto.

alx_81 Profilo | Guru

>OK! CI SIAMO HO INDICIZZATO I CAMPI E' VOLA!!!
>
>Per dirti la verità non ho mai capito bene gli indici ho
>meglio quali sono i campi da indicizzare. Io ho indicizzato
>il campo TITOLO della tabella dvd,
>`ID_ATTORI`, `ID_DVD` della tabella attori
>`ID_SOTTOTITOLI`, `ID_DVD` della tabella sottotitoli.
>
>Secondo te è giusto?
>Questa è l'ultima domanda poi chiudo il post!
Sai, per darti una risposta a queste domande ci vorrebbe un libro .
Il discorso è che prima devi capire cosa sono gli indici e di che tipo mysql ti permette di crearli..
una volta che capisci quello che fanno, puoi comprendere più semplicemente perchè e dove servono..
Sono un argomento che risulta complesso finchè non affrontato.. poi, una volta che si conoscono le strutture, la complessità si riduce a scegliere dove metterli..
Per partire, diciamo che puoi farli soprattutto sugli id di collegamento delle join e sui criteri di where..
però, per scegliere quelli "perfetti" dovrei conoscere bene tutti i parametri possibili della tabella.
Indicativamente, vedendo le query che abbiamo fatto, lascerei quelli che hai fatto tranne quello sul titolo. E aggiungerei quelli sul nome dell'attore e del sottotitolo (su cui vai con LIKE). Il tipo di indice non te lo so dire, poichè non conosco bene mysql.. Posso dirti che su sql ci sono CLUSTERED e NONCLUSTERED.
Mi raccomando, fai anche le chiavi primarie sul campo o sui campi che devono esprimere l'univocità della riga.
Giusto per darti un'informazione sommaria in più, considera un indice come una struttura di supporto che velocizza l'accesso ai dati, come l'indice di un libro o il glossario.. di più non posso dirti su mysql.. mi spiace..
>
>Ciao e grazie del prezioso aiuto.
figurati, è un piacere .
Magari appena posso guardo come si comportano gli indici in mysql e provo a scriverti qualche cosa in più..
ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5