Many-to-many relation filter

核能气质少年 提交于 2019-12-01 11:57:26
Erwin Brandstetter

This is the test case you should have provided:

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);

And this is the query you are after (one of many possible variants):

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 Fiddle.

The key word here is relational division. We have assembled a whole arsenal of queries to deal with this class of problems under this related question:

As you already noticed, the many2one category_id is not represented in the database as a table field, but as a table relating Partners and Categories.

The SQL you need could look like this:

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)

If you want to do the filter in the python object, the usual searchcall should work:

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

As a bonus, since Categories are organized in a tree, you could get those categories and all their children using:

list_ids = partner_model.search(cr, uid, [('category_id', 'child of', [3,4])])
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!