在教义'FROM'语句中的子查询?



我想编写这个SQL查询

select id FROM
(SELECT article.id AS id, MATCH(titre, intro, contenu) AGAINST ('query') as score FROM article ORDER BY score DESC) t1 
where score>0

在原则中使用querybuilder子查询。

我正在使用一个学说的扩展来解释"对手对决"。

我找不到在"FROM"中创建子查询的条令/querybuilder语法

所以我做了:

$this->createQueryBuilder('a')
->andWhere('MATCH(a.titre, a.intro, a.contenu) AGAINST (:q boolean) >0')
->orderBy('MATCH(a.titre, a.intro, a.contenu) AGAINST (:q boolean)', 'DESC')
->setParameter('q', $query)

这个语法是有效的,但我希望在不重复'MATCH(a.titre, a.intro, a.contenu) AGAINST (:q boolean)两次的情况下高效地执行它。

所以我需要编写子查询版本。

我认为这里至少有两种方法,它们都不需要子查询:

1( 您可以使用HAVING而不是WHERE,并引用选定的列名(+使用HIDDEN关键字从结果中隐藏该列(。尽管这可能性能较差,因为它会对已经选择的数据进行条件匹配和排序,因此查询优化器无法对其进行优化。

$this->createQueryBuilder('a')
->select('a.id, HIDDEN MATCH(a.titre, a.intro, a.contenu) AGAINST (:q boolean) AS score')
->andHaving('score > 0')
->orderBy('score', 'DESC')
->setParameter('q', $query);

2( 如果重复是你唯一的问题,只需将重复的部分定义为一个变量,并使用它:

$score = 'MATCH(a.titre, a.intro, a.contenu) AGAINST (:q boolean)'
$this->createQueryBuilder('a')
->select('a.id')
->andWhere("{$score} > 0")
->orderBy($score, 'DESC')
->setParameter('q', $query)

至于查询中的重复会导致性能损失——据我所知,您不必担心——MySQL应该通过重用相同的值(而不是重新计算(来为您处理这一问题。换句话说,它不会仅仅因为它在查询中出现两次就进行两次匹配——只要表达式相同,优化器就会考虑这一点。(尽管现在我在文档中找不到它的确切位置(

最新更新