SQL math syntax difficulty with division - sql

Can't understand why I can't get the correct answer. I'm trying to calculate a net margin percentage but the divide portion is being ignored. Hopefully really simple one?
SUM(
(dbo.K3_TradeTeam_Sales2.TotalSales - dbo.K3_TradeTeam_SalesReturn3.TotalCredits)
ISNULL(dbo.K3_TradeTeam_Purch1.TotalPurchases, 0) /
dbo.K3_TradeTeam_Sales2.TotalSales
) AS NetMargin

To get a net margin you probably want an expression like this,
(
SUM(
dbo.K3_TradeTeam_Sales2.TotalSales
-
COALESCE(dbo.K3_TradeTeam_SalesReturn3.TotalCredits, 0.0)
-
COALESCE(dbo.K3_TradeTeam_Purch1.TotalPurchases, 0.0)
)
/
SUM(
dbo.K3_TradeTeam_Sales2.TotalSales
)
) AS NetMargin
However, without knowing your schema I couldn't say for sure. This would also fail miserable when you have 0.0 total sales.
I'm assuming that your want the sum of net profits for each realtion divided by the sum of the total revenue for each relation. This would give you the cumulative profit margin for all relationships.

The sql logic should work.
Are you sure that TotalPurchases is not null? Because this makes it look like the devide is ignored, but the devide just returns 0. So I'm doing minus zero!
examples:
select SUM((200 - 100) - ISNULL(100, 0) / 10) AS NetMargin --returns 90
select SUM((200 - 100) - ISNULL(null, 0) / 10) AS NetMargin --return 100

When I am having trouble getting a math formula to work, I change the select temporarily to simply see the values of each of the fields as well as the calculation. Then I can do the calualtion manually to see how I am getting the results I am getting which alwmost always points me to the problem.
select
dbo.K3_TradeTeam_Sales2.TotalSales,
dbo.K3_TradeTeam_SalesReturn3.TotalCredits,
ISNULL(dbo.K3_TradeTeam_Purch1.TotalPurchases, 0),
dbo.K3_TradeTeam_Sales2.TotalSales
From...
I also never do a division without a case statement to handle the divisor being 0 problem. Even if I think it can never happen, I have seen it burn people too often not to consider that something (including bad data entry) might make it happen in the future.

Related

BASIC Questions: Using ROUND for calculations

