xandeadx.ru Блог музицирующего веб-девелопера

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

Опубликовано в

Если вам захочется сделать выборку нод вместе с 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
Похожие записи

Комментарии RSS

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

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

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

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

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

$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%%'

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

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

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

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании