2013-03-01 79 views
0

我有此表的设置(简体):MySQL的外键多联接

ads 
- id 
- brand_id 

brands 
- id 

tags 
- taggable_type 
- taggable_id 
- tag 

在标签表中的taggable_type值可以是“广告”或“品牌”,在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); 

对于初学者来说,我得到的完全错误加入。我也尝试了一个内连接和一个左连接,但它仍然无法工作。我觉得我只是在做一些根本上愚蠢的事情。任何帮助?

+0

你可以发布一些示例数据为每个表,然后查询所需的结果? – Taryn 2013-03-01 21:42:40

回答

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 Fiddle

但你可能还需要重新考虑你的数据库结构。 也许像下面这样的设置会更适合你。

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

将能够将标签分配给多个品牌或广告的好处。或对一个品牌和一个广告...

+0

谢谢hsan,这是个好主意 – 2013-03-01 23:02:34