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

标签 perl dbix-class

问题定义。

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


数据库解决方案:

定义自定义字段表的自定义字段表。它有一个 ID 和名称。 它与 Userfields 表(也称为“属性”)具有 has_many 关系。

Userfields 表有一个 userid、customfieldid、content 和 id。 它属于 Useraccounts 表(又名“useraccount”)和 Customfields(又名“customfield”)


我想要的建议选择语句:

这是一个 select 语句,可以实现并生成我需要的内容。

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 select 语句中的子 select 语句中的任何内容,并且它们中的任何一个或它们都不希望被排序。


问题

如何通过对我的 dbix 类结果集进行搜索来实现这一点,或者如何通过对我的 dbix 类结果集进行搜索来实现相同的结果?

这是我通常从我的 Useraccounts 表中选择的方式,尽管我不确定如何从这里执行我想要的复杂语句。

my @users = $db->resultset('Useraccounts')->search(
    undef,
    {
        page        => $page,
        join        => 'attributes',
        ...
    });

感谢您的宝贵时间。

-pdh

最佳答案

这真的很棘手,任何解决方案都不会很好,但如果您稍微改变一下规则,它确实看起来是可能的。请原谅我犯的任何错误,因为我没有去创建一个模式来测试它,但它基于我拥有的最佳信息(以及来自 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 是一个未绑定(bind)的变量——它是我们最终要查询的 uid 字段将此查询作为子选择放入。默认情况下,DBIC 为查询寻址的表别名 me;如果你给它一个不同的别名那么你会在这里使用不同的东西。 无论如何,您可以使用尽可能多的不同字段重复此 as_query 业务,只需更改字段名称(如果您很聪明,您将编写一个方法来生成它们),然后将它们在一个数组中,所以现在让我们假设 @field_queries 是一个数组,包含上面的 $mbd 以及另一个基于 Join Date 的数组,以及您喜欢的任何内容。

一旦你有了它,它就像......一样“简单”

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'},
    }
);

这会将每个子查询包含到选择中。

现在可悲的是:截至目前,这整件事实际上不会起作用,因为带有占位符的子查询不能正常工作。所以现在你需要一个额外的解决方法:代替 'customfield.name' => 'Mothers birthdate' 在子选择搜索中,做 'customfield.name' =>\q{'Mothers birthdate'}——这是对字段名称使用文字 SQL(请注意此处的 SQL 注入(inject)!),这将避免占位符错误。但在不久的将来,该错误将得到解决,上面的代码将正常运行,我们将更新答案,让您知道是这种情况。

参见 DBIx::Class::ResultSource order_by documentation

关于perl - 我如何在 DBIx::Class::ResultSet 上执行此搜索和 order_by,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3429764/

相关文章:

java - 在 html 中显示 sqlite 数据库查询

bash - sh : 1: Syntax error: redirection unexpected when using backticks perl

sql - Perl:DBIx::Class 初学者 - 子集关系和预取

mysql - DBIx::Class 基结果类

perl - 使用DBIX::Class时驼鹿触发器不触发

perl - 如何克隆 DateTime 对象

perl - 给定/何时存在什么样的简洁用例?

perl - 如何在 DBIx::Class 中获取表的类名

mysql - Perl DBIx::Class::ResultSet 不同值

mysql - 如何将数组的一部分插入MySQL?