2014-02-12 68 views
0

我不明白为什么这个查询返回"Music"如果我指定t3.name = 'Games'。它应该返回"Games"。任何想法?为什么这个PostgreSQL查询不显示“游戏”结果

Ad Load (1.9ms) SELECT "ads".* FROM "ads" INNER JOIN campaigns as c1 ON (c1.id = ads.campaign_id) INNER JOIN taggings as tg3 ON (tg3.taggable_id = c1.id) INNER JOIN tags as t3 ON (t3.id = tg3.tag_id) WHERE (
t3.name = 'Games' and tg3.context = 'categories') ORDER BY "ads"."id" ASC LIMIT 1 
    Campaign Load (0.4ms) SELECT "campaigns".* FROM "campaigns" WHERE "campaigns"."id" = $1 ORDER BY "campaigns"."id" ASC LIMIT 1 [["id", 2]] 
    ActsAsTaggableOn::Tag Load (0.6ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'categories' AND taggings.tagger_id IS NULL) [["taggable_id", 2], ["taggable_type", "Campaign"]] 
=> ["Music"] 

更新:

只是为了清除查询,我尽量做到的是:选择具有与标记为游戏类别竞选的所有广告。

什么我上面的查询试图做的是

  1. 加入这项运动,标记和标签
  2. 尝试通过标签(t3.name = 'Games')进行查询。但是我得到的结果改为"Music"

数据库架构如下:

Ad 
...  

Campaign 
> ad_id 

Tagging 
> tag_id 
> taggable_id (Campaign id) 
> taggable_type ("Campaign") 
> context ("categories") 

Tag 
> name: (i.e. "Games") 
+0

如果您想快速获得解释/解决方案,请复制表格的完整创建语句,完整查询语句和PostgreSQL版本。 – Houari

回答

1

每个广告可以有多个标签,所以当你请求包含Games标签的广告,还可能会得到与两者的广告 - 在GamesMusic标签。

如果您需要广告包含只有标签Games,那么你需要明确排除其余所有。

SELECT 
    "ads".* 
FROM 
    "ads" INNER JOIN campaigns as c1 
ON 
    (c1.id = ads.campaign_id) 
WHERE 
    c1.id IN (
    SELECT 
     tg3.taggable_id 
    FROM 
     taggings AS tg3 INNER JOIN tags t3 
    ON 
     tg3.tag_id = t3.id 
    WHERE 
     t3.name = 'Games' 
    AND 
     tg3.context = 'categories' 

    EXCEPT 

    SELECT 
     tg3.taggable_id 
    FROM 
     taggings AS tg3 INNER JOIN tags t3 
    ON 
     tg3.tag_id = t3.id 
    WHERE 
     t3.name != 'Games' 
    AND 
     tg3.context = 'categories' 
) 
ORDER BY 
    "ads"."id" ASC 
LIMIT 
    1; 
相关问题