Я пытаюсь выяснить, как написать следующий запрос для извлечения некоторых элементов, которые имеют несколько категорий.
$query->matching(
$query->logicalAnd(
[
// the following 4 lines are the problem lines
$query->logicalAnd(
$query->in('categories.uid', $categories),
$query->in('categories.uid', $countryCategories)
),
// $query->in('categories.uid', $categories),
// $query->in('categories.uid', $countryCategories),
$query->logicalOr(
[
$query->equals('is_pinned', 0),
$query->lessThan('pinned_until', time())
]
),
]
)
);
Идея состоит в том, чтобы выбрать элементы, где categories.uid
соответствует хотя бы одному uid в $categories
и хотя бы одному в $countryCategories
. И $categories
, и $countryCategories
- это массивы, заполненные категориями.
Запрос работал нормально, пока не была вставлена вторая строка $query->in('categories.uid' [...]
. Как только вторая строка вставлена, результат запроса будет пустым. Вероятно, это ошибка в запросе, но ни я, ни мой коллега не смогли найти рабочее решение.
При поиске я обнаружил sql UNION
, с которым я никогда раньше не работал, но я догадался, что это был бы путь, если бы мне пришлось написать утверждение вместо построения запроса.
Что я хотел бы знать, так это то, можно ли получить элементы с помощью "построителя запросов" или действительно необходимо написать заявление? Если есть решение с помощью построителя запросов, не могли бы вы указать мне? Если нет, то как мне построить запрос с помощью UNION
для выборки элементов по мере необходимости?
Если что-то неясно, пожалуйста, не стесняйтесь спрашивать, я постараюсь уточнить дальше. Благодаря.
EDIT
Мы также отладили запрос, и я выполнил его напрямую в phpmyadmin. Он работал без "AND (sys_category.uid IN ( 41, 2 ))
", но с ним результат пуст. Следующим был отлаженный запрос:
SELECT `tx_gijakobnews_domain_model_news`.*
FROM `tx_gijakobnews_domain_model_news` `tx_gijakobnews_domain_model_news`
LEFT JOIN `sys_category_record_mm` `sys_category_record_mm` ON ( `tx_gijakobnews_domain_model_news`.`uid` = `sys_category_record_mm`.`uid_foreign`) AND (( `sys_category_record_mm`.`tablenames` = 'tx_gijakobnews_domain_model_news') AND ( `sys_category_record_mm`.`fieldname` = 'categories'))
LEFT JOIN `sys_category` `sys_category` ON `sys_category_record_mm`.`uid_local` = `sys_category`.`uid`
WHERE ((
(`sys_category`.`uid` IN ( 15, 17, 10, 11, 12, 16, 13, 14 ))
////// this following line is where the problem begins
AND (`sys_category`.`uid` IN ( 41, 2 ))
)
/////////// the following lines are additional restrictions
/////////// which have no influence on the problem
AND ((`tx_gijakobnews_domain_model_news`.`is_pinned` = 0) OR ( `tx_gijakobnews_domain_model_news`.`pinned_until` < 1560867383))
)
AND ( `tx_gijakobnews_domain_model_news`.`sys_language_uid` IN ( 0, -1) )
AND ( `tx_gijakobnews_domain_model_news`.`pid` = 31)
AND ( ( `tx_gijakobnews_domain_model_news`.`deleted` = 0)
AND ( `tx_gijakobnews_domain_model_news`.`t3ver_state` <= 0)
AND ( `tx_gijakobnews_domain_model_news`.`pid` <> -1)
AND ( `tx_gijakobnews_domain_model_news`.`hidden` = 0)
AND ( `tx_gijakobnews_domain_model_news`.`starttime` <= 1560867360)
AND ( ( `tx_gijakobnews_domain_model_news`.`endtime` = 0)
OR ( `tx_gijakobnews_domain_model_news`.`endtime` > 1560867360) ) )
AND ( ( ( `sys_category`.`deleted` = 0)
AND ( `sys_category`.`t3ver_state` <= 0)
AND ( `sys_category`.`pid` <> -1)
AND ( `sys_category`.`hidden` = 0)
AND ( `sys_category`.`starttime` <= 1560867360)
AND ( ( `sys_category`.`endtime` = 0)
OR ( `sys_category`.`endtime` > 1560867360) ) )
OR ( `sys_category`.`uid`
IS NULL) )
ORDER BY `tx_gijakobnews_domain_model_news`.`publish_date` DESC
Если отсутствует скобка, я, вероятно, случайно удалил ее при форматировании ...