Mysql : select sur plusieurs tables?

  • Auteur de la discussion Auteur de la discussion Recif
  • Date de début Date de début
WRInaute impliqué
Bonjour,

Voici mon souci: j'ai 2 ou trois tables avec divers articles. J'aimerai simplement faire une liste commune de tous les articles confondus, triés par date (ou par index primaire). Je trouve plein d'exemple sur le net, mais c'est à chaque fois du relationnel, donc des articles liés à un identifiant se trouvant sur une autre table, ça ne répond donc pas à mon problème...
Y a t-il une syntaxe qui existe spécifiquement pour ce problème ouo bien il faut faire un array (php) commun à toutes les tables et trier ensuite le tout?...

Merci
 
WRInaute discret
Pour utiliser "union" les définitions techniques des rubriques récupérés dans les select doivent être identiques entres les différentes requêtes. Si ce n'est pas le cas, il faut faire un cast sinon ça ne marchera pas.

Si tu me dis que c'est le cas, tu dois te poser la question sur le modèle de ta base et son optimisation et surtout la raison pour la quelle tu crées trois tables identiques au lieu d'utiliser une seule.
 
WRInaute accro
jamalofski a dit:
Pour utiliser "union" les définitions techniques des rubriques récupérés dans les select doivent être identiques entres les différentes requêtes. Si ce n'est pas le cas, il faut faire un cast sinon ça ne marchera pas.
On peut aussi les préparer via des opérateurs dans les selects, ce qui permet d'unir des tables avec des définitions de champs différentes (mais je suis d'accord que ce n'est pas l'idéal)
 
WRInaute impliqué
En fait j'ai trois tables avec trois métiers différents et une liste de personnes (pour la petite histoire, c'était obligatoire car chaque métier a ses spécification, et donc pas les mêmes champs). Il y a quelques champs qui ont le même nom entre les tables.
Sur la page principale j'aimerais lister les dernières personnes enregistrées mais tous métiers confondus, donc dans les trois tables.
Par contre si vous pouviez mettre un exemple ça m'arrangerais... :wink:
Merci
 
WRInaute accro
Donc le bon modèle de données aurait été une table avec les métiers et les champs communs, et une table annexe pour les spécifs différentes.

