2013-04-02 12 views
8

Ho un tavolo partenaire. Un partenaire può avere uno o più indirizzi. E ovviamente un indirizzo può "appartenere" a più di un partenaire. Quindi ho 3 tavoli: partenaire, partenaire_adresse e adresse. L'indirizzo ha una sola città (ville in francese) quindi ho una chiave esterna id_ville nella tabella addresse.Join SQL e join esterno sinistro: perché i risultati sono diversi?

SELECT 
    p.nom, 
    v.nom, v.id_region as id_r, v.id_departement as id_p, 
    r.description as region 
FROM partenaire p 
JOIN partenaire_adresse pa 
    ON pa.id_partenaire=p.id 
JOIN adresse a 
    ON a.id=pa.id_adresse 
JOIN ville v 
    ON v.id=a.id_ville 
JOIN region r 
    ON v.id_region=r.id 
LIMIT 4; 

Questo mi dà questi risultati:

+----------------------------+-------------+------+------+--------+ 
| nom      | nom   | id_r | id_p | region | 
+----------------------------+-------------+------+------+--------+ 
| Ferme Auberge Christlesgut | Breitenbach | 1 | 2 | Alsace | 
| Alice Pizza    | Strasbourg | 1 | 1 | Alsace | 
| Au Vieux Cellier   | Strasbourg | 1 | 1 | Alsace | 
| Auberge du 7Eme Art  | Strasbourg | 1 | 1 | Alsace | 
+----------------------------+-------------+------+------+--------+ 

Ora, se faccio un LEFT OUTER JOIN l'ultimo tavolo (region) i risultati non sono gli stessi:

SELECT 
    p.nom, 
    v.nom, v.id_region as id_r, v.id_departement as id_p, 
    r.description as region 
FROM partenaire p 
JOIN partenaire_adresse pa 
    ON pa.id_partenaire=p.id 
JOIN adresse a 
    ON a.id=pa.id_adresse 
JOIN ville v 
    ON v.id=a.id_ville 
LEFT OUTER JOIN region r 
    ON v.id_region=r.id 
LIMIT 4; 
Non

stesso risultati. Vedere:

+---------------------+----------+------+------+----------------+ 
| nom     | nom  | id_r | id_p | region   | 
+---------------------+----------+------+------+----------------+ 
| 'Le 144' Petrossian | Paris 18 | 12 | 43 | Île-de-France | 
| 'Le 144' Petrossian | Paris 08 | 12 | 43 | Île-de-France | 
| 'O'Quai'   | Vouvray | 7 | 26 | Centre   | 
| 'O'Quai'   | Tours | 7 | 26 | Centre   | 
+---------------------+----------+------+------+----------------+ 

Penso che non dovrebbe, perché nella prima query, id_region e id_departement non sono nulla, quindi se si fa un "join" o un "LEFT outer join", i risultati dovrebbero essere gli stessi . O mi sta sfuggendo qualcosa?

+2

Aggiungere un ordine a ogni query per effettuare qualsiasi tipo di confronto significativo basato su alcuni record nella parte anteriore. –

risposta

4

Il problema riscontrato è legato al fatto che SQL non fornisce alcuna garanzia sull'ordine del risultato quando non è specificato alcun ordine. Se si aggiunge una clausola ORDER BY, si dovrebbero ottenere gli stessi risultati, a condizione che le tabelle abbiano le chiavi corrispondenti su tutte le righe (ovviamente).

+0

Ho aggiunto "order by p.nom" e funziona per entrambi. Quello che non capisco è che c'è una chiave su "nom" del partenaire da tavolo, e con "join" ci vogliono 28.9 secondi, e con "left outer join" ci vogliono 0.10! Come mai? –

+0

Abbastanza onestamente non lo so. Quali sono stati i tempi senza l'ordine? potresti provare a usare "EXPLAIN" su entrambe le query per vedere in che modo sono pianificati in modo diverso. – didierc

+0

+1 per 'explain'. Ci proverò. Per quanto riguarda "without the order by", ci sono voluti 0.10 secondi. –

Problemi correlati