Drupal → Как правильно делать JOIN для таблиц с CCK полями

19.01.2011

Если вам захочется сделать выборку нод вместе с CCK полями, то первым желанием будет посмотреть схему таблиц и набросать что-нибудь в духе:

SELECT n.title, f.field_name_value FROM {node} n
INNER JOIN {content_type_story} f ON n.nid = f.nid AND n.vid = f.vid
WHERE n.type = 'story'
ORDER BY n.title

(в примере выбираются заголовки нод типа story и соответствующее им значение cck поля field_name)

Однако тут есть подводный камень — если поле используется только в одном типе материалов и может иметь только одно значение, то оно хранится в таблице с именем content_type_TYPE (где TYPE это тип материала), иначе же значения хранятся в таблице content_FIELD_NAME (где FIELD_NAME это название поля). Это значит, что как только мы добавим поле field_name в другой материал, или дадим ему возможность иметь несколько значений, запрос перестанет работать.

Поэтому правильней будет — сначала с помощью CCK API узнать название таблицы, и только потом джойнить её в SQL запросе:

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

$result = db_query("
  SELECT title, %s FROM {node} n
  INNER JOIN {%s} f ON n.nid = f.nid AND n.vid = f.vid
  WHERE n.type = 'story'
  ORDER BY n.title
", $db_info['columns']['value']['column'], $db_info['table']);

Подробнее.

Написанное актуально для
CCK 6.x-2.x
Похожие записи

Комментарии

Спасибо большое за материал, какраз в тему)

А зачем в запросе вот эта часть ON n.nid = f.nid AND n.vid = f.vid? Не хватит просто ON n.vid = f.vid

нет, не хватит. это составной ключ

Спасибо за отличный сайт, нужная информация всегда вовремя

Гость
26.05.2011, 13:23

Здраствйте! У меня есть запрос , который выводит количество материалов по полю ццк . Запрос работает , но только для полного совпадения строк , как сделать - чтоб можно было искать по части строки ?

$res = db_result(db_query('SELECT count(*) FROM {node} n INNER JOIN  {%s} f ON n.nid = f.nid AND n.vid = f.vid  WHERE n.type = \'%s\'  AND %s LIKE  \'%s\'  AND n.status = 1'  , $db_info['table'] , $type, $db_info['columns']['value']['column'], $num ));

Я так понимаю - надо подставить знаки % где-то тут : %s LIKE \'%s\' , но чет не работает (((

LIKE '%%%s%%'

% экранируется собой же

Гость
26.05.2011, 20:38

Большое спасибо!!! Я уже наставил этих процентов до головной боли ;)

Слава
29.10.2012, 17:26

В 7-ке - отдельное поле - отдельная таблица.
Вопрос, делаю выборку-таблицу руками через свой модуль. Views не походит, поскольку нужны кастомные сортировки, поиск и т.д. В таблице колонки - значения соответствующих полей типа материала (автор, заголовок, дата и т.д.). Колонок около 15 - 20. Джойнить в запросе 15 - 20 таблиц - запрос получается нереально медленным, десятки секунд. Возможно ли как-то оптимизировать запрос?

Добавить комментарий