问题
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