2015-05-01 50 views
1

這可能是一個愚蠢的問題,但它讓我難倒了。我基本上使用3個表來提取Campaign和Team的詳細信息(如下)。如何將查詢結果限制爲僅重複?

SELECT  GOLD.CAMPAIGN_ID, 
      TEAM.ID, 
      TEAM.NAME 
FROM  CAMPAIGN_ANALYTICS_GOLD GOLD 
LEFT JOIN ENTITY ENT 
ON   ENT.CAMPAIGN_ID = GOLD.CAMPAIGN_ID 
LEFT JOIN TEAM TEAM 
ON   TEAM.ID = ENT.TEAM_ID 
GROUP BY GOLD.CAMPAIGN_ID, 
      GOLD.CAMPAIGN_NAME, 
      TEAM.ID, 
      TEAM.NAME; 

我能夠繪製出什麼廣告活動都符合球隊,但我想只爲被映射到多個團隊的廣告活動篩選結果。例如,這是一些結果的樣子:

CAMPAIGN_ID ID   NAME 
830   65   Media Group APAC 
917   40   iAdvertising 
1133   9   Media Comp 
1133   2   Ad Network 5 
7163   931   Y Vector 
8149   318   Hectic Media 
8149   3827   Effective Media Net 
15982   1919   ADCMP 10 
27587   2675   MediaCorp NA 
27587   48   North Shore Ad 

什麼我需要添加到我的查詢,以確定其映射到多個團隊的活動標識(在這個例子中,1133,8149 ,和27587),或者爲了達到這些結果,最佳做法是什麼?

回答

2

您可以使用內部連接來解決此問題,以便您可以過濾要獲取的行。

編輯:該查詢假定只能有一個在ENTITY錶行具有相同的CAMPAIGN_IDTEAM_ID對。如果你可以有重複的行,那麼我認爲你應該看看John Bollinger提供的解決方案。

SELECT  GOLD.CAMPAIGN_ID, 
      TEAM.ID, 
      TEAM.NAME 
FROM  CAMPAIGN_ANALYTICS_GOLD GOLD 
LEFT JOIN ENTITY ENT 
ON   ENT.CAMPAIGN_ID = GOLD.CAMPAIGN_ID 
LEFT JOIN TEAM TEAM 
ON   TEAM.ID = ENT.TEAM_ID 
INNER JOIN 
(

SELECT  CAMPAIGN_ID 
FROM  ENTITY 
GROUP BY CAMPAIGN_ID 
HAVING COUNT(*) > 1 

) x on x.G_ID= GOLD.CAMPAIGN_ID 
GROUP BY GOLD.CAMPAIGN_ID, 
      GOLD.CAMPAIGN_NAME, 
      TEAM.ID, 
      TEAM.NAME; 
+1

將確定與多個'entity's活動,但如果多個'entity's是它可以產生不必要的額外結果分配給同一個活動和團隊。是否需要考慮取決於數據。 –

+0

@John Bollinger:你的權利。我已經更新了我的答案。 – user707727

1

[更新]我猜我是MYSQL的noob,認爲它像MSSQL Lol:P。但是現在我已經更新了我的答案以符合MYSQL。你可以檢查我的SQL小提琴here

您可以使用COUNT(CAMPAIGN_ID)GROUP BY CAMPAIGN_ID度日CAMPAIGN_ID(也就是說具有相同的CAMPAIGN_ID行,因此重複)分組的行總數然後篩選其中是大於1的有不同的方式來做到這一點的計數但這裏是我最喜歡的方式:

SELECT tt.CAMPAIGN_ID, tt.ID, tt.NAME 
FROM 
(
    SELECT GOLD.CAMPAIGN_ID, 
      TEAM.ID, 
      TEAM.NAME, 
      COUNT(GOLD.CAMPAIGN_ID) as [Count] 
    FROM CAMPAIGN_ANALYTICS_GOLD GOLD 
    LEFT JOIN ENTITY ENT ON ENT.CAMPAIGN_ID = GOLD.CAMPAIGN_ID 
    LEFT JOIN TEAM TEAM ON TEAM.ID = ENT.TEAM_ID 
    GROUP BY GOLD.CAMPAIGN_ID 
) t 
INNER JOIN CAMPAIGN_ANALYTICS_GOLD GOLD ON GOLD.CAMPAIGN_ID = t.CAMPAIGN_ID 
WHERE t.Count > 1 

我不知道你的表的佈局,所以我做了一個測試表與您發佈,然後創建的查詢只在我的SQL小提琴鏈接返回重複相同的結果。

