SQL STATEMENT Values getting multiplied by 3 - mysql

SUM(ISNULL(FlagHrs,0.00) + ISNULL(BackFlagSoldHrs,0.00)) AS Ttl_EmpFlagHrs
Using this statement in a select statement but the values I am getting in Ttl_EmpFlagHrs are getting multiplied by 3, Flaghrs and BackFlaghrs are the different columns present in a certain table.

Since there is no sample data or full query, you are forcing us to answer based on speculation.
Based on your question, Objective is to add FlagHrs and BackFlagSoldHrs and when its null, count it as zero.
Since you are using SUM function, which is a group function, result of multiple rows will be added and presented as a single value.
Based on your question, it is highly likely that, single row is repeated 3 times (could be result of a join) and hence sum is showing up as 3 times.
You can verify this by removing SUM function and checking rows actually selected as result of your query.
Solution:
Verify Join condition to ensure correct rows are selected in your query
If theory of adding it up multiple times is true, you can use AVG function in place of SUM function, the result will be equivalent of single row (rather than 3x)
See if you need to use DISTINCT keyword to remove duplicate rows (if its not desired result)

Related

Difference between SUM() and COUNT() in MySQL

I was solving this Leetcode question(1173. Immediate Food Delivery I) and I am kinda confused on why I am not getting the right answer when using COUNT(). but when I use SUM(), I am getting the right answer. I specify a condition for both SUM and COUNT and from my understanding, they should both be adding or counting when order_date=customer_pref_delivery_date, is that mean the condition only working for SUM()?
Query that return the right answer(33.33):
select round(sum(order_date=customer_pref_delivery_date)/count(delivery_id)*100,2) as immediate_percentage
from Delivery
Query that return the wrong answer(100.00)
select round(count(order_date=customer_pref_delivery_date)/count(delivery_id)*100,2) as immediate_percentage
from Delivery
So basically SUM() function will return the sum of the expression inside of it and COUNT() will returns the number of non-NULL values of elements or rows that the query have returned.
In this case with your query you are looking to get the percentage of the immediate delivery orders so your formula to implement this is ((<numberofimmediate>/<totalamount>)*100). At first you can think that COUNT() would be the right approach, but that actually will return the complete number of elements in your query so to avoid this we will use SUM() to just acumulate the 'ones' that complete the condition ( preferred and estimated are equals so will return 1). If you want to see this in a more visual way you can do:
SELECT delivery_id,order_date=customer_pref_delivery_date FROM Delivery
This will return the delivery id and 1 if the condition is true but 0 if its false. Then you can use both of functions to see what is the effect on each one:
SELECT COUNT(order_date=customer_pref_delivery_date) FROM Delivery;
SELECT SUM(order_date=customer_pref_delivery_date) FROM Delivery;
COUNT()query will return, again, the complete amount of data present in the comparation (Counting 1 and 0)
SUM()query will return the sum of all the values present in the comparation (Adding 1 and 0)
Hope this gives you a better understanding of what's going on with COUNT and SUM on your queries
You can check this fiddle
Obviously, when you choose Count() it counts how many fields have numbers for example: we have 5 rows, every row has a number (random numbers, let's say 1,2,3,4,5) so the count here will be 5 while the Sum() gives you the sum of variables in this field (in our example: 1+2+3+4+5 = 15).
In the query that gives you the wrong answer, you simply divide count by count (for example 5/5 *100) which will always give you 1.
I hope that you understand

Dynamically Pivoting Table Data | mySQL

Essentially I have a table in my database called Table1 with the following data:
The table has a ProductID that repeats because the values of AssignedColour, ColourFinding and ColourPower vary.
I would like to present all ProductID data in one single row, meaning if there is more than one AssignedColour, ColourFinding and ColourPower listed, it will contain a number at the end.
The final result I of the SELECT query should look like the following:
The number of columns presented horizontally is based on the number of AssignedColour per ProductID
Is something like this possible to accomplish in a mySQL SELECT Query?
An SQL query cannot expand the number of columns of the result set depending on the data values it discovers during query execution. The columns in the SELECT-list must be fixed at the time the query is prepared, before it reads any data.
Also the column names cannot be changed during the query execution. They must be set at the time the query is prepared.
There's no way to do what you are describing in a single SQL query. Your options are:
Do two queries: one to enumerate the colors per product, and then use the result of the first to format a second query with the columns you want.
Do one query to fetch the data in rows as it exists in your table, then write code in your app to display it in rows however you think is best.
Either way, you have to write at least a bit of code in the client. You can't do this in one query.

MySQL Select Results Excluding Outliers Using AVG and STD Conditions

I'm trying to write a query that excludes values beyond 6 standard deviations from the mean of the result set. I expect this can be done elegantly with a subquery, but I'm getting nowhere and in every similar case I've read the aim seems to be just a little different. My result set seems to get limited to a single row, I'm guessing due to calling the aggregate functions. Conceptually, this is what I'm after:
SELECT t.Result FROM
(SELECT Result, AVG(Result) avgr, STD(Result) stdr
FROM myTable WHERE myField=myCondition limit=75) as t
WHERE t.Result BETWEEN (t.avgr-6*t.stdr) AND (t.avgr+6*t.stdr)
I can get it to work by replacing each use of the STD or AVG value (ie. t.avgr) with it's own select statement as:
(SELECT AVG(Result) FROM myTable WHERE myField=myCondition limit=75)
However this seems waay more messy than I expect it needs to be (I've a few conditions). At first I thought specifying a HAVING clause was necessary, but as I learn more it doesn't seem to be quite what I'm after. Am I close? Is there some snazzy way to access the value of aggregate functions for use in conditions (without needing to return the aggregate values)?
Yes, your subquery is an aggregate query with no GROUP BY clause, therefore its result is a single row. When you select from that, you cannot get more than one row. Moreover, it is a MySQL extension that you can include the Result field in the subquery's selection list at all, as it is neither a grouping column nor an aggregate function of the groups (so what does it even mean in that context unless, possibly, all the relevant column values are the same?).
You should be able to do something like this to compute the average and standard deviation once, together, instead of per-result:
SELECT t.Result FROM
myTable AS t
CROSS JOIN (
SELECT AVG(Result) avgr, STD(Result) stdr
FROM myTable
WHERE myField = myCondition
) AS stats
WHERE
t.myField = myCondition
AND t.Result BETWEEN (stats.avgr-6*stats.stdr) AND (stats.avgr+6*stats.stdr)
LIMIT 75
Note that you will want to be careful that the statistics are computed over the same set of rows that you are selecting from, hence the duplication of the myField = myCondition predicate, but also the removal of the LIMIT clause to the outer query only.
You can add more statistics to the aggregate subquery, provided that they are all computed over the same set of rows, or you can join additional statistics computed over different rows via a separate subquery. Do ensure that all your statistics subqueries return exactly one row each, else you will get duplicate (or no) results.
I created a UDF that doesn't calculate exactly the way you asked (it discards a percent of the results from the top and bottom, instead of using std), but it might be useful for you
(or someone else) anyway, matching the Excel function referenced here https://support.office.com/en-us/article/trimmean-function-d90c9878-a119-4746-88fa-63d988f511d3
https://github.com/StirlingMarketingGroup/mysql-trimmean
Usage
`trimmean` ( `NumberColumn`, double `Percent` [, integer `Decimals` = 4 ] )
`NumberColumn`
The column of values to trim and average.
`Percent`
The fractional number of data points to exclude from the calculation. For example, if percent = 0.2, 4 points are trimmed from a data set of 20 points (20 x 0.2): 2 from the top and 2 from the bottom of the set.
`Decimals`
Optionally, the number of decimal places to output. Default is 4.

Find which field will limit the result to zero records

Is there any standard way to find which clause has limited the result to zero record?
For example i have this query:
SELECT * FROM `tb` WHERE `room` > 2 AND `keywords` LIKE 'Apartment'
If this query do not return any record, How i can find which field has limited the result to zero record.
When you try to search some thing, if there is no result, Some search engine show you a messeage like this:
Try to search without keywords
Or if you are using MATCH(city) AGAINST('tegas') It show you:
Are you meaning texas
During the query execution, all criteria is evaluated. In order to determine if one specific item caused the query to return zero records, then you must run a separate statement for each criteria scenario.
I would suggest starting with all possible criteria, and then working back based off of the importance of the remaining items. This way you are limiting the processing in the most effective manner.

subtraction in query (SUM)

I have this query that have this output (the correct):
15
44
Query:
SELECT T.numContribuinte,
T.numero,
SUM(C.valor - T.valorTotalChamadas) AS saldo
FROM telemovel T
JOIN CARREGAMENTO C ON C.numero = T.numero
GROUP BY T.numContribuinte, T.numero
HAVING saldo > 0
ORDER BY T.numero DESC
If I remove the word sum the output will be:
15
15
My question is
Why the absence of the sum produce this difference in the output?
The reason for the difference is that by design, MySQL allows columns in the SELECT to not be stated in the GROUP BY or aggregate functions (MAX, MIN, COUNT, etc). The caveat to this functionality is the values returned are arbitrary -- they can't be guaranteed to be consistent every time.
The support is in line with what's dictated by ANSI, but few (SQLite only to my knowledge) support this behavior. Others require the column to either be mentioned in the GROUP BY or enclosed in an aggregate function.
When you GROUP BY some columns, you ask MySQL to take all rows with identical values in those columns, and replace those rows with only one row in the result set. MySQL needs to know from which of those many rows you want each column's value to be in the one row returned. You must use an aggregate function to describe that, like MIN to select the smallest value, MAX to select the largest value, or SUM to select the sum of all the values being replaced.
If you fail to specify an aggregate function, MySQL will take the value from any row it wants. Which row it takes the value from may be different when you run the same query more than once -- the behavior is not defined.