如何在DBIx :: Class :: ResultSet上执行此搜索和order_by

时间:2010-08-07 08:39:35

标签: perl dbix-class

问题定义。

我有多个拥有多个用户的客户端。每个客户端都需要能够将自定义数据与用户,搜索和订单相关联。


数据库解决方案:

定义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

1 个答案:

答案 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