如何在 SELECT 部分使用 DBIx::Class 的子查询?
How do I use a sub query in the SELECT part with DBIx::Class?
请帮助在 DBIx::Class
中编写此 MySQL 查询(以提供有关如何在 DBIx::Class
中使用子查询的示例):
SELECT x, (SELECT COUNT(*) FROM t2 WHERE t2.y=x) AS c FROM t1 WHERE t1.z=123
(我知道它可以用 GROUP BY
重写为 JOIN
,但我想要的是子查询(举个例子让我动手)。)
DBIx::Class
文档对在 WHERE
子句中使用子查询进行了广泛的审查,但我没有找到如何在 SELECT
字段列表中使用子查询(如上例所示) ).
你走在正确的轨道上。子查询上的 as_query
is what you need. But you also need the columns
option in the second hashref. Make sure you use count_rs
,它翻转内部开关以生成其中包含 COUNT(*)
的结果集。
my $obj = ResultSet('TableOne')->search(
{
z => 123,
},
{
columns => [
'x',
{
c => ResultSet('TableTwo')->search(
{
'y' => {
-ident => 'me.x',
},
},
{
alias => 'sub_query', # this name is arbitrary
},
)->count_rs->as_query,
},
],
}
)->first;
生成的查询将如下所示:
SELECT me.x, (
SELECT COUNT( * )
FROM table_two sub_query
WHERE y = me.x
)
FROM table_one me
WHERE me.z = 123
如您所见,我们通过子查询选择的值在 SQL 中不称为 c
,但在对象的数据中称为 c
。
use DDP;
p $obj;
DB::Result::TableOne {
# ...
internals: {
_column_data {
x "foo",
c "bar"
},
_in_storage 1,
_result_source DBIx::Class::ResultSource::Table
}
}
您可以在行对象上使用 get_column
访问它。
say $obj->get_column('c');
# bar
在 prefetch
的情况下你想要 select 子查询结果你必须命名你的子查询,否则你会得到错误(参见 simbabque 的 下的注释)
my $partial = $c->model( 'ServicePackageSet' )->search([
{ service_type_id_covered => { -ident => 'me.id' } },
{ service_type_id_surplus => { -ident => 'me.id' } },
],{ select => });
my $pricelist = $c->model( 'ServiceTree' )->search({
},{
'+select' => { exists => $partial->as_query },
'+as' => [ 'partial' ],
prefetch => [qw/ Price Package /],
order_by => [qw/ Package.short_name name /],
});
尽管如果您想使用子查询作为过滤器,它无需命名也可以工作:
my $pricelist = $c->model( 'ServiceTree' )->search({
-not_exists => $partial->as_query
},{
prefetch => [qw/ Price Package /],
order_by => [qw/ Package.short_name name /],
});
请帮助在 DBIx::Class
中编写此 MySQL 查询(以提供有关如何在 DBIx::Class
中使用子查询的示例):
SELECT x, (SELECT COUNT(*) FROM t2 WHERE t2.y=x) AS c FROM t1 WHERE t1.z=123
(我知道它可以用 GROUP BY
重写为 JOIN
,但我想要的是子查询(举个例子让我动手)。)
DBIx::Class
文档对在 WHERE
子句中使用子查询进行了广泛的审查,但我没有找到如何在 SELECT
字段列表中使用子查询(如上例所示) ).
你走在正确的轨道上。子查询上的 as_query
is what you need. But you also need the columns
option in the second hashref. Make sure you use count_rs
,它翻转内部开关以生成其中包含 COUNT(*)
的结果集。
my $obj = ResultSet('TableOne')->search(
{
z => 123,
},
{
columns => [
'x',
{
c => ResultSet('TableTwo')->search(
{
'y' => {
-ident => 'me.x',
},
},
{
alias => 'sub_query', # this name is arbitrary
},
)->count_rs->as_query,
},
],
}
)->first;
生成的查询将如下所示:
SELECT me.x, (
SELECT COUNT( * )
FROM table_two sub_query
WHERE y = me.x
)
FROM table_one me
WHERE me.z = 123
如您所见,我们通过子查询选择的值在 SQL 中不称为 c
,但在对象的数据中称为 c
。
use DDP;
p $obj;
DB::Result::TableOne {
# ...
internals: {
_column_data {
x "foo",
c "bar"
},
_in_storage 1,
_result_source DBIx::Class::ResultSource::Table
}
}
您可以在行对象上使用 get_column
访问它。
say $obj->get_column('c');
# bar
在 prefetch
的情况下你想要 select 子查询结果你必须命名你的子查询,否则你会得到错误(参见 simbabque 的
my $partial = $c->model( 'ServicePackageSet' )->search([
{ service_type_id_covered => { -ident => 'me.id' } },
{ service_type_id_surplus => { -ident => 'me.id' } },
],{ select => });
my $pricelist = $c->model( 'ServiceTree' )->search({
},{
'+select' => { exists => $partial->as_query },
'+as' => [ 'partial' ],
prefetch => [qw/ Price Package /],
order_by => [qw/ Package.short_name name /],
});
尽管如果您想使用子查询作为过滤器,它无需命名也可以工作:
my $pricelist = $c->model( 'ServiceTree' )->search({
-not_exists => $partial->as_query
},{
prefetch => [qw/ Price Package /],
order_by => [qw/ Package.short_name name /],
});