0

私はこのテーブルをセットアップしています(簡略化):

ads
 - id
 - brand_id

brands
 - id

tags
 - taggable_type
 - taggable_id
 - tag

タグ テーブルの taggable_type は「Ad」または「Brand」のいずれかになり、taggable_id はそれぞれ ad_id または brand_id を識別し、タグは文字列になります。

広告はブランドのタグを継承します。特定のタグ セットの広告セットを取得する検索クエリを作成しようとしています。これらのタグは、広告自体またはその広告に関連付けられたブランドのいずれかに属しています。

これらのテーブルはすべてかなり大きくなる可能性があるため、効率的にする必要があります。

これが私が持っているものです(これは機能していません)

SELECT
  a.*
FROM
  ads a
JOIN
  ((
    SELECT
      *
    FROM
      tags
    WHERE
      tag IN ({$tags})
      AND taggable_type = "Ad"
  ) t FULL JOIN (
    SELECT
      *
    FROM
      tags
    WHERE
      tag IN ({$tags})
      AND taggable_type = "Brand"
  )) tt
  ON (t.taggable_id = a.id) OR (tt.taggable_id = a.brand_id);

まず、完全結合でエラーが発生します。内部結合と左結合も試しましたが、まだ機能していません。根本的にばかげたことをしているように感じます。何か助けはありますか?

4

1 に答える 1

1

このように動作するはずです

SELECT DISTINCT
  ads.*
FROM
  ads
  LEFT JOIN brands
    ON ads.brand_id = brands.id
  INNER JOIN tags
    ON (
      tags.taggable_type = 'brand'
      AND brands.id = tags.taggable_id)
    OR (
      tags.taggable_type = 'ad'
      and ads.id = tags.taggable_id)
WHERE
  tags.tag IN ('tag 1', 'tag 2', 'tag 7')

SQL フィドル

しかし、データベースの構造についてもう一度考えた方がよいかもしれません。おそらく、次のような設定の方が適しているでしょう。

ads(id, brand_id)
brands(id)
tags(id)
tags_ads(tag_id, ad_id)
tags_brands(tag_id, brand_id)

タグを複数のブランドまたは広告に割り当てることができるという利点があります。またはブランドと広告に...

于 2013-03-01T21:58:50.727 に答える