Many-to-many relation filter

前端 未结 2 1995
萌比男神i
萌比男神i 2021-01-16 06:50

I need to filter my query with categories table which has many2many relation with another table. Is it possible to filter query with many2many relation?

Table

相关标签:
2条回答
  • 2021-01-16 06:56

    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:

    • How to filter SQL results in a has-many-through relation
    0 讨论(0)
  • 2021-01-16 07:03

    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])])
    
    0 讨论(0)
提交回复
热议问题