我如何使用 Doctrine Native Query 通过条件语句的连接计数来排序结果?
How can I use Doctrine Native Query to order results by the count of a join with a conditional statement?
我想 select 来自 poll
table 的行,并按连接 vote
table 的行数或总和对它们进行排序其中 vote.is_current_vote = true
.
投票 table 跟踪所有投票,但投票中只计算每个用户的最新投票,标记为 is_current_vote
。
我正在努力研究如何使用 Doctrine Query Builder 或 Native Query 来计算投票数 table。
数据库结构如下:
create table if not exists user
(
id int auto_increment
primary key,
username varchar(45) not null,
slug varchar(45) not null,
created_at datetime not null,
updated_at datetime null,
constraint UNIQ_8D93D649989D9B62
unique (slug),
constraint UNIQ_8D93D649F85E0677
unique (username)
)
collate=utf8_unicode_ci
;
create table if not exists poll
(
id int auto_increment
primary key,
user_id int null,
question varchar(140) not null,
slug varchar(140) not null,
is_active tinyint(1) not null,
created_at datetime not null,
updated_at datetime null,
constraint UNIQ_84BCFA45989D9B62
unique (slug),
constraint FK_84BCFA45A76ED395
foreign key (user_id) references user (id)
)
collate=utf8_unicode_ci
;
create index IDX_84BCFA45A76ED395
on poll (user_id)
;
create table if not exists vote
(
id int auto_increment
primary key,
poll_id int not null,
user_id int not null,
created_at datetime not null,
is_current_vote tinyint(1) not null,
constraint FK_5A1085643C947C0F
foreign key (poll_id) references poll (id),
constraint FK_5A108564A76ED395
foreign key (user_id) references user (id),
)
collate=utf8_unicode_ci
;
create index IDX_5A1085643C947C0F
on vote (poll_id)
;
create index IDX_5A108564A76ED395
on vote (user_id)
;
我在 MySQL 中使用此查询,它提供了我想要的数据:
select poll.id, poll.slug, poll.question, poll.created_at,
u.id, u.username, u.slug, u.profile_picture,
sum(case when v.is_current_vote = true then 1 else 0 end) as total_votes
from poll
left join user u on poll.user_id = u.id
left join vote v on poll.id = v.poll_id
group by poll.id
order by total_votes desc
数据应按票数排序,其中 "v.is_current_vote=true"。
示例数据(省略了上面的一些列以便于阅读):
poll.question, u.username, total_votes
Is Elvis Alive?, someone, 15
Is the future bright?, someone_else, 10
Is this all a dream?, another_user, 5
是否可以在 Symfony/Doctrine QueryBuilder 语句中做类似的事情,或者我是否必须使用 Native SQL?我也不知道该怎么做。如果能提供一些指导,我将不胜感激。
这是我当前的本机 SQL 尝试,我从 poll
table 中获取行,但投票和用户都是 null
:
/**
* Class PollRepository
* @package PollBundle\Repository
*/
class PollRepository extends EntityRepository
{
/**
* @return \Doctrine\ORM\NativeQuery
*/
public function findPopular()
{
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('PollBundle\Entity\Poll', 'poll');
$rsm->addJoinedEntityFromClassMetadata('PollBundle\Entity\User', 'u', 'poll', 'user', [
'id' => 'user_id',
'slug' => 'user_slug',
'created_at' => 'user_created_at',
'updated_at' => 'user_updated_at',
'is_active' => 'user_is_active',
]);
$rsm->addJoinedEntityFromClassMetadata('PollBundle\Entity\Vote', 'v', 'poll', 'votes', [
'id' => 'vote_id',
'user_id' => 'vote_user_id',
'created_at' => 'vote_created_at',
'updated_at' => 'vote_updated_at',
]);
$sql = '
SELECT poll.id, poll.slug, poll.question, poll.created_at,
u.id, u.username, u.slug, u.profile_picture,
sum(case when v.is_current_vote = true then 1 else 0 end) as total_votes
from poll
left join user u on poll.user_id = u.id
left join vote v on poll.id = v.poll_id
group by poll.id
order by total_votes desc
';
return $this->_em->createNativeQuery($sql, $rsm)->getResult();
}
}
您是否尝试过与此查询类似的查询? Doctrine 几乎可以做 SQL 可以做的所有事情。
$query = $this->createQueryBuilder('p')
->select('p.question, u.username, count(v.isCurrentVote) AS votes')
// joins maybe need change depending on your relations
->leftJoin('p.user', 'u')
->leftJoin('p.votes', 'v')
->groupBy('p.id')
->orderBy('votes');
return $query->getQuery()->getResult();
我想 select 来自 poll
table 的行,并按连接 vote
table 的行数或总和对它们进行排序其中 vote.is_current_vote = true
.
投票 table 跟踪所有投票,但投票中只计算每个用户的最新投票,标记为 is_current_vote
。
我正在努力研究如何使用 Doctrine Query Builder 或 Native Query 来计算投票数 table。
数据库结构如下:
create table if not exists user
(
id int auto_increment
primary key,
username varchar(45) not null,
slug varchar(45) not null,
created_at datetime not null,
updated_at datetime null,
constraint UNIQ_8D93D649989D9B62
unique (slug),
constraint UNIQ_8D93D649F85E0677
unique (username)
)
collate=utf8_unicode_ci
;
create table if not exists poll
(
id int auto_increment
primary key,
user_id int null,
question varchar(140) not null,
slug varchar(140) not null,
is_active tinyint(1) not null,
created_at datetime not null,
updated_at datetime null,
constraint UNIQ_84BCFA45989D9B62
unique (slug),
constraint FK_84BCFA45A76ED395
foreign key (user_id) references user (id)
)
collate=utf8_unicode_ci
;
create index IDX_84BCFA45A76ED395
on poll (user_id)
;
create table if not exists vote
(
id int auto_increment
primary key,
poll_id int not null,
user_id int not null,
created_at datetime not null,
is_current_vote tinyint(1) not null,
constraint FK_5A1085643C947C0F
foreign key (poll_id) references poll (id),
constraint FK_5A108564A76ED395
foreign key (user_id) references user (id),
)
collate=utf8_unicode_ci
;
create index IDX_5A1085643C947C0F
on vote (poll_id)
;
create index IDX_5A108564A76ED395
on vote (user_id)
;
我在 MySQL 中使用此查询,它提供了我想要的数据:
select poll.id, poll.slug, poll.question, poll.created_at,
u.id, u.username, u.slug, u.profile_picture,
sum(case when v.is_current_vote = true then 1 else 0 end) as total_votes
from poll
left join user u on poll.user_id = u.id
left join vote v on poll.id = v.poll_id
group by poll.id
order by total_votes desc
数据应按票数排序,其中 "v.is_current_vote=true"。
示例数据(省略了上面的一些列以便于阅读):
poll.question, u.username, total_votes
Is Elvis Alive?, someone, 15
Is the future bright?, someone_else, 10
Is this all a dream?, another_user, 5
是否可以在 Symfony/Doctrine QueryBuilder 语句中做类似的事情,或者我是否必须使用 Native SQL?我也不知道该怎么做。如果能提供一些指导,我将不胜感激。
这是我当前的本机 SQL 尝试,我从 poll
table 中获取行,但投票和用户都是 null
:
/**
* Class PollRepository
* @package PollBundle\Repository
*/
class PollRepository extends EntityRepository
{
/**
* @return \Doctrine\ORM\NativeQuery
*/
public function findPopular()
{
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('PollBundle\Entity\Poll', 'poll');
$rsm->addJoinedEntityFromClassMetadata('PollBundle\Entity\User', 'u', 'poll', 'user', [
'id' => 'user_id',
'slug' => 'user_slug',
'created_at' => 'user_created_at',
'updated_at' => 'user_updated_at',
'is_active' => 'user_is_active',
]);
$rsm->addJoinedEntityFromClassMetadata('PollBundle\Entity\Vote', 'v', 'poll', 'votes', [
'id' => 'vote_id',
'user_id' => 'vote_user_id',
'created_at' => 'vote_created_at',
'updated_at' => 'vote_updated_at',
]);
$sql = '
SELECT poll.id, poll.slug, poll.question, poll.created_at,
u.id, u.username, u.slug, u.profile_picture,
sum(case when v.is_current_vote = true then 1 else 0 end) as total_votes
from poll
left join user u on poll.user_id = u.id
left join vote v on poll.id = v.poll_id
group by poll.id
order by total_votes desc
';
return $this->_em->createNativeQuery($sql, $rsm)->getResult();
}
}
您是否尝试过与此查询类似的查询? Doctrine 几乎可以做 SQL 可以做的所有事情。
$query = $this->createQueryBuilder('p')
->select('p.question, u.username, count(v.isCurrentVote) AS votes')
// joins maybe need change depending on your relations
->leftJoin('p.user', 'u')
->leftJoin('p.votes', 'v')
->groupBy('p.id')
->orderBy('votes');
return $query->getQuery()->getResult();