2012-06-01 2 views
1

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

Один запрос должен возвращать результат, как это:

NAME | TotalCharges | TotalPayments 
John   80    100 
Nick   100    90 

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

CUSTOMERS 
-ID 
-NAME 

CHARGES 
-ID 
-CUSTOMER_ID 
-AMOUNT 

PAYMENTS 
-ID 
-CUSTOMER_ID 
-AMOUNT 

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

CUSTOMERS 
-ID 
-NAME 

CHARGES_AND_PAYMENTS 
-ID 
-CUSTOMER_ID 
-CHARGE_AMOUNT 
-PAYMENT_AMOUNT 

Другой подход заключается в использовании одной таблицы для обеих сборов и платежей, используя флаг TRANSACTION_TYPE. 0-> Оплата, 1-> Charge, но если я использую этот подход, я не смог бы получить общие сборы и платежи за клиента с помощью одного запроса (или я могу?)

CUSTOMERS 
-ID 
-NAME 

CHARGES_AND_PAYMENTS 
-ID 
-CUSTOMER_ID 
-TRANSACTION_TYPE (Flag: 0=Payment, 1=Charge) 
-AMOUNT 

Какой лучший подход?

+0

Вы * можете * получить желаемый результат с помощью третьего подхода в одном запросе. В случае, если вам также потребуется получить общую сумму (все платежи за вычетом всех платежей), третий подход будет самым гибким решением. –

ответ

1

ли сумма на начислений и выплат таблицы на идентификатор клиента

select Customers.Name 
, Customers.id 
, (select sum(Charges.Amount) 
     from Charges 
     where CustomerId = Customers.id) 
, (select sum(Payments.Amount) 
     from Payments 
     where CustomerId = Customers.id) 
+0

Будьте осторожны с вложенными выделениями. Все люди рекомендуют это избегать. Есть slooow: http://www.selikoff.net/2008/12/10/memo-avoid-nested-queries-in-mysql-at-all-costs/. – danihp

1

Ваш первый подход - правильное решение.

Sql запрос для извлечения данных будет:

select 
    CUSTOMERS.ID, CUSTOMERS.Name, 
    sum(CHARGES.AMOUNT) as total_CHARGES_amount, 
    sum(PAYMENTS.AMOUNT) as total_PAYMENTS_amount 
from 
    CUSTOMERS 
    left outer join 
    CHARGES on CUSTOMERS.ID = CHARGES.CUSTOMER_ID 
    left outer join 
    PAYMENTS on CUSTOMERS.ID = PAYMENTS.CUSTOMER_ID 
group by 
    CUSTOMERS.ID, CUSTOMERS.Name 
1

Во всех 3-х подходов, вы можете получить данные с одноместной запрос, но я порекомендую первый подход, так как в нем ваши данные будут правильно организованы в соответствии с объектами. И ваш единственный запрос будет выглядеть так:

Select C.Name, SUM(CH.AMOUNT) AS CHARGES, SUM(P.AMOUNT) AS PAYMENTS 
FROM CUSTOMERS C 
LEFT JOIN CHARGES CH ON C.ID = CH.CUSTOMER_ID 
LEFT JOIN PAYMENTS P ON C.ID = P.CUSTOMER_ID 
WHERE C.ID = @CustomerId 
GROUP BY C.Name 
1

Вы должны использовать первый подход, расщепляющие платежи и платежи в две отдельные группы.

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

Сборы, скорее всего, будут иметь различную информацию, такую ​​как дата выставления счетов и т. Д.

Как уже отмечалось, вы можете комбинировать результаты нескольких таблиц в одном запросе. Однако этот факт совершенно отделен от вопроса о том, как разработать схему базы данных.

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