I have a variance report query here I need the 'Variance' to not have 10 decimal points in the Variance Column. What is the most convenient way to round Variance results to the 100th?
WITH A AS
(
select
A.FACTORY,
A.JOB_NUMBER,
A.PROCESS_STAGE,
A.PART_CODE,
B.PART_DESC_1,
A.INPUT_QTY_STD,
A.QUANTITY_INPUT,
A.QUANTITY_OUTSTANDING,
A.INPUT_QTY_ACTUAL,
(A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)) as variance,
A.ACTUAL_CLOSE_DATE
from
(select * from [man_prod].[dbo].[JOB_STAGE_LINES]
where JOB_NUMBER in (select JOB_NUMBER from JOB_OUTPUTS where
BF_QTY_ACTUAL<>0
and ABS(DATEDIFF(HOUR,ACTUAL_CLOSE_DATE,GETDATE())) < 12 and STATUS_FLAG='C'
)) A
join fin_prod.dbo.PRODUCT_MASTER B
ON A.PART_CODE=B.PART_CODE
WHERE
A.INPUT_QTY_STD<>0 and
A.QUANTITY_OUTSTANDING <>0
)
SELECT * FROM A WHERE A.variance >10.000000 OR A.variance <-10
order by PROCESS_STAGE asc ,PART_CODE asc, variance desc ;
The Variance column comes out at 00.0000000000 i need it to display 00.000 or 00.000000
Help is greatly appreciated
Use the MySQL ROUND() function, the second argument is the number of decimal places if it is positive.
ROUND((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
In this example if the value is 0.0000000000 it would be rounded to 3 decimal places, or 0.000.
You can use the TRUNCATE option:
TRUNCATE((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
or use the ROUND if you are looking for rounding(as suggested by doublesharp)
ROUND((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
Using Convert to convert it to a decimal of the desired length is what i prefer when i am not actually rounding the value, just formatting.
CONVERT(DECIMAL(10,3),10000)
Related
I need an SQL query , with multiple AND's. Let me explain with an example,
For example I want to search in a database for a property , who's price is greater than 1000 and less than 2000 (price is between 1000-2000), and its area is greater than 1000 sqft. and less than 2000 sq ft. (area is between 1000-2000).
So i was guessing that the query could be,
SELECT *
FROM table_name
WHERE (price>1000 AND price<2000) AND (area>1000 AND area<2000)
this is something i need ! Thank you
Your original query looks fine to me, but you can also use BETWEEN if you like, try this:
SELECT * FROM table_name WHERE (price BETWEEN 1001 AND 2000) AND (area BETWEEN 1001 AND 2000);
expr BETWEEN min AND max
If expr is greater than or equal to min and expr is less than or equal to max, BETWEEN returns 1, otherwise it returns 0. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. Otherwise type conversion takes place according to the rules described in Section 12.2, “Type Conversion in Expression Evaluation”, but applied to all the three arguments
Use between instead of and
SELECT * FROM table_name WHERE (price between 1001 AND 1999) AND (area between 1001 AND 1999)
Use this, i think it will solve your problem. It works for me:
SELECT * FROM table_name WHERE price and area BETWEEN 1001 and 1999.
If we have same values of the parameters, then we can add the condition with and all the parameters.
I am trying to get the percent and it just shows up as zero. I want to show two decimal places such as 0.65
Here is a piece of the query I am selecting:
select count(numbers)/count(othernumbers) decimal(3,2) as"rate"
if I use this it shows up as 0 and gets rid of the rest
select count(numbers)/count(othernumbers) as"rate"
need to convert both of your "count(numbers)" and "count(othernumbers)" to decimal also.
select convert(decimal(5,2), count(numbers))
/
convert(decimal(5,2), count(othernumbers))
as"rate"
Here's an example that works in SSMS (Sql Server):
select Convert(decimal(3,2), convert(decimal(4,2), 1.0) / convert(decimal(4,2), 10.0)) as [rate]
You have to use this convert value to Decimal, This will give you the decimal till two places
SELECT CONVERT( DECIMAL(10,2),
( CONVERT(DECIMAL(10,2), numbers) /
CONVERT(DECIMAL(10,2), othernumbers) ) ) AS rate
SELECT FORMAT(this / that, 2) as rate
Meanwhile, I question whether COUNT(numbers) is what you want. That counts how many rows have a non-NULL value in the column numbers.
Also, fraction is usually more like x / (x+y) -- meaning the fraction of the total (x+y) that is x.
A "percentage" needs 100* somewhere. 13/20 is the fraction 0.65 or the percentage 65.00 .
Have you checked ceil(), floor() and round()
If you want without rounding anything
SELECT TRUNCATE(count(numbers)/count(othernumbers),2) as "rate"
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_truncate
select convert(decimal(11, 2), 102)
select convert(decimal(11, 2), 102.5)
select convert(decimal(11, 2), 102.74)
select convert(decimal(11, 2), 102.745)
Results:
102.00;
102.50;
102.74;
102.75
In a column I have something like this:
Amount:
12
2x25
192
How is it possible to multiply in this example 2x25 to order it correctly ASC.
My starting point:
SELECT * FROM table
ORDER BY REPLACE(Amount,'x','*') ASC
TIA
frgtv10
try this
SELECT
CAST(if(Amount LIKE '%x%', SUBSTRING_INDEX(Amount, 'x', 1) *
SUBSTRING_INDEX(Amount, 'x', -1) , Amount) as unsigned ) as amount
FROM table1
ORDER BY Amount ASC
DEMO HERE
steps and explaining :
locate fields with x value
sbstring from left and right and multiply it.
then cast the multiplication as unsigned.
order it asc
As long as this is the only formula (multiplying 2 numbers), you should be able to hard-code it with INSTR, SUBSTRING, and CONVERT.
I created a field called 'hours_spent' in MySQL using the decimal datatype to store time. The values are stored like this 1.30, 2.30 etc... (for 1hr30min, 2hr30min).
I want to calculate the sum of various time values.
The sum of time is not what I expected: 1.30 + 2.30 = 3.60, whereas I expected 4.00.
I used the SUM function in MySQL to count the hours_spent field. If the values are 0.30 + 1.50 = 1.80, whereas I expected 2.20.
My first mistake was to use the decimal type instead of the time datatype, but I cannot change datatype.
So, is there any way to sum the time values and get result as I expect?
Thanks
I prepared you a demo at sqlfiddle, you can try it there if you want:
http://www.sqlfiddle.com/#!2/c9afc/2
Here are the query samples:
select #indexer:=instr(dateasdecimal, '.')
, left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1) as totalMinutes
from testtable;
select #indexer:=instr(dateasdecimal, '.')
, sum(left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1)) as totalMinutes
from testtable;
Note: Please don't forget to accept answers to your questions:
https://meta.stackexchange.com/a/65088/200585
To convert a decimal into seconds, you could use this:
truncate(hours_spent,0)*60+(hours_spent-truncate(hours_spent,0))*100
and then you can do the sums easily. Then you can convert back seconds to the decimal format with this:
truncate(seconds/60,0)+truncate(mod(seconds, 60)/100,2)
You could always turn the decimals into a string, cast as time, then sum that time using time_to_sec and produce a formatted time with sec_to_time. Of course, it would be much better to be storing those times a different way, even if it involves converting the entire dataset.
SELECT sec_to_time(sum(time_to_sec(goodTime))) FROM (
SELECT CAST(badTime AS TIME) AS goodTime FROM (
SELECT REPLACE(badTime, '.', ':') AS badTime FROM (
SELECT CAST(badTime AS dec(4,2)) AS badTime FROM (
SELECT 1.3 AS badTime
UNION select 2.3
) z
) y
) x
) w
I'm having trouble with calculating the median of a list of values, not the average.
I found this article
Simple way to calculate median with MySQL
It has a reference to the following query which I don't understand properly.
SELECT x.val from data x, data y
GROUP BY x.val
HAVING SUM(SIGN(1-SIGN(y.val-x.val))) = (COUNT(*)+1)/2
If I have a time column and I want to calculate the median value, what do the x and y columns refer to?
I propose a faster way.
Get the row count:
SELECT CEIL(COUNT(*)/2) FROM data;
Then take the middle value in a sorted subquery:
SELECT max(val) FROM (SELECT val FROM data ORDER BY val limit #middlevalue) x;
I tested this with a 5x10e6 dataset of random numbers and it will find the median in under 10 seconds.
This will find an arbitrary percentile by replacing the COUNT(*)/2 with COUNT(*)*n where n is the percentile (.5 for median, .75 for 75th percentile, etc).
val is your time column, x and y are two references to the data table (you can write data AS x, data AS y).
EDIT:
To avoid computing your sums twice, you can store the intermediate results.
CREATE TEMPORARY TABLE average_user_total_time
(SELECT SUM(time) AS time_taken
FROM scores
WHERE created_at >= '2010-10-10'
and created_at <= '2010-11-11'
GROUP BY user_id);
Then you can compute median over these values which are in a named table.
EDIT: Temporary table won't work here. You could try using a regular table with "MEMORY" table type. Or just have your subquery that computes the values for the median twice in your query. Apart from this, I don't see another solution. This doesn't mean there isn't a better way, maybe somebody else will come with an idea.
First try to understand what the median is: it is the middle value in the sorted list of values.
Once you understand that, the approach is two steps:
sort the values in either order
pick the middle value (if not an odd number of values, pick the average of the two middle values)
Example:
Median of 0 1 3 7 9 10: 5 (because (7+3)/2=5)
Median of 0 1 3 7 9 10 11: 7 (because 7 is the middle value)
So, to sort dates you need a numerical value; you can get their time stamp (as seconds elapsed from epoch) and use the definition of median.
Finding median in mysql using group_concat
Query:
SELECT
IF(count%2=1,
SUBSTRING_INDEX(substring_index(data_str,",",pos),",",-1),
(SUBSTRING_INDEX(substring_index(data_str,",",pos),",",-1)
+ SUBSTRING_INDEX(substring_index(data_str,",",pos+1),",",-1))/2)
as median
FROM (SELECT group_concat(val order by val) data_str,
CEILING(count(*)/2) pos,
count(*) as count from data)temp;
Explanation:
Sorting is done using order by inside group_concat function
Position(pos) and Total number of elements (count) is identified. CEILING to identify position helps us to use substring_index function in the below steps.
Based on count, even or odd number of values is decided.
Odd values: Directly choose the element belonging to the pos using substring_index.
Even values: Find the element belonging to the pos and pos+1, then add them and divide by 2 to get the median.
Finally the median is calculated.
If you have a table R with a column named A, and you want the median of A, you can do as follows:
SELECT A FROM R R1
WHERE ( SELECT COUNT(A) FROM R R2 WHERE R2.A < R1.A ) = ( SELECT COUNT(A) FROM R R3 WHERE R3.A > R1.A )
Note: This will only work if there are no duplicated values in A. Also, null values are not allowed.
Simplest ways me and my friend have found out... ENJOY!!
SELECT count(*) INTO #c from station;
select ROUND((#c+1)/2) into #final;
SELECT round(lat_n,4) from station a where #final-1=(select count(lat_n) from station b where b.lat_n > a.lat_n);
Here is a solution that is easy to understand. Just replace Your_Column and Your_Table as per your requirement.
SET #r = 0;
SELECT AVG(Your_Column)
FROM (SELECT (#r := #r + 1) AS r, Your_Column FROM Your_Table ORDER BY Your_Column) Temp
WHERE
r = (SELECT CEIL(COUNT(*) / 2) FROM Your_Table) OR
r = (SELECT FLOOR((COUNT(*) / 2) + 1) FROM Your_Table)
Originally adopted from this thread.