I am in Google's Data Analytics course and every now and then I get to a spot where I could just press on, but I want to know the answer anyway.
We are learning embedded calculations and a very simply equation was given:
`
SELECT
Date,
Region,
Total_Bags,
Small_Bags,
(Small_Bags / Total_Bags) * 100 AS Small_Bags_Percent
FROM `shaped-fx-370703.avocado_data.avocado_prices`
WHERE
Total_Bags <> 0
`
Resulting column from calculation
I would like to know how to use ROUND so that the result in Small_Bags_Percent only go out to 1 decimel
I understand the syntax of round is ROUND(integer,decimel places) but I don't know how to point the "integer" to the results in Small_Bags_Percent. I've tried THEN and even
ROUND(((Small_Bags / Total_Bags) * 100 AS Small_Bags_Percent),2)
``` (hey, I'm just seeing what sticks lol)
The ROUND function goes round the calculation but not the alias for the calculation e.g.
ROUND((Small_Bags / Total_Bags) * 100,2) AS Small_Bags_Percent

How to limit the character amount you are selecting from

I'm trying to average a field and it's very simple to do but there are some problems with some values. There are values I know are way too big and I was hoping to exclude them by the number of characters (I would probably put 4 characters max).
I'm unfamiliar with a sql clause that could execute this. If there is one that would be great.
select avg(convert(float,duration)) as averageduration
from AsteriskCalls where ISNUMERIC(duration) = 1
I expect the output to be around 500-1000 but it comes up as an 8 digit number.
That is easy enough:
select avg(convert(float,duration)) as averageduration
from AsteriskCalls
where ISNUMERIC(duration) = 1 and length(duration) <= 4;
This will not necessarily work, of course, because you could have '1E30', which would be a pretty big number. And it would miss '0.001', which is a pretty small number.
The more accurate method uses try_convert():
select avg(try_convert(float, duration)) as averageduration
from AsteriskCalls
where try_convert(float, duration) <= 1000.0
And that should probably really be:
where abs(try_convert(float, duration)) <= 1000.0

Code Not calculating correctly Cast /NullIF

I’m trying to calculate CNC machine efficiency. My code doesn’t calculate correctly. I’m not sure why. For instance, The Completed value is 2. The PPHOURGOAL is 1. The 8 is for an 8-hour shift.
cast(((Completed / 8) /NULLIF(Completed,0) / (PPHOURGOAL * 8) )* 100 as dec(5,4)) as EightHourShiftEfficiency, ---Divide the previously calculated production rate by the maximum rate and multiply by 100 to calculate the efficiency rate.
Calculation should be as ((2/8)/(1*8))*100 = 2. Which should translate to ((.25)/(8))*100=2
But the system is returning 1.5625 instead.
I am guessing that integer division is the culprit. Does this do what you want?
cast(((Completed / 8.0) /NULLIF(Completed, 0.0) / (PPHOURGOAL * 8.0) ) * 100.0 as dec(5, 4)) as E
Found the error of my ways. My select statement was doubling rows that caused my calculations to be off.

Select SUM() SQL

I need to get the total from a column with SQL but it's not working, can anybody see what I do wrong.
SELECT a.Artikelnummer
,a.Artikelnamn
,a.Antalperpall
,COUNT(*) AS AntalArtiklar
,SUM(e.Antalpallar) AS TotalPall
,SUM(e.Antalperpall) AS TotalStyck
FROM Artikel AS a
INNER JOIN Evig AS e ON a.ArtikelnummerID = e.ArtikelnummerID
WHERE (e.Datum <= '{0}')
AND (a.Kundkund = '{1}')
AND (a.Artikelnamn = '{2}')
GROUP BY a.Artikelnummer
,a.Artikelnamn
,a.Antalperpall
SUM(e.Antalperpall) AS TotalStyck: it is this one who returns a strange value. What I wanna do is take the integer value in each row and get a total from that.
OK I went down to the basement and visited the server, and I found the problem. I needed to multiply with Antalpallar like this SUM(e.Antalperpall * ABS(e.Antalpallar)) . But it is still not working and I think it is becouse of the negative values.
se data here
so where it is negativ value in Antalpallar like this -1200 *-2 should be -2400 but i don't think it's doing that, or? It is stuff going in and out of a warehouse.
Anyhow, the final value of adding those togheter should be 14320, but i get one on 20 000 something and without ABS()(or with) a sum on 5000 something.
Anyone knows how to write this SUM(e.Antalperpall * ABS(e.Antalpallar)) to get the value i want?
You might wanna try it by eliminating if there are any strange values (characters) in Antalperpall. Use sum(cast (e.Antalperpall as Money)) and in filterclause
where ISNUMERIC( e.Antalperpall) = 1. If there are any stange values in the field, you will obviously get conversion error.

Converting pounds to kilos in SQL

I am trying to pull data from a table with the filter weight < 25 kgs , but my table has weight in pounds, I tried using below sql can some one please tell me is this the right way to do it or is there any other way .
select * from dbo.abc
where (round((WEIGHT * 0.453592 ),0) < 25)
Your solution would work, but it's not sargaeble. A better solution would be to convert your 25kgs to lbs. That way, if you have an index on your WEIGHT column, the query analyzer could make use of it.
One additional note: Why round to 0 decimal places? You'll lose accuracy that way. Unless you have some requirement to do so, I'd drop the rounding. It's unnecessary overhead.
As other people mentioned, you don't want to convert weight as it will cause SQL Server not to use your index. So try this instead:
SELECT *
FROM dbo.acb
WHERE WEIGHT < ROUND(25/.453592,4)