Выполнение расчетов в sql

У меня есть следующий запрос SQL;

SELECT DISTINCT
    Contacts.ContactId,
    ROUND(SUM(LandingDetails.Quantity * LandingDetails.UnitPrice), 2) AS  Owed,
    SocietyMemberships.WeeklyDeductionRate,
    SocietyMemberships.FromMinimumReturn,
    Deductions.DeductionRate
FROM 
    dbo.LandingDetails
INNER JOIN 
    dbo.LandingHeaders ON LandingDetails.LandingId = LandingHeaders.LandingId
INNER JOIN 
    dbo.Vessels ON LandingHeaders.VesselId = Vessels.VesselId
INNER JOIN 
    dbo.Contacts ON Vessels.OwnerId = Contacts.ContactId
INNER JOIN 
    dbo.SocietyMemberships ON Contacts.SocietyId = SocietyMemberships.SocietyId
INNER JOIN 
    dbo.Deductions ON Vessels.DeductionId = Deductions.DeductionId
WHERE 
    LandingHeaders.Posted = 0
GROUP BY 
    Contacts.ContactId,
    SocietyMemberships.WeeklyDeductionRate,
    SocietyMemberships.FromMinimumReturn,
    Deductions.DeductionRate

Который производит следующую таблицу в качестве своего вывода;

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

Если мы возьмем в качестве примера первую строку таблицы, общие вычеты будут рассчитываться путем взятия процента (из столбца DeductionRate), в данном случае 1,5%, из столбца задолженности. Если после удаления этих 1,5% от общей суммы столбца задолженностей и удаления суммы в WeeklyDeductionRate, в данном случае 10,0, останется сумма не менее 110, тогда можно взять WeeklyDeductionRate. Однако, если сумма должна быть ниже 110 после удаления WeeklyDeductionRate, ее не следует удалять.

Я уверен, что это можно сделать в SQL, просто не знаю, с чего начать.

NB. Хотя в таблице возвращаемых данных показаны все столбцы WeeklyDeductionRate, FromMinimumReturn а также DeductionRate показывать одни и те же цифры, они могут варьироваться, поэтому цифры с "жестким кодированием" не подходят.

Спасибо

РЕДАКТИРОВАТЬ

Платформа базы данных - SQL Server (2012 или 2014). В качестве примера того, что я действительно хотел бы закончить, и снова взяв в качестве примера первую строку, я хотел бы иметь результирующий набор, который гласит:

ContactId      Owed             TotalDeductions
    39         1609.390000           34.14

где общая сумма вычетов составляет 1609,39 * 1,5%, что = 24,14 плюс 10, так как общая сумма 34,14 при вычете из 1609,39 оставит остаток как минимум 110.

1 ответ

Решение

Я думаю, что добавление следующего выражения case в ваш оператор select должно сделать это:

CASE WHEN 
   SUM(LandingDetails.Quantity * LandingDetails.UnitPrice) 
   - 
   SUM(LandingDetails.Quantity * LandingDetails.UnitPrice) * DeductionRate + WeeklyDeductionRate 
   > FromMinimumReturn 
THEN SUM(LandingDetails.Quantity * LandingDetails.UnitPrice) * DeductionRate + WeeklyDeductionRate
ELSE 0 END
AS TotalDeductions

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

WITH cte AS (
  <<<your original query here>>> -- I left it out to save space...
)

SELECT 
    ContactId,
    Owed,
    WeeklyDeductionRate,
    FromMinimumReturn,
    DeductionRate,
    CASE 
       WHEN Owed - (Owed * DeductionRate + WeeklyDeductionRate) > FromMinimumReturn 
       THEN Owed * DeductionRate + WeeklyDeductionRate
       ELSE 0 END
    AS TotalDeductions
FROM cte

Это вернется к вычисленным значениям TotalDeductions, если вычитание из Owed оставит результат над FromMinimumReturn, иначе вернет 0 для TotalDeductions.

Другие вопросы по тегам