1

別のテーブルとmany2manyの関係があるcategoriesテーブルでクエリをフィルタリングする必要があります。many2manyリレーションを持つクエリをフィルタリングすることは可能ですか?

テーブルには、テーブルに関連するres_partnermany2manyフィールドがあります。または、パートナーが多くのカテゴリを持つことができるとしましょう。必要なのは、 「business」または「retail」という名前のカテゴリを持つテーブルをフィルタリングすることです。これらのカテゴリのいずれも含まれていない場合は、表示されません。category_idres_partner_category.res_partnerres_partners

また、 :と関係がある別のフィールドがres_partnerあります。category_value_idsone2manyres_partners_category_value

res_partner関係のある次のフィールドがあります。

  • category_idto res_partner_category(many2many)
  • category_value_idsto res_partner_category_value(one2many)
  • name(char)

res_partner_category関係のある次のフィールドがあります。

  • partner_idsto res_partner(many2many)
  • name(char)

res_partner_category_value関係のある次のフィールドがあります。

  • category_group_idto res_partner_category(many2one)
  • category_idto res_partner_category(many2one)
  • object_idto res_partner(many2one)

しかしres_partner_category_value、SQLクエリでテーブルを使用しようとすると、クエリで使用できないというエラーが発生します。

したがって、たとえば、これらのカテゴリのパートナーが4つある場合:

  • 最初:categ1、categ2、business
  • 2番目:小売
  • 3番目:小売、ビジネス
  • 4番目:categ1、categ2

クエリは、第1、第2、および第3のパートナーを返す必要があります。
ある人は、many2manyの関係でこのようにフィルタリングすることは不可能だと私に言いました。それで、それは本当に不可能なのか、それとも単に複雑なのかしら。

編集:
私はと呼ばれるもう1つのテーブルを見つけましres_partner_category_relた。データベースのすべてのオブジェクトを表示できるOpenerp管理インターフェイスでは、そのテーブルが表示されないため、表示されませんでした。あなたはそれをデータベースを通して直接見ることができるだけです。だから私はこの「欠けている」テーブルに混乱しました:

res_partner_category_rel:

  • partner_id(many2one)
  • category_id(many2one)
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);

そして、これはあなたが求めているクエリです(多くの可能なバリアントの1つ):

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 に答える