Performing calculations in sql

烂漫一生 提交于 2019-12-12 01:45:39

问题


I have the following SQL query;

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

Which produces the following table as its output;

I need some advice as to how I can add one further column to the output table which for the sake of argument we'll call TotalDeductions.

If we take the first row of the table as an example Total deductions would be calculated by taking a percentage (from the DeductionRate column), in this case 1.5%, of the owed column. If after removing that 1.5% from the total of the owed column and removing the sum in the WeeklyDeductionRate, in this case 10.0, one is left with a sum that is at least 110 then the WeeklyDeductionRate can be taken. If however the sum were to be below 110 after the WeeklyDeductionRate were removed then it should not be removed.

I'm sure that this can be done in SQL, just not sure where to start.

NB Although in the table of returned data shown all of the Columns WeeklyDeductionRate, FromMinimumReturn and DeductionRate show the same figures they can vary, so 'hard coding' figures isn't an option.

Thanks

EDIT

The database platform is SQL Server (either 2012 or 2014). As an example of what I would really like to end up with , and again taking the first row as an example I'd like to have a result set that reads:

ContactId      Owed             TotalDeductions
    39         1609.390000           34.14

where total deductions is made up of 1609.39 * 1.5% which = 24.14 plus 10 as the total 34.14 when deducted from 1609.39 would leave a balance of at least 110.


回答1:


I think adding the following case expression to your select statement should do it:

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

However, this has a lot of repeating code (the Owed calculation), so I would wrap the original query in a common table expression and do it like this:

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

This will return to calculated TotalDeductions if subtracting it from the Owed leaves a result over the FromMinimumReturn else it will return 0 for TotalDeductions.



来源:https://stackoverflow.com/questions/31224394/performing-calculations-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!