How to create query with simple formula? - mysql

Hey is there any way to create query with simple formula ?
I have a table data with two columns value_one and value_two both are decimal values. I want to select this rows where difference between value_one and value_two is grater then 5. How can i do this?
Can i do something like this ?
SELECT * FROM data WHERE (MAX(value_one, value_two) - MIN(value_one, value_two)) > 5
Example values
value_one, value_two
1,6
9,3
2,3
3,2
so analogical difs are: 5, 6, 1, 1 so the selected row would be only first and second.

Consider an example where smaller number is subtracted with a bigger number:
2 - 5 = -3
So, the result is a difference of two numbers with a negation sign.
Now, consider the reverse scenario, when bigger number is subtracted with the smaller number:
5 - 2 = 3
Pretty simple right.
Basically, the difference of two number remains same, if you just ignore the sign. This is in other words called absolute value of a number.
Now, the question arises how to find the absolute value in MySQL?
Answer to this is the built-in method of MySQL i.e. abs() function which returns an absolute value of a number.
ABS(X):
Returns the absolute value of X.
mysql> SELECT ABS(2);
-> 2
mysql> SELECT ABS(-32);
-> 32
Therefore, without worrying about finding min and max number, we can directly focus on the difference of two numbers and then, retrieving the absolute value of the result. Finally, check if it is greater than 5.
So, the final query becomes:
SELECT *
FROM data
WHERE abs(value_one - value_two) > 5;
You can also do complex operations once the absolute value is calculated like adding or dividing with the third value. Check the code below:
SELECT *
FROM
data
WHERE
(abs(value_one - value_two) / value_three) + value_four > 5;
You can also add multiple conditions using logical operators like AND, OR, NOT to do so. Click here for logical operators.
SELECT *
FROM
data
WHERE
((abs(value_one - value_two) / value_three) + value_four > 5)
AND (value_five != 0);
Here is the link with various functions available in MySQL:
https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html

No, you would just use a simple where clause:
select *
from data
where abs(value_one - value_two) > 5;

Related

Why is my query returning "OK" instead of rows?

I have the following query:
SELECT
(sign(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time)) AS h2h_win_one_time_1,
(abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time) ^ 2) AS h2h_win_one_time_2
FROM belgarath.match_result AS mr
LIMIT 10
Which returns:
However, when I try to multiply the two fields:
SELECT
(
sign(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time)
) *
(
abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time) ^ 2
) AS h2h_win_one_time_comb
FROM belgarath.match_result AS mr
LIMIT 10
Workbench simply returns OK instead of any rows.
Doing some investigation I can get the first two rows to display if I use LIMIT 2. Looking at the returned values above I guess there must be some issue with multiplying the minus values or zero values from rows 3-10. However, this can be done simply on a calculator so what am I missing?
Maybe you think that the operator ^ is the power operator when in fact it is the Bitwise XOR operator.
MySql has the function pow() for your case:
pow(abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time), 2)

Get value between from to dataset columns ssrs

I have a data set like that:
Data Set Contents
From To Comment
----+---+--------
0 50 Bad
50 70 Good
70 100 Excellent
If I have a value of 75, I need to get Excellent by searching the Dataset.
I know about the lookup function but it is not what I want. How can I do that?
The values should be in percentage.
Note : the value (75) is Average of a column (Calculated) it
calculate student grade from max and student mark Version SQL Server
2016
Note 2 : the dataset is from database not static values
Thank You
Assuming you only ever have a fixed number of 'grades' then this will work. However, I would strongly recommend doing this type of work on the server where possible.
Here we go...
I created two datasets
dsGradeRange with the following sql to recreate your example (more or less)
DECLARE #t TABLE (low int, high int, comment varchar(20))
INSERT INTO #t VALUES
(0,49,'Bad'),
(50,69,'Good'),
(70,100, 'Excellent')
SELECT * FROM #t
dsRandomNumbers This just creates 30 random numbers between 0 and 100
SELECT *
FROM (SELECT top 30 ABS(CHECKSUM(NEWID()) % 100) as myNumber FROM sys.objects) x
ORDER BY myNumber
I added a table to the report to show the grades (just for reference).
I then added a table to show the dsRandomNumbers
Finally I set the expression of the 2nd column to the following expression.
=SWITCH
(
Fields!myNumber.Value < LOOKUP("Bad", Fields!comment.Value, Fields!high.Value, "dsGradeRange"), "Bad",
Fields!myNumber.Value < LOOKUP("Good", Fields!comment.Value, Fields!high.Value, "dsGradeRange"), "Good",
True, "Excellent"
)
This gives the following results
As you can see we only need to compare to the high value of each case, the first match will return the correct comment.
Right click on your dataset and add a calculated field. Go to Field Properties > Fields > Add and add the following expression, which descripes your scenario:
=IIF(Fields!Number.Value < 50, "Bad", "Good")

MYSQL - Find rows, where part of search string matches part of value in column

