2010-11-01 5 views
1

J'essaie de résoudre le problème du deuxième jour mais sans succès pour le moment.Combiner plusieurs requêtes MySql en une seule requête

Mon but est:

Pour certains ID taxonomie terme (par exemple 1) Je dois obtenir au moins un filepath de ImageField des nœuds qui appartiennent à ce terme id (tid 1)

Voici trois requêtes qui me donnent ce dont j'ai besoin. Tout fonctionne bien mais je sais que ça a l'air vraiment moche et, j'en suis sûr, il y a un gros problème de performance.

$childterm = 10; // Taxonomy term ID 
$result = db_fetch_array(db_query("SELECT node.vid FROM node JOIN 
            term_node ON node.vid=term_node.vid WHERE 
     term_node.tid=$childterm AND 
            node.type= 'product' LIMIT 0,1"));   

$nvid = $result['vid']; // Extracting node VID by term ID that will be used futher 

$result = db_fetch_array(db_query("SELECT field_image_cache_fid FROM 
            content_field_image_cache WHERE 
     vid = '%d'", $nvid)); 

$fid = $result['field_image_cache_fid']; // Extracting file ID from array 

$result = db_fetch_array(db_query("SELECT filepath FROM files WHERE 
            files.fid = '%d'", $fid));   

$filepath = $result['filepath']; // Finally. Extracting file path from array 

Veuillez regarder l'image.

alt text Comment puis-je améliorer la requête? Puis-je obtenir la valeur de chemin de fichier en utilisant seulement une requête SQL?

Merci d'avance.

Répondre

5

Quelque chose comme ça devrait fonctionner.

$sql = "SELECT f.filepath FROM {node} AS n 
INNER JOIN {term_node} AS t ON t.nid = n.nid 
INNER JOIN {content_field_image_cache} as c ON c.nid = n.nid 
INNER JOIN {files} AS f on f.fid = c.fid 
WHERE n.type = '%s' 
AND t.tid = %d;" 

$ resultat = requête_db ($ sql, $ type_noeud, $ tid);

Notez que vous devez obtenir les informations sur le nom de la table de contenu en utilisant

$db_info = content_database_info(content_fields($field_name)); 

La raison est parce que le SQL cassera si vous avez changé de/vers plusieurs valeurs, à moins que vous utilisez cette méthode pour table supplémentaire et les noms de colonnes.

+0

Je pense que ceux-ci devraient probablement être des jointures internes plutôt que des jointures externes. –

+0

@Mark B: Il est vrai que les vieilles habitudes ont la vie dure. – googletorp

+0

En outre, sachez que CCK, le module fournissant des tables comme content_field_image_cache, pourrait (et par conséquent WILL) modifier la disposition de la base de données à volonté. Cette table pourrait juste disparaître sur les changements de configuration. Les requêtes comme les vôtres vont alors se casser. Vous pourriez au moins mettre de la documentation à ce sujet. Ou, plus solide, fournit des vérifications dans hook_requirements(). – berkes

1

J'ai accepté la réponse de @googletorp. Même si sa solution ne fonctionnait pas à 100% pour moi, elle indiquait la bonne direction.

Voici code correct:

$childterm = 10;// taxonomy term 
$nodetype = 'product';// node type 
$sql = "SELECT f.filepath FROM node n 
     INNER JOIN term_node tn ON tn.vid = n.vid 
     INNER JOIN content_field_image_cache cf ON cf.vid = n.vid 
     INNER JOIN files f ON f.fid = cf.field_image_cache_fid 
     WHERE n.type = $nodetype AND tn.tid = $childterm LIMIT 0, 1"; 
     $result = db_fetch_array(db_query($sql)); 
    $filepath = $result['filepath']; // image path 

Merci, vous êtes tous les gars cool!

+0

Dans ce cas, cela ne fait aucune différence si vous vous joignez à 'vid' ou' nid', puisque 'vid' est seulement utilisé pour les révisions du contenu du corps du noeud. Toujours dans Drupal, vous devez utiliser des espaces réservés, comme je l'ai démontré, pour aider à protéger contre l'injection SQL. Dans ce cas également, puisque vous n'obtenez qu'un seul résultat, vous devriez utiliser 'db_result' au lieu de' db_fetch_array' – googletorp

Questions connexes