0

我有这个表设置(简化):

ads
 - id
 - brand_id

brands
 - id

tags
 - taggable_type
 - taggable_id
 - tag

tags 表中的 taggable_type 将是“Ad”或“Brand”,taggable_id 将分别标识 ad_id 或 brand_id,然后 tag 是一个字符串。

广告继承了他们的品牌标签,我正在尝试编写一个搜索查询,为给定的一组标签提取一组广告,其中这些标签属于广告本身或与该广告关联的品牌。

这些表都可能相当大,所以我需要它高效。

这是我所拥有的(这不起作用)

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 回答