开发者

Multiple Join Multipliers

I have 3 tables: Insurance Policies, Claims and Receivables

I need a query that will return one row per policy period per policy. The query needs to include the policy start and end date, total claims for each period, total paid and O/S for each period, and total amount received for each period.

I've managed to do everything but the recievables. When this is introduced to the query, everything is multiplied by the number of rows in that table.

Here is my data

Policies

PolNo   Version   TransType   InceptionDate   RenewalDate
0021          0   New         01/开发者_高级运维01/2008      01/01/2009
0021          1   MTA         01/01/2008      01/01/2009
0021          2   MTA         01/01/2008      01/01/2009
0021          3   Renewal     01/01/2009      01/01/2010

Claims

PolNo   ClaimNo   ClaimDate      Paid    Outstanding
0021    0001      01/05/2008   300.00        -100.00
0021    0002      01/06/2008   500.00         200.00
0021    0003      01/07/2008   200.00         300.00
0021    0004      01/08/2008   800.00           0.00
0021    0005      01/02/2009     0.00           0.00
0021    0006      01/10/2009     0.00        1000.00

Receivables

PolNo   Version   RecvdDate    Amount
0021          0   02/01/2008   150.00
0021          0   01/02/2008   150.00
0021          0   01/03/2008   150.00
0021          0   01/04/2008   150.00
0021          0   01/05/2008   150.00
0021          0   01/06/2008   150.00
0021          0   01/07/2008   150.00
0021          0   01/08/2008   150.00
0021          2   01/09/2008   150.00
0021          2   01/10/2008   150.00
0021          3   02/01/2009   500.00
0021          3   01/02/2009   500.00

Here is my working query

select distinct(a.InceptionDate) as InceptionDate, a.RenewalDate as RenewalDate,
count(b.ClaimNo) as ClaimCount, sum(b.Paid) as TotPaid, sum(b.Outstanding) as TotalO/S
from Policies a, Claims b
where a.PolNo='0021'
and a.PolNo=b.PolNo
and b.ClaimDate between a.InceptionDate and a.RenewalDate
and a.TransType in ('New','Renewal')
group by a.InceptionDate, a.RenewalDate

Result:

InceptionDate   RenewalDate   ClaimCount      TotPaid       TotalO/S
01/01/2008      01/01/2009        4           1800.00       400.00
01/01/2009      01/01/2010        2           0             1000.00

I had to add TransType to the query as I was getting a multiplier for claims data, but this query works.

Now when I add the third table, I get a multiplier. Everything from Claims is multiplied by the number or rows in Receivables for the period, and AmountRecvd is multiplied by the number of rows in Claims for the period.

Here is the query:

select distinct(a.InceptionDate) as InceptionDate, a.RenewalDate as RenewalDate,
count(b.ClaimNo) as ClaimCount, sum(b.Paid) as TotPaid, sum(b.Outstanding) asTotalO/S,
sum(c.Amount) as RecvdAmount
from Policies a, Claims b, Receivables c
where a.PolNo='0021'
and a.PolNo=b.PolNo
and a.PolNo=c.PolNo
and b.ClaimDate between a.InceptionDate and a.RenewalDate
and c.RecvdDate between a.InceptionDate and a.RenewalDate
and a.TransType in ('New','Renewal')
group by a.InceptionDate, a.RenewalDate

Result

InceptionDate   RenewalDate   ClaimCount   TotPaid   TotalO/S   AmountRecvd
01/01/2008      01/01/2009       40         18000       4000       6000.00
01/01/2009      01/01/2010       20             0      10000       2000.00

I cant see that it is possible to join Receivables with Claims. I tried joining them on PolNo but had the same result.

Can anyone see a solution?

Cheers

Updated This query doesn't muliply ClaimsCount, but AmountRevd still multiplying by Claims (TotPaid removed for simplicity):

SELECT
    p.InceptionDate,
    p.RenewalDate,
    sum(c1.ClaimCount) AS ClaimsCount,
    sum(r1.TotRecvd) AS AmountRecvd
FROM Policies p
LEFT JOIN (SELECT 
        p1.InceptionDate, 
        p1.RenewalDate, 
        c.Polno, 
        c.ClaimDate,
        COUNT(c.SubCount) AS ClaimCount
    FROM Policies p1 
    INNER JOIN (SELECT 
            PolNo,
            ClaimDate,
            Count(*) as SubCount
        FROM Claims 
        GROUP BY PolNo, ClaimDate) c
        ON p1.PolNo=c.PolNo
    WHERE c.ClaimDate BETWEEN p1.InceptionDate AND p1.RenewalDate
    AND p1.TransType IN ('New','Renewal')
    GROUP BY p1.InceptionDate, p1.RenewalDate, c.Polno, c.ClaimDate) c1
    ON p.PolNo=c1.PolNo
LEFT JOIN (SELECT 
        p2.InceptionDate, 
        p2.RenewalDate, 
        r.Polno,
        SUM(r.SubTot) AS TotalRecvd
    FROM Policies p2
    INNER JOIN (SELECT
            PolNo,
            RecvdDate,
            SUM(Amount) as SubTot
        FROM Receivables
        GROUP BY Polno,RecvdDate) r
        ON p2.PolNo=r.PolNo
    WHERE r.RecvdDate BETWEEN p2.InceptionDate AND p2.RenewalDate
    AND p2.TransType IN ('New','Renewal')
    GROUPBY p2.InceptionDate, p2.RenewalDate, r.Polno) r1
    ON p.PolNo=r1.PolNo