Pour te faire ta requête (puisque c'est ça que tu demandes) il faudrait au moins que tu donnes les specs de tes tables
 
WRInaute impliqué
C'est plus complexe que ça pour la structure, mais je ne souhaite pas entrer dans les détails, il faut se dire que c'est infaisable.

Pour deux tables tables:

Metier 1
id
nom
prenom
critere1
date

Metier 2
id
nom
prenom
critere2
date

J'aimerais avoir la liste des derniers enregistrements triés par date, mais les deux tables confondues...

- nom / prenom / date
- nom / prenom / date
...
 
WRInaute accro
SELECTnom AS LENOM, prenom AS LEPRENOM, date AS LADATE from metier 1
UNION SELECT nom AS LENOM, prenom AS LEPRENOM, date AS LADATE from metier 2
ORDER BY LADATE DESC

(bon bien sûr tu n'as pas mis date comme nom de champs mais autre chose)
 
WRInaute impliqué
J'ai essayé avec UNION mais j'ai un message d'erreur

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in ...

requete en php :

Code:
$result = mysql_query("select id as IDALL from metier1 UNION 
select id as IDALL, prenom as PRENOM from metier2 order by IDALL DESC");
 while($row = mysql_fetch_array($result)) {
 	echo "$row[0]<br>";
}
 
WRInaute accro
Ben oui, je me suis cassée à te donner la structure exacte que tu voulais :) (qui soit dit en passant ne correspond pas à ce que tu as fait)
 
WRInaute impliqué
Bon ben j'y arrive pas... Je demande pas le même nombre de champs dans les deux tables, j'ai aucun resultat...
(j'ai pas mis tous les champs, il y en a une bonne quinzaine dans chaque table)...

Code:
$result = mysql_query("select id as IDALL, prenom as PRENOM, critere1 as CRITERE from metier1 UNION 
select id as IDALL, prenom as PRENOM, critere2 as CRITERE from metier2 order by IDALL DESC");
 while($row = mysql_fetch_array($result)) {
    echo "$row[0] - $row[1] - $row[2]<br>";
}
 
WRInaute discret
Recif a dit:
C'est UNION? et pas UNION ALL?

UNION récupère toutes les lignes et supprime les doublons (comprendre UNION DISTINCT). UNION est donc beaucoup plus gourmand en ressources qu'un simple UNION ALL qui
conserve toutes les lignes. De manière imagée cela donne:

{a,b,c} UNION {a,b,d} = {a,a,b,b,c,d}
{a,b,c} UNION ALL {a,b,d} = {a,b,c,d}

Si tes tables n'ont pas de lignes communes alors fait un UNION ALL, sinon ca dépendra de ce que tu veux obtenir.
 
WRInaute impliqué
Je veux obtenir toutes les lignes, il n'y a aucun rapport entre les deux bases et si il y a des doublons, il faut que je les affichent également...
 
WRInaute impliqué
Apparemment j'ai trouvé u truc : il refuse de me donner des résultat si le nombre de colonnes demandées n'est pas identique dans les deux select... Mais j'i une table qui a deux fois plus de colonnes que l'autre... Comment faire?...
 
WRInaute discret
Recif a dit:
Apparemment j'ai trouvé u truc : il refuse de me donner des résultat si le nombre de colonnes demandées n'est pas identique dans les deux select... Mais j'i une table qui a deux fois plus de colonnes que l'autre... Comment faire?...

Ah oui, http://dev.mysql.com/doc/refman/5.0/fr/union.html

Pour résoudre le problème il te suffit de rajouter les colonnes qui manquent. Par exemple quelque chose comme

Code:
SELECT col1, col2, NULL, 0
FROM table1
UNION ALL
SELECT col1, col2, col3, col4
FROM table2

J'ai complété la table1 avec deux colonnes contenant respectivement la valeur NULL et l'entier 0.
 
WRInaute impliqué
Ok, merci.
Je rencontre un autre problème : même en suivant le nombre de colonne (j'ajoute à chaque fois une colonne supplémentaire et je test), arrivé à un moment, il ne me trie plus l'ensemble mais me place les enregistrements de la table 1 pui ceux de la table 2 à la fin... Plus de tri sur la date... Je comprends plus rien!...

Cette requete ne fonctionne pas :
Code:
$result = $db->sql_query("select id as ID, uid_pro as UIDPRO, taux as TAUX, nombre as NOMBRE, date as DATEALL from table1 UNION ALL
select id as ID, uid_pro as UIDPRO, taux as TAUX, produit as PRODUIT, date as DATEALL from table2 order by DATEALL DESC");
 while($row = $db->sql_fetchrow($result)) {
 	echo "$row[ID] - $row[UIDPRO] - $row[TAUX] - $row[DATEALL] - $row[VALACHAT] - $row[PRODUIT]<br>";
}

Celle ci marche :

Code:
$result = $db->sql_query("select id as ID, uid_pro as UIDPRO, taux as TAUX, date as DATEALL from table1 UNION ALL
select id as ID, uid_pro as UIDPRO, produit as PRODUIT, date as DATEALL from table2 order by DATEALL DESC");
 while($row = $db->sql_fetchrow($result)) {
 	echo "$row[ID] - $row[UIDPRO] - $row[TAUX] - $row[DATEALL] - $row[VALACHAT] - $row[PRODUIT]<br>";
}
 
WRInaute impliqué
Ouahou... Je crois que j'ai réussi à m'en dépatouiller... :-o Je vais encore regarder si je ne trouve pas d'anomalies avant de crier victoire...
 
WRInaute discret
Recif a dit:
Code:
$result = $db->sql_query("select id as ID, uid_pro as UIDPRO, taux as TAUX, nombre as NOMBRE, date as DATEALL from table1 UNION ALL
select id as ID, uid_pro as UIDPRO, taux as TAUX, produit as PRODUIT, date as DATEALL from table2 order by DATEALL DESC");
 while($row = $db->sql_fetchrow($result)) {
 	echo "$row[ID] - $row[UIDPRO] - $row[TAUX] - $row[DATEALL] - $row[VALACHAT] - $row[PRODUIT]<br>";
}

Euh, tu mets au point tes requêtes en utilisant le code ci-dessus ? Tu sais que c'est plus sympa avec PhpMyAdmin ?
 
WRInaute impliqué
Ok, merci, ça fonctionne! :)

J'ai juste un souci de tri. Le tri par DATEALL fonctionne :

Code:
select date as DATEALL, id , uid_pro, taux as TAUXALL, nombre, nombre2, validite1, validite2, commentaire, val1, val2, val3, val4, val5, val6 from table1 UNION ALL
select date as DATEALL, id, uid_pro, produit, valeur_achat, taux as TAUXALL, validite1, validite2, NULL, NULL, NULL, NULL, NULL, NULL, NULL from table2 order by DATEALL DESC

Par contre le tri par TAUXALL ne fonctionne pas... :(

Code:
select date as DATEALL, id , uid_pro, taux as TAUXALL, nombre, nombre2, validite1, validite2, commentaire, val1, val2, val3, val4, val5, val6 from table1 UNION ALL
select date as DATEALL, id, uid_pro, produit, valeur_achat, taux as TAUXALL, validite1, validite2, NULL, NULL, NULL, NULL, NULL, NULL, NULL from table2 order by TAUXALL DESC

Je comprends pas , c'est la même syntaxe pourtant... Est ce que le tri ne peut s'opérer qu'avec le premier élément?...
 
WRInaute accro
Tu as un décalage de colonnes sur la deuxième partie de ta requête, tu as oublié de rajouter les Null correspondant à produit et valeur_achat dans la première sélection
 
WRInaute impliqué
Ben je ne peux pas, j'ai besoin de ces valeurs... Si je mets NULL à la place, je ne peux pas les récupérer...
 
WRInaute accro
Euh pas à la place
R1 -> R2
date -> date (col1)
id -> id (col2)
uid_pro ->uid_pro (col3)
taux -> produit (col4) donc là tu fais NULL dans la requete 1
pareil pour valeur_achat il faut un Null dans la requete 1
à ce moment là taux sera dans la colonne 6 dans les deux requetes et ça marchera mieux
 
Discussions similaires
Haut