1

我需要使用与另一个表有很多关系的类别表过滤我的查询。是否可以使用 many2many 关系过滤查询?

Tableres_partner有 many2manycategory_id与 table 相关的字段res_partner_category.res_partner,或者说合作伙伴可以有很多类别。我需要的是过滤res_partners具有“商业”或“零售”类别的表。如果它没有任何这些类别,则不应显示。

还有另一个领域res_partnercategory_value_ids并且与 有one2many关系res_partners_category_value

res_partner具有以下具有关系的字段:

  • category_idres_partner_category(many2many)
  • category_value_idsres_partner_category_value(one2many)
  • name(字符)

res_partner_category具有以下具有关系的字段:

  • partner_idsres_partner(many2many)
  • name(字符)

res_partner_category_value具有以下具有关系的字段:

  • category_group_idres_partner_category(many2one)
  • category_idres_partner_category(many2one)
  • object_idres_partner(many2one)

但是,如果我尝试res_partner_category_value在 SQL 查询中使用表,则会收到无法在查询中使用它的错误。

例如,如果有 4 个合作伙伴属于这些类别:

  • 第一个:categ1,categ2,业务
  • 第二:零售
  • 第三:零售、商业
  • 第四:categ1,categ2

查询应返回第一、第二和第三伙伴。
一个人告诉我,不可能像这样使用 many2many 关系进行过滤。所以我想知道这真的不可能还是很复杂?

编辑:
我又发现了一张名为res_partner_category_rel. 我没有看到它,因为在 Openerp 管理界面中,您可以看到数据库的所有对象,但没有显示该表。您只能通过数据库直接看到它。所以我对这个“缺失”的表感到困惑:

res_partner_category_rel:

  • partner_id(多人)
  • category_id(多人)
4

2 回答 2

5

这是您应该提供的测试用例:

CREATE TABLE partner (
  partner_id serial PRIMARY KEY
, partner    text
);
INSERT INTO partner (partner) VALUES 
  ('partner1')
, ('partner2')
, ('partner3')
, ('partner4')
;    
CREATE TABLE category (
  category_id serial PRIMARY KEY
, category    text
);
INSERT INTO category (category) VALUES 
  ('categ1')
 ,('categ2')
 ,('business')
 ,('retail');

CREATE TABLE partner_category (
  partner_id  int REFERENCES partner(partner_id)
, category_id int REFERENCES category(category_id)
, CONSTRAINT cat_pk PRIMARY KEY (partner_id, category_id)
);
INSERT INTO partner_category (partner_id, category_id) VALUES 
   (1,1), (1,2), (1,3)
  ,(2,4)
  ,(3,3), (3,4)
  ,(4,1), (4,2);

这是您所追求的查询(许多可能的变体之一):

SELECT p.*
FROM   partner p
WHERE  EXISTS (SELECT * FROM partner_category pc
               WHERE  pc.partner_id = p.partner_id AND pc.category_id = 3)
OR     EXISTS (SELECT * FROM partner_category pc
               WHERE  pc.partner_id = p.partner_id AND pc.category_id = 4)
ORDER  BY p.partner_id;

SQL小提琴。

这里的关键词是关系划分。我们已经组装了一个完整的查询库来处理这个相关问题下的这类问题:

于 2012-11-06T20:44:01.267 回答
2

正如您已经注意到的,many2onecategory_id在数据库中并没有表示为表字段,而是表示为与合作伙伴和类别相关的表。

您需要的 SQL 可能如下所示:

SELECT p.* 
FROM res_partner p
  INNER JOIN res_partner_category_rel rel ON p.id = rel.partner_id
    INNER JOIN res_partner_category c ON rel.category_id = c.id
WHERE c.id in (3,4)

如果你想在 python 对象中进行过滤,通常的search调用应该可以工作:

list_ids = partner_model.search(cr, uid, [('category_id', 'in', [3,4])])

作为奖励,由于类别是按树组织的,您可以使用以下方式获取这些类别及其所有子类别:

list_ids = partner_model.search(cr, uid, [('category_id', 'child of', [3,4])])
于 2012-11-07T14:49:32.703 回答