在mysql中获取相关表的相关记录

时间:2018-03-02 13:30:42

标签: mysql sql

我有三个表 ClaimHeader ResClaim ResActivity ClaimHeader 表的主键在 ResClaim 表中用作外键, ResClaim 表的主键在 ResActivity中用作外键 table。

以下是我的表格

ClaimHeader:

HeaderID  FileID    FileName
1         fileid1    file1.xml
2         fileid2    file2.xml
3         fileid3    file3.xml
4         fileid4    file4.xml
--------------------------------------------------
ResClaim:

ClaimPKID  HeaderPKID    ClaimDateSettlement
1          1             2017-04-08
2          1             2017-03-08
3          2             2017-04-10
4          3             2017-05-08
--------------------------------------------------
ResActivity:

ActivityPKID  ClaimPKID    ActivityNet
1             1             400
2             2             3000
3             2             2030
4             3             5000

Tables screenshot

ResClaim 表使用 HeaderPKID 作为 ClaimHeader 表中的外键,而 ResActivity 表使用 ClaimPKID 作为 ResClaim

中的外键

我的场景是我应该显示来自所有三个表的相关记录。

例如,我想显示 ClaimHeader 表中的 FileID ResClaim 表中的总声明数量和 ActivityNet的总和来自 ResActivity 的表格,其中包含匹配的条件。

我的预期结果是:

FileID   |  Total Claim(s) |  ActivityNet 
--------------------------------------------------
fileid2  |    1            |   5030 (3000+2030)
--------------------------------------------------

我在下面尝试过查询:

SELECT 
  `ClaimHeader`.*, 
  count(ResClaim.ClaimPKID) as claims,  
  sum(ResActivity.ActivityNet) as net 
FROM 
  `ClaimHeader` 
  RIGHT OUTER JOIN `ResClaim` 
    ON ResClaim.ClaimPKID = ClaimHeader.HeaderID 
  RIGHT OUTER JOIN `ResActivity` 
    ON ResClaim.ClaimPKID = ResActivity.ActivityPKID

上面的查询没有返回相关的记录值 - 而是返回所有列的总和并从ResActivity和ResClaim表中计算。

1 个答案:

答案 0 :(得分:0)

目前还不完全清楚你在问什么。您似乎要么每个声明标题需要一个结果行,要么每个文件需要一个结果行。因此,请按相关列进行分组。

通过加入所有记录,您获得的索赔标题和声明当然是多方面的,例如与

  • 声明标题:head1,head2
  • 对头1的索赔:索赔10,索赔11
  • 对头部2的索赔:索赔20,索赔21
  • 对于权利要求10的动作:action100,action101
  • 权利要求11的动作:动作110,动作111
  • 权利要求20的动作:action200,action201

你从连接中得到这个中间结果:

header | claim   | action
-------+---------+----------
head1  | claim10 | action100
head1  | claim10 | action101
head1  | claim11 | action110
head1  | claim11 | action111
head2  | claim20 | action200
...

现在,通过按标题分组,您将获得head1的一个聚合结果行,head2的一个聚合结果行。由于中间结果包含每个操作一个记录,因此您可以轻松地对它们求和。但是对于声明:head1有四个记录,如果你count(*)count(claimpkid),你会得到4的结果(count(claimpkid)统计所有claimpkid非空,这个例子总是如此)。您想要做的是计算不同的声明(这里有两个:声明10和声明11)。因此,请使用COUNT DISTINCT

select 
  h.headerid, 
  count(distinct c.claimpkid) as claims,  
  coalesce(sum(a.activitynet), 0) as net 
from claimheader h
left outer join resclaim c on c.claimpkid = h.headerid 
left outer join resactivity a on a.activitypkid = c.claimpkid
group by h.headerid
order by h.headerid;

我正在使用左外连接(和COALESCE)用于标题没有声明或声明没有操作的情况,为此我们将显示零而不是从结果中删除它们。

如上所述,如果您希望每个文件使用此文件,请选择fileid并按其分组,而不是headerid