I wasn't able to find this anywhere, here's my problem:
I have a string like '1 2 3 4 5' and then I have a mysql table that has a column, let's call it numbers, that look like this:
numbers
1 2 6 8 9 14
3
1 5 3 6 9
7 8 9 23 44
10
I am trying to find the easiest way (hopefully in a single query) to find the rows, where any of the numbers in my search string (1 or 2 or 3 or 4 or 5) is contained in the numbers column. In the give example I am looking for rows with 1,2 and 3 (since they share numbers with my search string).
I am trying to do this with a single query and no loops.
Thanks!
The best solution would be to get rid of the column containing a list of values, and use a schema where each value is in its own row. Then you can use WHERE number IN (1, 2, 3, 4, 5) and join this with the table containing the rest of the data.
But if you can't change the schema, you can use a regular expression.
SELECT *
FROM yourTable
WHERE numbers REGEXP '[[:<:]](1|2|3|4|5)[[:<:]]'
[[:<:]] and [[:<:]] match the beginning and end of words.
Note that this type of search will be very slow if the table is large, because it's not feasible to index it.
Here is a start point (split string function) : http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ := SplitString(string,delimiter,position)
Create a function so it converts a string to an array := stringSplitted(string,delimiter)
Create a function so it compares two arrays :=arrayIntersect(array1, array2)
SELECT numbers
FROM table
WHERE arrayIntersect(#argument, numbers)
Two function definitions with loops and one single query without any loop
SELECT * FROM MyTable WHERE (numbers LIKE '%1%' OR numbers LIKE '%2%')
or you can also use REGEX something like this
SELECT * FROM events WHERE id REGEXP '5587$'

BETWEEN operator working wrong in MySQL

I have a query having BETWEEN operator but it showing wrong results
My query-
SELECT * FROM register WHERE height BETWEEN '1' AND '6'
It also shows the user with height 10, 12 and 16 which is wrong. What is the problem with this query?
I have another query which work fine but is not proper way of using as it make query lengthy
SELECT * FROM register WHERE height > 1 AND height < 12
Give me idea for right way of getting the query as if more condition is added it would be hard for the query to understand and code.
Assuming height is an integer should it not be
SELECT * FROM register WHERE height BETWEEN 1 AND 6
You don't need the single quotes
If:
1. You can't or don't want to change the column type
2. The charachters in the field are only numbers
You can change your query to:
SELECT *
FROM register
WHERE CONVERT(height, UNSIGNED INTEGER) BETWEEN 1 AND 6
See my example at this SQL fiddle.
Check the data type of your column 'Height' it should be a int or float or double and if it is amongs above run the following query
SELECT * FROM register WHERE height BETWEEN 1 AND 6
If the height field is not numeric, you could convert it before making you comparison.
SELECT * FROM register WHERE CONVERT(height, unsigned) BETWEEN 1 AND 6

Select random row from MySQL (with probability)

I have a MySQL table that has a row called cur_odds which is a percent number with the percent probability that that row will get selected. How do I make a query that will actually select the rows in approximately that frequency when you run through 100 queries for example?
I tried the following, but a row that has a probability of 0.35 ends up getting selected around 60-70% of the time.
SELECT * FROM table ORDER BY RAND()*cur_odds DESC
All the values of cur_odds in the table add up to 1 exactly.
If cur_odds is changed rarely you could implement the following algorithm:
1) Create another column prob_sum, for which
prob_sum[0] := cur_odds[0]
for 1 <= i <= row_count - 1:
prob_sum[i] := prob_sum[i - 1] + cur_odds[i]
2) Generate a random number from 0 to 1:
rnd := rand(0,1)
3) Find the first row for which prob_sum > rnd (if you create a BTREE index on the prob_sum, the query should work much faster):
CREATE INDEX prob_sum_ind ON <table> (prob_sum);
SET #rnd := RAND();
SELECT MIN(prob_sum) FROM <table> WHERE prob_sum > #rnd;
Given your above SQL statement, whatever numbers you have in cur_odds are not the probabilities that each row is selected, but is instead just an arbitrary weighting (relative to the "weights" of all the other rows) which could instead be best interpreted as a relative tendency to float towards the top of the sorted table. The actual value in each row is meaningless (e.g. you could have 4 rows with values of 0.35, 0.5, 0.75 and 0.99, or you could have values of 35, 50, 75 and 99, and the results would be the same).
Update: Here's what's going on with your query. You have one row with a cur_odds value of 0.35. For the sake of illustration, I'm going to assume that the other 9 rows all have the same value (0.072). Also for the sake of illustration, let's assume RAND() returns a value from 0.0 to 1.0 (it may actually).
Every time you run this SELECT statement, each row is assigned a sorting value by multiplying its cur_odds value by a RAND() value from 0.0 to 1.0. This means that the row with a 0.35 will have a sorting value between 0.0 and 0.35.
Every other row (with a value of 0.072) will have sorting values ranging between 0.0 and 0.072. This means that there is an approximately 80% chance that your one row will have a sorting value greater than 0.072, which would mean that there is no possible chance that any other row could be sorted higher. This is why your row with the cur_odds value of 0.35 is coming up first more often than you expect.
I incorrectly described the cur_odds value as a relative change weighting. It actually functions as a maximum relative weighting, which would then involve some complex math to determine the actual relative probabilities involved.
I'm not sure what you need can be done with straight T-SQL. I've implemented a weighted probability picker many times (I was even going to ask a question about best methods for this this morning, ironically) but always in code.