這裏是我的答案對未來的觀衆MSSQL版本:

SELECT * 
FROM 
(
    SELECT GOLD.CAMPAIGN_ID, 
      TEAM.ID, 
      TEAM.NAME, 
      COUNT(GOLD.CAMPAIGN_ID) OVER (PARTITION BY GOLD.CAMPAIGN_ID) as [Count] 
    FROM CAMPAIGN_ANALYTICS_GOLD GOLD 
    LEFT JOIN ENTITY ENT ON ENT.CAMPAIGN_ID = GOLD.CAMPAIGN_ID 
    LEFT JOIN TEAM TEAM ON TEAM.ID = ENT.TEAM_ID 
    GROUP BY GOLD.CAMPAIGN_ID, GOLD.CAMPAIGN_NAME, TEAM.ID, TEAM.NAME 
) t 
WHERE t.Count > 1 

而且MSSQL SQL小提琴鏈接here

如果您仍然希望結果是獨一無二的有重複行(活動,id和名稱),那麼您可以將DISTINCT子句添加到任一查詢的外部select語句。

+0

他標記了mysql-workbench,所以假設他使用mysql似乎是合理的。不幸的是,mysql在主要的DBMS中是值得注意的,因爲它不支持分析函數。 –

+0

@JohnBollinger我更新了我的答案以使用MYSQL。 –

+0

新查詢與@ user707727具有相同的問題(根據數據不同,這可能根本不成問題):如果活動通過兩個不同的實體與同一團隊相關聯,則可能產生誤報。 –

2

如果您使用的是MySQL,那麼您無法訪問分析函數,否則這些分析函數將提供非常方便的解決方案(per @JohnOdom)。在這種情況下,您也無法訪問公用表表達式,這很方便。

如果假定與同一團隊相關聯的兩個不同實體可能與同一活動相關聯是安全的,那麼可以將問題簡化爲識別與多個關聯實體關聯的活動,@ user707727提供瞭解。

更通用的解決方案有點複雜,但您至少可以做出一些假設。特別是,活動只能通過與現有實體及其現有團隊的關聯與多個團隊相關聯,因此您可以執行內部連接而不是外部連接。此外,請注意,全部爲關於哪些團隊與哪些廣告系列相關聯的信息僅由表entity承載,因此查詢探查該關係需要僅考慮該表。

以下解決方案首先通過分析僅表ENTITY分析通緝對(campaign_id,team_id)對,然後加入表TEAM以獲取團隊名稱。如果需要關於活動的其他信息(例如其名稱),則表campaign也可以加入外部查詢中。假設campaign_idteam_id是其各自表的PK,則頂層不需要分組。

SELECT 
    CAMP_TEAM.CAMPAIGN_ID, 
    TEAM.ID, 
    TEAM.NAME 
FROM 
    (
    (
     SELECT CAMPAIGN_ID 
     FROM ENTITY 
     GROUP BY CAMPAIGN_ID 
     HAVING COUNT(DISTINCT TEAM_ID) > 1 
    ) CAMP 
    JOIN ENTITY ENT 
     ON ENT.CAMPAIGN_ID = CAMP.CAMPAIGN_ID 
    GROUP BY ENT.CAMPAIGN_ID, ENT.TEAM_ID 
) CAMP_TEAM 
    JOIN TEAM TEAM 
    ON TEAM.ID = CAMP_TEAM.TEAM_ID 
; 
1

組通過消除了左邊,這樣只要用前去捧場

SELECT  GOLD.CAMPAIGN_ID, 
      TEAM.ID, 
      TEAM.NAME 
FROM  CAMPAIGN_ANALYTICS_GOLD GOLD 
JOIN  ENT 
    ON  ENT.CAMPAIGN_ID = GOLD.CAMPAIGN_ID 
JOIN  TEAM 
    ON  TEAM.ID = ENT.TEAM_ID 

JOIN  CAMPAIGN_ANALYTICS_GOLD GOLDdup 
    ON  GOLD.CAMPAIGN_ID = GOLDdup.CAMPAIGN_ID 
JOIN  ENT as ENTdup 
    ON  ENTdup.CAMPAIGN_ID = GOLDdup.CAMPAIGN_ID 
and  ENTdup.TempID <> ENT.TEAM_ID -- this finds the dups 

GROUP BY GOLD.CAMPAIGN_ID, 
      GOLD.CAMPAIGN_NAME, 
      TEAM.ID, 
      TEAM.NAME;