我从这个问题得到了这个mysql查询。
SELECT a.*
FROM products a
INNER JOIN product_tags b ON a.product_id = b.product_id
WHERE b.tag_id IN (1,23,54)
GROUP BY a.product_id
HAVING COUNT(1) = 3
我正试图弄清楚如何将此转换为DBIx::类语法?
从DBIx文档,这是什么说的连接,但我不确定如何合并它?
定义连接和关系^
在DBIx::Class中,两个表之间的每个关系需要首先在表的ResultSource中定义。如果需要在两个方向上访问关系(即获取CD的所有音轨,并获取一个音轨的CD数据),则需要为两个表定义该关系。
对于CD/Tracks示例,这意味着在MySchema::CD:
中写入 MySchema::CD->has_many('tracks', 'MySchema::Tracks');
和MySchema::Tracks:
MySchema::Tracks->belongs_to('cd', 'MySchema::CD', 'CDID');
还有其他几种类型的关系,它们在DBIx::Class::Relationship中有更全面的描述。使用join ^
一旦定义了所有关系,在实际连接中使用它们就相当简单了。您选择的关系类型(例如has_many)已经表明将执行哪种类型的连接。例如,has_many生成一个LEFT JOIN,它将获取左侧的所有行,无论右侧是否有匹配的行(正在连接的表)。您可以在关系中强制使用其他类型的连接,请参阅DBIx::Class:: relationship文档。
在执行搜索或查找操作时,可以使用join属性指定还要基于哪些关系来优化结果,如下所示:
$schema->resultset('CD')->search(
{ 'Title' => 'Funky CD',
'tracks.Name' => { like => 'T%' }
},
{ join => 'tracks',
order_by => ['tracks.id'],
}
);
如果您不认识大多数语法,您可能应该去阅读DBIx::Class::ResultSet中的"search"和DBIx::Class::ResultSet中的"ATTRIBUTES",但这里有一个快速分解:
搜索的第一个参数是WHERE属性的hashref,在本例中是对CD表中Title列的限制,以及对Tracks表中音轨名称的限制,但仅针对与所选CD实际相关的音轨。第二个参数是搜索属性的hashref,返回的结果将按相关曲目的id排序。
首先在product的标签上定义一个rel。
MySchema::Result::Product->has_many(
'tags', 'MySchema::Result::ProductTag', 'product_id'
);
从标签中定义产品的rel:
MySchema::Result::ProductTag->belongs_to(
'products', 'MySchema::Result::Product', 'product_id'
);
顺便说一下,如果您使用的是Schema::Loader,那么应该已经被推断出来了。(无耻的插播:上面的内容用DBIx::Class::Candy和DBIx::Class::Helper::Row::RelationshipDWIM会更短更甜)
现在复制原始查询:
$schema->resultset('Product')->search({
tags.tag_id => { -in => [1,23,54] },
}, {
join => 'tags',
group_by => 'me.product_id',
having => { 'count 1' => 3 },
})