2015-05-01 47 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;