我正在尝试在Catalyst应用程序中使用DBIx :: Class来创建一个将在交叉表列表中生成结果的SQL语句。这是我试图生成的SQL的一个例子。
select * from crosstab('
select event_member_id, round, gross from results where event_id = 21 and round = 6 or round = 7 order by 1, 2')
AS results(player integer, Saturday integer, Sunday integer)
;
我试图创建一个名为cross_tab的自定义方法,如下所示:
sub cross_tab {
my $self = shift;
my $attributes = shift || {};
$attributes->{'select'} = "* from crosstab('
select event_member_id, round, gross from results where
event_id = 21 and
round = 6 or round = 7
order by 1, 2')"
;`enter code here`
$attributes->{'as'} = [
'results(player integer, Saturday integer, Sunday integer)',
];
return $self->search({}, $attributes);
}
这会创建如下所示的SQL:
SELECT me.* from crosstab('
select event_member_id, round, gross from results where
event_id = 21 and
round = 6 or round = 7
order by 1, 2')
FROM results me;
这是相当接近的,但我不想要" me"在开头附加,我也不想添加添加FROM语句" FROM结果我"。我认为这是通过搜索方法添加的。
除了"搜索"还有更好的DBIx :: Class方法吗?或者有没有办法告诉DBIx :: Class不要添加附加子句?
答案 0 :(得分:0)
我不确定你为什么不想要'我'在那里。 DBIC总是添加它,并且它不会妨碍在处理结果集中的数据时过滤掉它。
最简单的方法是获得你想做的事可能是创建一个virtual view。然后,您可以在该视图中定义确切的查询,并直接在结果源上选择,就像它是模式中的任何其他表一样。
您也可以使用反向引用的字符串语法(\'sql literal'
)通过子查询和一些自定义SQL实现类似的结果,尽管总而言之它会更难。
这样的事情应该做:
package MyApp::Schema::Result::VirtualCrosstab;
use base qw/DBIx::Class::Core/;
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
__PACKAGE__->table('virtual_crosstab');
__PACKAGE__->result_source_instance->is_virtual(1);
__PACKAGE__->result_source_instance->view_definition(qq[
select * from crosstab(
select event_member_id, round, gross
from results
where event_id = 21 and round = 6 or round = 7 order by 1, 2
)
AS results(player integer, Saturday integer, Sunday integer)
;
]);
__PACKAGE__->add_columns(
'player' => {
data_type => 'integer',
is_auto_increment => 1,
},
'saturday' => {
data_type => 'integer',
},
'sunday' => {
data_type => 'integer',
},
);
1;