2014-02-12 67 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; 
相關問題