Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/06/2011, 15h56   #1
Invité régulier
 
Inscription : avril 2011
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2011
Messages : 35
Points : 6
Points : 6
Par défaut Select avec sous-requête

Bonjour,

Je bataille sur une requête depuis un moment. Pour tout vous expliquer, j'ai une table commune (36000 lignes) où il me manque des communes (4000 au total).
J'ai une autre table, commune_temp, qui est une table qui n'a pas les même colonnes que la première et qui, elle, possède toutes les communes (soit 40000 lignes si vous suivez bien ). Voici les structures de ces tables :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
commune :
inseecom	int(11)
dcpcantcom	int(1) 
typecheflieucom	int(1) 
codecantcom	int(5) 
nomcom		varchar(255)
latitudecom	decimal(10,6) 
longitudecom	decimal(10,6)
codepostalcom	int(5)
depcom		int(3)

commune_temp :
actual 		int(1)
cheflieu 	int(1)
cdc 	        int(1)
rang 	        int(1)
reg 	        int(2)
dep 	        varchar(3)
com 	        int(3)
ar 	        int(1)
ct 	        int(2)
modif 		int(1)
pole 	        int(5)
tncc 	        int(1)
artmaj 		varchar(5)
ncc 	        varchar(255)
artmin 		varchar(5)
nccenr 		varchar(255)
articlct 	varchar(5)
nccct 		varchar(255)
Les seuls lignes qui sont similaires entre les 2 tables sont :
  • commune.nomcom et commune_temp.ncc
  • commune.depcom et commune_temp.dep

Mon but est de remplir ma table commune avec les communes qui sont présente dans la table commune_temp mais pas dans commune.

J'ai donc écrit la requête suivante :

Code :
1
2
3
4
5
6
7
SELECT com_temp.ncc
FROM gms.commune_temp AS com_temp
WHERE com_temp.ncc NOT IN
(
     SELECT com.nomcom
     FROM gms.commune AS com
)
Le problème, c'est que c'est beaucoup trop long, et mon PC finit par planter (il est très vieux ) J'ai même essayé avec des LIMIT, en réalisant par exemple un " LIMIT 100 " puis " LIMIT 100, 100 " puis " LIMIT 200, 100 " mais bon, il y a 4000 communes. J'ai aussi trouvé la solution de faire département par département qui marche :

Code :
1
2
3
4
5
6
SELECT ncc
FROM commune_temp
WHERE dep = 1
AND ncc NOT IN (SELECT nomcom
                FROM commune
                WHERE arrondissementcom = 1)
Encore un problème, il y a 100 départements... Et il lui faut 30 secondes par département...

J'ai essayé de faire avec une sorte de jointure :

Code :
1
2
3
4
5
SELECT ncc
FROM commune_temp, commune
WHERE dep = depcom
AND ncc NOT IN (SELECT nomcom
                FROM commune)
Je sais que ce n'est pas comme ça, mais là je bloque, si quelqu'un peut m'aider.
(J'espère avoir réussi à être clair )
Kentin64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 19h22   #2
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Il faut créer 1 index sur commune.nomcom et 1 sur commune_temp.ncc
Ensuite utilise la requête :
Code :
1
2
3
4
5
SELECT ncc
  FROM commune_temp ct
 WHERE NOT EXISTS (SELECT 1
                    FROM commune c
                   WHERE c.nomcom = ct.ncc)
Ou celle là :
Code :
1
2
3
4
SELECT ncc
  FROM commune_temp ct
  LEFT JOIN commune c ON c.nomcom = ct.ncc
 WHERE c.nomcom IS NULL
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 09h36   #3
Invité régulier
 
Inscription : avril 2011
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2011
Messages : 35
Points : 6
Points : 6
Merci, mais ça ne va pas plus vite... Tant pis, je vais le faire département par département. Il faut cliquer toutes les minutes donc j'en ai pour 1h30, mais bon des fois on a pas le choix

Je te remercie qd même
Kentin64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 10h02   #4
Invité régulier
 
Inscription : avril 2011
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2011
Messages : 35
Points : 6
Points : 6
Bon finalement, j'ai trouvé un moyen pour le faire assez rapidement, c'est un peu... Dégueu, désolé pour l'expression ^^

Voilà :

Code :
1
2
3
4
5
6
7
SELECT ncc
FROM commune_temp ct
WHERE dep BETWEEN 1 AND 9
AND NOT EXISTS (SELECT 1
		FROM commune c
		WHERE depcom BETWEEN 1 AND 9
		AND c.nomcom = ct.ncc)
Pas très beau, mais ça marche assez bien, genre 45 secondes pour les 10 départements.

Merci pour ton SELECT, je m'en suis aidé.

Bye !
Kentin64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 11h10   #5
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Saluton,
Une jointure du genre de celle proposée par skuatamad serait probablement plus performante qu'une sous-requête corrélée.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h57.


 
 
 
 
Partenaires

Hébergement Web