首页 > 解决方案 > 如何在带有 DBIx::Class 的 SELECT 部分中使用子查询?

问题描述

请帮助编写这个 MySQL 查询DBIx::Class(有一个关于如何使用子查询的例子DBIx::Class):

SELECT x, (SELECT COUNT(*) FROM t2 WHERE t2.y=x) AS c FROM t1 WHERE t1.z=123

(我知道它可以重写为JOINwith GROUP BY,但我想要子查询(例如,让我动手)。)

DBIx::Class文档对在子句中使用子查询进行了广泛的审查,WHERE但我没有找到如何在SELECT字段列表中使用子查询(如上例所示)。

标签: mysqlsqlperlsubquerydbix-class

解决方案


你走在正确的轨道上。这as_query就是你需要的。但是您还需要第二个 hashref 中的columns选项。确保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

如您所见,我们通过子查询选择的值并没有c在 SQL 中调用,而是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_columnrow 对象访问它。

say $obj->get_column('c');
# bar

推荐阅读