1

为简单起见,我将给出一个我想要实现的快速示例:

表 1 - 成员

  ID    |   Name
--------------------
  1     |   John    
  2     |   Mike    
  3     |   Sam  


表 1 - Member_Selections

  ID    |   planID
--------------------
  1     |   1    
  1     |   2    
  1     |   1    
  2     |   2    
  2     |   3    
  3     |   2    
  3     |   1    


表 3 - Selection_Details

planID  |   Cost
--------------------
  1     |   5    
  2     |   10    
  3     |   12  

当我运行查询时,我想返回按成员分组的所有成员选择的总和。然而,我面临的问题(例如表 2 数据)是一些成员可能错误地在系统中拥有重复的信息。虽然我们尽最大努力预先过滤这些数据,但有时它会从裂缝中溜走,所以当我对系统进行必要的调用以提取信息时,我也想过滤这些数据。

结果应该显示:

结果表

ID  |    Name    | Total_Cost
-----------------------------
1   |    John    |   15
2   |    Mike    |   22
3   |    Sam     |   15

而是将 John 设为 20 美元,因为他错误地插入了两次计划 ID #1。

我的查询目前是:

SELECT
    sq.ID, sq.name, SUM(sq.premium) AS total_cost
FROM
(
    SELECT
    m.id, m.name, g.premium
    FROM members m
    INNER JOIN member_selections s USING(ID)
    INNER JOIN selection_details g USING(planid)
) sq group by sq.agent

添加 DISTINCT s.planID 会错误地过滤结果,因为它只会显示已售出的单个 PlanID 1(即使成员 1 和 3 购买了它)。

任何帮助表示赞赏。

编辑

还有一张我忘了提到的表是代理表(将计划出售给成员的代理)。

最后的 group by 语句将代理 ID 出售的所有商品分组(将最终结果变成单行)。

4

4 回答 4

2

也许最简单的解决方案是在 member_selections 表上放置一个唯一的复合键:

 alter table member_selections add unique key ms_key (ID, planID);

这将阻止添加任何记录,其中 ID/planID 的唯一组合已经存在于表中的其他位置。那只允许一个 (1,1)

评论跟进:

刚刚看到您对“更改忽略...”的评论。这很好,但您仍然会在表中留下错误的重复项。我建议做唯一键,然后手动清理表格。我在评论中输入的查询应该会为您找到所有重复项,然后您可以手动清除它们。一旦表清理干净,就不需要查询的重复处理版本。

于 2011-01-11T21:00:07.557 回答
0

使用 UNIQUE 键来防止意外的重复条目。这将在源头上消除问题,而不是在问题开始出现症状时。它还使以后的查询更容易,因为您可以指望拥有一个一致的数据库。

于 2011-01-11T21:01:03.857 回答
0

关于什么:

SELECT
    sq.ID, sq.name, SUM(sq.premium) AS total_cost
FROM
(
    SELECT
    m.id, m.name, g.premium
    FROM members m
    INNER JOIN 
         (select distinct ID, PlanID from member_selections) s
    USING(ID)
    INNER JOIN selection_details g USING(planid)
) sq group by sq.agent

顺便说一句,是否有理由在 member_selections 上没有主键来防止这些重复发生?

于 2011-01-11T21:02:51.337 回答
0

您可以将 group by 子句添加到内部查询中,该子句按所有三列分组,基本上只返回唯一行。(我还将 'premium' 更改为 'cost' 以匹配您的示例表,并删除了代理部分)

SELECT
    sq.ID, 
    sq.name, 
    SUM(sq.Cost) AS total_cost
FROM
(
    SELECT
            m.id, 
            m.name, 
            g.Cost
    FROM 
            members m
            INNER JOIN member_selections s USING(ID) 
            INNER JOIN selection_details g USING(planid)

        GROUP BY
            m.ID,
            m.NAME,
            g.Cost
) sq 
group by 
    sq.ID,
    sq.NAME
于 2011-01-11T22:29:56.253 回答