У меня три таблицы ClaimHeader, ResClaim и ResActivity. Первичный ключ таблицы ClaimHeader используется как внешний ключ в таблице ResClaim, а первичный ключ таблицы ResClaim используется как внешний ключ в таблице ResActivity.
Ниже приведены мои таблицы
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
ResClaim таблица использует HeaderPKID в качестве внешнего ключа из таблицы ClaimHeader и ResActivity таблица использует ClaimPKID в качестве внешнего ключа из таблицы ResClaim
Мой сценарий - я должен отображать соответствующую запись из всех трех таблиц.
Например, я хочу отобразить FileID из таблицы ClaimHeader, Total Claim count из таблицы ResClaim и Sum of 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.
Пока еще не совсем понятно, что вы просите. Кажется, вам либо нужна одна строка результата для заголовка заявки, либо одна строка результата для каждого файла. Итак, группа по рассматриваемой колонке.
Присоединившись ко всем записям, вы, конечно же, получаете заголовки претензий и претензий многократно, например, с
вы получаете этот промежуточный результат от объединений:
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
и group вместо него, а не headerid
.