问题定义。
我有多个拥有多个用户的客户端。每个客户端都需要能够将自定义数据与用户,搜索和订单相关联。
数据库解决方案:
定义customfields表的Customfields表。它有一个id和名字。 它与Userfields表(又名“属性”)有一个has_many关系。
Userfields表具有userid,customfieldid,content和id。 它属于Useraccounts表(又名“useraccount”)和Customfields(又名“customfield”)
我想要的选择陈述:
这是一个实现并生成我需要的选择语句。
SELECT ua.*, (
SELECT content FROM Userfields uf
INNER JOIN Customfields cf
ON cf.id = uf.customfieldid
WHERE cf.name = 'Mothers birthdate'
AND uf.uid=ua.uid
) AS 'Mothers birthdate',
(
SELECT content FROM Userfields uf
INNER JOIN Customfields cf
ON cf.id = uf.customfieldid
WHERE cf.name = 'Join Date' AND
uf.uid=ua.uid
) AS 'Join Date'
FROM UserAccounts ua
ORDER BY 'Mothers birthdate';
在这种情况下,它们可以是选择语句中的0 ... x子选择语句中的任何一个,也可以是其中任何一个,或者它们都不想被排序。
问题
如何使用 - >搜索我的dbix类结果集来实现这一点,或者如何通过搜索我的dbix类结果集来实现相同的结果?
以下是我通常从Useraccounts表中选择的方法,虽然我不确定如何从这里做我想要的复杂语句。
my @users = $db->resultset('Useraccounts')->search(
undef,
{
page => $page,
join => 'attributes',
...
});
感谢您的时间。
-pdh
答案 0 :(得分:2)
这真的很毛茸茸,而且任何解决方案都不会很漂亮,但如果你稍微改变一下规则, 看起来是可行的。原谅我犯的任何错误,因为我没有去创建一个架构来测试它,但它基于我所拥有的最佳信息(以及来自ribasushi的大量帮助)。
首先,(假设您的userfields表与customfields表有一个belongs_to关系,称为customfield
)
my $mbd = $userfields_rs->search(
{
'customfield.name' => 'Mothers birthdate',
'uf.uid' => \'me.uid' # reference to outer query
},
{
join => 'customfield',
alias => 'uf', # don't shadow the 'me' alias here.
}
)->get_column('content')->as_query;
# Subqueries and -as don't currently mix, so hack the SQL ourselves
$mbd->[0] .= q{ AS 'Mothers Birthdate'};
与uf.uid匹配的文字me.uid
是一个未绑定的变量 - 它是查询中的uid
字段,我们最终将此查询作为子选择。默认情况下,DBIC将查询要寻址的表别名为me
;如果你给它一个不同的别名,那么你会在这里使用不同的东西。
无论如何,您可以根据需要重复这个as_query
业务,只需更改字段名称(如果您很聪明,您将编写一个方法来生成它们),并将它们放入数组,现在让我们假设@field_queries
是一个数组,包含$mbd
以及另一个基于连接日期的数组,以及您喜欢的任何内容。
一旦你拥有了它,就像......一样“简单”。
my $users = $useraccounts_rs->search(
{ }, # any search criteria can go in here,
{
'+select' => [ @field_queries ],
'+as' => [qw/mothers_birthdate join_date/], # this is not SQL AS
order_by => {-asc => 'Mothers birthdate'},
}
);
将每个子查询包含在select中。
现在可悲的是:截至目前,实际上 实际上将不会工作,因为带有占位符的子查询无法正常工作。所以现在你需要一个额外的解决方法:在子选择搜索中代替'customfield.name' => 'Mothers birthdate'
,执行'customfield.name' => \q{'Mothers birthdate'}
- 这是使用文字SQL作为字段名称(SQL的很小心)注入这里!),它将回避占位符错误。但是在不久的将来,这个bug将被解决,上面的代码也可以正常工作,我们会更新答案让你知道情况。
请参阅DBIx :: Class :: ResultSource order_by documentation