Множественные множители - PullRequest
       28

Множественные множители

0 голосов
/ 18 августа 2011

У меня есть 3 таблицы: страховые полисы, претензии и дебиторская задолженность

Мне нужен запрос, который будет возвращать одну строку за период политики для каждой политики. Запрос должен включать дату начала и окончания действия политики, общее количество требований за каждый период, общее количество оплаченных и O / S за каждый период и общую сумму, полученную за каждый период.

Мне удалось сделать все, кроме дебиторской задолженности. Когда это вводится в запрос, все умножается на количество строк в этой таблице.

Вот мои данные

Правила

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

Претензии

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

Дебиторская задолженность

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

Вот мой рабочий запрос

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

Результат:

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

Мне пришлось добавить TransType к запросу, так как я получал множитель для данных претензий, но этот запрос работает.

Теперь, когда я добавляю третью таблицу, я получаю множитель. Все из утверждений умножается на число или строки в дебиторской задолженности за период, а AmountRecvd умножается на количество строк в утверждениях за период.

Вот запрос:

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

Результат

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

Не вижу возможности объединить дебиторскую задолженность с претензиями. Я пытался присоединиться к ним на PolNo, но у меня был тот же результат.

Кто-нибудь может увидеть решение?

Приветствия

Обновлено Этот запрос не умножает ClaimsCount, но AmountRevd все еще умножается на Claims (TotPaid удален для простоты):

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

1 Ответ

1 голос
/ 18 августа 2011
-- 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

Или без 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

Вывод (транспонированный):

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
...