2015-02-10 2 views
0

У меня есть 2 таблицы, tblBasicInfo и tblPayment.Вычитание значения из родительской таблицы с SUM (значение из детской таблицы)

Отношения 1 для многих, где tblBasicInfo находится на 1-й стороне, а tblPayment находится на стороне many.

Отношения не являются обязательными и в этом и состоит проблема.

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

Если в дочерней таблице нет записей, соответствующих критериям, то это должно быть представлено нулем (data from parent table - 0).

Прошу прощения, если это не кристально ясно, английский не мой родной, и я недостаточно опыт, чтобы знать, как правильно описать проблему.

Было бы лучше, чтобы продемонстрировать, что я имею в виду с небольшим примером:

Мы будем исходить из схемы таблицы:

tblBasicInfo: #ID, TotalPrice (double) 

tblPayment: #P_ID, $ID, Amount (double), IsPaid (bool) 

Вот содержание для родительской таблицы tblBasicInfo:

ID | TotalPrice 

1 | 100 

2 | 150 

3 | 200 

4 | 250 

Вот содержание для детского стола tblPayment:

P_ID | ID | IsPaid | Amount 

    1 | 1 | true | 50 

    2 | 1 | false | 25 

    3 | 2 | false | 100 

    4 | 2 | false | 25 

    5 | 3 | true | 200 

Это то, что я достиг сам по себе:

SELECT tblBasicInfo.ID, 
    (tblBasicInfo.TotalPrice - sum(tblPayment.Amount)) AS [Difference] 
    FROM tblBasicInfo, tblPayment 
    WHERE (tblBasicInfo.ID = tblPayment.ID) 
    GROUP BY tblBasicInfo.TotalPrice, tblPayment.IsPaid 
    HAVING (tblPayment.IsPaid = TRUE) --this is the criteria I talked above 
    ORDER BY tblBasicInfo.ID; 

Это то, что я получаю из приведенного выше запроса:

ID | Difference 

1 | 50 
3 | 0 
. 
. 
. 

мне нужно получить следующий результат:

ID | Difference 

1 | 50 
2 | 150  -- does not meet the criteria (IsPayed = false) 
3 | 0 
4 | 250  -- no records in child table 
. 
. 
. 

Приносим извинения за неправильное название вопроса, но я знаю lly не знал, как описать эту проблему.

ответ

1

Я попытался это на SQL Server, но вы можете достичь же в других RDMS вы можете добиться этого в вероятно, больше, чем один из способов здесь я представил два решения я обнаружил, что первое решение работает лучше, чем второй

SELECT ti.id,MAX(totalprice) - ISNULL(SUM(CASE WHEN is_payed = ((0)) THEN 0 ELSE amount END),0) amount 
FROM tblbasicinfo ti LEFT OUTER JOIN tblpayment tp ON ti.id = tp.p_id 
GROUP BY ti.id 

--OR 

SELECT id,totalprice-ISNULL((SELECT SUM(amount) 
FROM tblpayment tp 
WHERE ti.id = tp.p_id AND is_payed = ((1)) 
GROUP BY id),0) AS reconsile 
FROM tblbasicinfo ti 

enter image description here

CREATE TABLE tblBasicInfo (id INT IDENTITY(1,1),totalprice MONEY) 

CREATE TABLE tblPayment (id INT IDENTITY(1,1), P_ID INT ,is_payed BIT,amount MONEY) 

INSERT INTO tblbasicinfo 

VALUES(100),(150),(200),(250) 

INSERT INTO tblpayment(p_id,is_payed,amount) 
VALUES(1,((1)),50),(1,((0)),25),(2,((0)),100),(2,((0)),25),(3,((1)),200) 
+0

Я выбрал второй вариант. Одна заметка для будущих читателей ** и важная: ** Функция 'ISNULL' - это не то же самое в SQL Server и MS Access, в MS Access вместо нее используется' NZ'! Утверждено и официально принято. Спасибо. С наилучшими пожеланиями до следующего раза! – AlwaysLearningNewStuff

0

(незначительная коррекция - IsPaid, а не IsPayed)
Это не тестируется или что-нибудь это просто направить вас в правильном направлении, мы надеемся.
Вы хотите использовать левое соединение, а затем проверить, если сумма равна нулю в вашем расчете difference

SELECT 
    bi.ID, 
    (bi.TotalPrice - sum(IIF(p.Amount is null,0,p.Amount))) AS [Difference] 
    FROM tblBasicInfo bi, 
     left join tblPayment p 
      on p.id = bi.id 
      and p.IsPaid = 1 
    GROUP BY bi.ID, bi.TotalPrice 
    ORDER BY bi.ID; 
1

попробовать это

select a.Id,(a.TotalPrice-payment.paid) as Difference from tblBasicInfo a 
    left join 
    (

    select sum(Amount) as paid,Id 
    from 
    tblPayment 
    group by Id 
     where IsPaid =1)payment 
    on a.Id=payment.Id 
+0

ОК, я пробовал, и он работает. Я просто прошу вас помочь мне в следующем: для случая, когда в дочерней таблице нет записей, 'Difference' является' NULL'. Мне нужно, чтобы это было «TotalPrice». Мне удалось это сделать, изменив '(a.TotalPrice-payment.paid)' на 'NZ (a.TotalPrice-payment.paid, a.TotalPrice)', но мне интересно узнать, есть ли лучший способ. Спасибо. С наилучшими пожеланиями. – AlwaysLearningNewStuff

+0

вы можете попробовать следующее: (a.TotalPrice-isnull (payment.paid, 0)) как Разница для разницы. –

+0

У меня есть ответ на ваш ответ. Причина, по которой я принял другую, состоит в том, что мне легче понять это. Спасибо за помощь. С наилучшими пожеланиями до следующего раза. – AlwaysLearningNewStuff

Смежные вопросы