2010-11-01 2 views
1

Я пытаюсь решить проблему второго дня, но пока не добился успеха.Объедините несколько запросов MySql в один запрос

Моя цель:

Для определенного термина таксономии ID (например, 1) Мне нужно, чтобы получить по крайней мере один Imagefield FilePath узлов, принадлежащих к этому термин идентификатор (TID 1)

Ниже три вопроса, которые дают мне то, что мне нужно. Все работает отлично, но я знаю, что это выглядит очень уродливо, и, я уверен, есть большая проблема с производительностью.

$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 

Пожалуйста, посмотрите изображение.

alt text Как я могу улучшить запрос? Могу ли я получить значение filepath, используя только один SQL-запрос?

Заранее спасибо.

ответ

5

Что-то вроде этого должно работать.

$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;" 

$ result = db_query ($ sql, $ node_type, $ tid);

Обратите внимание, что вы должны получить информацию об имени таблицы содержимого с помощью

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

Причина заключается в том, потому что SQL сломается, если вы перешли от/до нескольких значений, если не использовать этот метод для дополнительной таблицы и имена столбцов.

+0

Я думаю, что они, вероятно, должны быть внутренними объединениями, а не левыми внешними соединениями. –

+0

@Mark B: Правда, старые привычки умирают тяжело. – googletorp

+0

Кроме того, помните о том, что CCK, модуль, предоставляющий такие таблицы, как content_field_image_cache, может (и, следовательно, WILL) изменять макет базы данных по своему усмотрению. Эта таблица может просто исчезнуть при конфигурационных изменениях. Запросы, подобные вашим, затем будут разбиты. По крайней мере, вы можете поместить в эту документацию. Или, более прочный, выполните проверки в hook_requirements(). – berkes

1

Я принял ответ от @googletorp. Хотя его решение не на 100% работало на меня, оно указывало на правильное направление.

Вот правильный код:

$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 

Спасибо, что вы все классные ребята!

+0

В этом случае не имеет значения, если вы присоединяетесь к 'vid' или' nid', так как 'vid' используется только для пересмотра содержимого тела узла. Также в drupal вы должны использовать заполнители, как я продемонстрировал, для защиты от SQL-инъекций. Также в этом случае, поскольку вы получаете только один результат, вы должны использовать 'db_result' вместо' db_fetch_array' – googletorp

Смежные вопросы