2017-05-31 10 views
1

私は2つのシンプルなテーブルを持っています。最初はブランドであり、各ブランドはトップブランドを持つ場合があります。例えば、ElseveはLoreal Parisというトップブランドを持っています。しかし、エイボンにはトップブランドはありません。私はシンプルな製品テーブルを持っています。ここでPostgres tsvector with relational tables

はここsqlfiddle

は、ブランドのテーブルです。

id |  name  | parent_id | depth 
----+--------------+-----------+------- 
    3 | Loreal Paris |  null |  0 
    1 | Avon   |  null |  1 
    2 | Elseve  |  3 |  1 
(3 rows) 

そして、ここで私はtsvectorsを取得しようとすると製品テーブル

id | brand_id | name 
----+----------+----------- 
    1 |  1 | Product 1 
    2 |  2 | Product 2 
(2 rows) 

は、製品1文書はヌル結果を返します。しかし、少なくとも私はこの文書の中でAvonを取得する必要があります。

product_id | product_name |      document 
------------+--------------+-------------------------------------------------- 
      1 | Product 1 | 
      2 | Product 2 | '2':2 'elsev':3 'loreal':4 'paris':5 'product':1 
(2 rows) 

この問題を解決するにはどうすればよいですか?

Voa Tsunに感謝します。私はクエリを少し更新しました。私はもうグループ化する必要はありません。

select 
    products.id as product_id, 
    products.name as product_name, 
    to_tsvector(products.name) || 
    to_tsvector(brands.name) || 
    to_tsvector(top_brands.name) 
    as document 
from products 
    JOIN brands on brands.id = products.brand_id 
    LEFT JOIN brands as top_brands on coalesce(brands.parent_id,brands.id) = top_brands.id; 
+0

あなたは 'NULL'入力の' COALESCE() 'どこか、理由は' to_tsvector() ''を返しますNULL'を使用する必要があります。 f.exを参照してください。 [ドキュメントで複数の列を使用する方法](https://www.postgresql.org/docs/current/static/textsearch-controls.html) – pozs

+0

http://rextester.com/SQVSTS56141ここですか?.. –

+0

こんにちは@pozs。私はすでにそれを使用しました。このようにto_tsvector(coalesce(string_agg(top_brands.name、 ''))))。私はそれが論理的ではないことを知っている。 Avonのtop_brandレコードが存在しないためです。それは役に立たない。 top_brandをすべてのブランドに追加し、top_brandを持たないブランドのtop_brand名のレコードを空にすると、動作します。 –

答えて

1

私はあなたのポストからもらったような基本的な考え方は、「PARENT_ID」でNOT NULLに対してIDに参加することですが、「少なくともIDに対して」。ここのような :

select 
     products.id as product_id, 
     products.name as product_name, 
     to_tsvector(coalesce(products.name,brands.name)) || 
     to_tsvector(brands.name) || 
     to_tsvector(coalesce(string_agg(top_brands.name, ' '))) 
     as document 
    from products 
     JOIN brands on brands.id = products.brand_id 
     LEFT JOIN brands as top_brands on coalesce(brands.parent_id,brands.id) = 
    top_brands.id 
    GROUP BY products.id,brands.id; 

    product_id product_name document 
1 1 Product 1 '1':2'avon':3,4'product':1 
2 2 Product 2 '2':2'elsev':3'loreal':4'pari':5'product':1 
+0

はい。それは魅力のように働く。 –