mysql - TYPO3 9.5 存储库查询以获取具有多个 sys_categories 的元素
问题描述
我试图弄清楚如何编写以下查询来获取一些具有多个类别的元素。
$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 in$categories
和至少一个 in的元素$countryCategories
。$categories
和都是$countryCategories
用类别 uid 填充的数组。
查询工作正常,直到插入第二行$query->in('categories.uid' [...]
。一旦插入第二行,查询结果就为空。这可能是查询中的错误,但我和我的同事都找不到有效的解决方案。
在搜索时,我发现了 sql UNION
,这是我以前从未使用过的,但我猜想如果我必须编写语句而不是构建查询,这将是可行的方法。
我想知道的是是否可以使用“查询构建器”获取元素,或者是否真的需要编写语句?如果查询生成器有解决方案,您可以为我指出吗?如果不是,我将如何构建查询以UNION
根据需要获取元素?
如果有不清楚的地方,请不要犹豫,我会尝试进一步说明。谢谢。
编辑
我们也调试了查询,我直接在 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
如果缺少括号,我可能在格式化时意外删除了它...
解决方案
我认为问题在于 where 子句是按“每行”应用的。
含义如果您有如下查询(基于您的查询):
SELECT *
FROM news
LEFT JOIN sys_category_record_mm mm
ON (news.uid = mm.uid_foreign) /* AND (...) */
LEFT JOIN sys_category
ON mm.uid_local = sys_category.uid
WHERE
sys_category.uid IN (1,2,3)
AND sys_category.uid IN (4,5,6)
您可能有一个新闻条目,即类别 1 和类别 4。但结果集将是两个不同的行:
news.uid | sys_category.uid
1 | 1
1 | 4
并且 WHERE 子句将它们都过滤掉,因为 sys_category.uid 不是单独在(1, 2, 3)和(4, 5, 6) 中的每一行。
在 SQL 级别上执行此操作的方法可能是对 sys_category 进行两次连接。但我不相信(相当简单的)extbase 查询生成器是可能的。
编辑:
作为一种解决方案,您可以使用$query->statement()
允许使用自定义 sql 查询的方法。
$result = $query->statement('SELECT news.* FROM news');
推荐阅读
- tensorflow - 如何在急切执行模式下冻结 tf.keras 框架内的张量流变量?
- r - 如果数据表列选择器也处于活动状态,如何选择行
- c# - 如何在不隐藏表单 C# 的情况下截取屏幕截图
- assembly - 如何声明数据向量
- python-3.x - 如何触发 dag 立即运行
- java - 如何在 Spring-WS 2.4.4 或更高版本中更改 maxOccurs 的默认限制?
- python - GroupBy 操作使用整个数据框对值进行分组
- python - 尽管另行宣布,Django 迁移未应用更改
- php - 如何添加需要服务方法的路由要求?
- python - 在导入的python源中调用导入(!)python源的函数