WHERE p.PolNo = '0021'
AND p.TransType IN ('New','Renewal')
AND p.PolNo = c1.PolNo
AND p.PolNo = r1.PolNo
AND p.InceptionDate = c1.InceptionDate
AND p.RenewalDate = c1.RenewalDate
AND p.InceptionDate = r1.InceptionDate
AND p.RenewalDate = r1.RenewalDate
GROUP BY p.InceptionDate, p.RenewalDate


-- Query for the periods:
WITH Periods AS (
    SELECT DISTINCT
        PolNo, InceptionDate, RenewalDate
    FROM Policies
    WHERE TransType in ('New','Renewal')
),

-- Query for the claims
PeriodClaims AS (
    SELECT
        p.PolNo, p.InceptionDate, p.RenewalDate,
        COUNT(*) AS CountClaims,
        SUM(c.Paid) AS PaidClaims,
        SUM(c.Outstanding) AS OutstandingClaims
    FROM Periods p
    INNER JOIN Claims c ON c.PolNo = p.PolNo
    WHERE c.ClaimDate BETWEEN p.InceptionDate AND p.RenewalDate
    GROUP BY p.PolNo, p.InceptionDate, p.RenewalDate
),

-- Query for the receivables
PeriodRecieved AS (
    SELECT
        p.PolNo, p.InceptionDate, p.RenewalDate,
        COUNT(*) AS CountReceived,
        SUM(r.Amount) AS AmountReceived
    FROM Periods p
    INNER JOIN Receivables r ON r.PolNo = p.PolNo
    WHERE r.RecvdDate BETWEEN p.InceptionDate AND p.RenewalDate
    GROUP BY p.PolNo, p.InceptionDate, p.RenewalDate
)

-- All together now
SELECT 
    p.PolNo, p.InceptionDate, p.RenewalDate,
    c.CountClaims, c.PaidClaims, c.OutstandingClaims,
    r.CountReceived, r.AmountReceived
FROM Periods p
LEFT JOIN PeriodClaims c
    ON c.PolNo = p.PolNo
    AND c.InceptionDate = p.InceptionDate
    AND c.RenewalDate = p.RenewalDate
LEFT JOIN PeriodRecieved r
    ON r.PolNo = p.PolNo
    AND r.InceptionDate = p.InceptionDate
    AND r.RenewalDate = p.RenewalDate

Or, without CTE:

SELECT 
    p.PolNo, p.InceptionDate, p.RenewalDate,
    c.CountClaims, c.PaidClaims, c.OutstandingClaims,
    r.CountReceived, r.AmountReceived
FROM (
    -- Query for the periods:
    SELECT DISTINCT
        PolNo, InceptionDate, RenewalDate
    FROM Policies
    WHERE TransType in ('New','Renewal')
) p
LEFT JOIN (
    -- Query for the claims
    SELECT
        p.PolNo, p.InceptionDate, p.RenewalDate,
        COUNT(*) AS CountClaims,
        SUM(c.Paid) AS PaidClaims,
        SUM(c.Outstanding) AS OutstandingClaims
    FROM (
        -- Query for the periods:
        SELECT DISTINCT
            PolNo, InceptionDate, RenewalDate
        FROM Policies
        WHERE TransType in ('New','Renewal')
    ) p
    INNER JOIN Claims c ON c.PolNo = p.PolNo
    WHERE c.ClaimDate BETWEEN p.InceptionDate AND p.RenewalDate
    GROUP BY p.PolNo, p.InceptionDate, p.RenewalDate
) c
    ON c.PolNo = p.PolNo
    AND c.InceptionDate = p.InceptionDate
    AND c.RenewalDate = p.RenewalDate
LEFT JOIN (
    -- Query for the receivables
    SELECT
        p.PolNo, p.InceptionDate, p.RenewalDate,
        COUNT(*) AS CountReceived,
        SUM(r.Amount) AS AmountReceived
    FROM (
        -- Query for the periods:
        SELECT DISTINCT
            PolNo, InceptionDate, RenewalDate
        FROM Policies
        WHERE TransType in ('New','Renewal')
    ) p
    INNER JOIN Receivables r ON r.PolNo = p.PolNo
    WHERE r.RecvdDate BETWEEN p.InceptionDate AND p.RenewalDate
    GROUP BY p.PolNo, p.InceptionDate, p.RenewalDate
) r
    ON r.PolNo = p.PolNo
    AND r.InceptionDate = p.InceptionDate
    AND r.RenewalDate = p.RenewalDate

Output (transposed):

PolNo                       21           21
InceptionDate       2008-01-01   2009-01-01
RenewalDate         2009-01-01   2010-01-01
CountClaims                  4            2
PaidClaims             1800.00         0.00
OutstandingClaims       400.00      1000.00
CountReceived               10            2
AmountReceived         1500.00      1000.00
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