How to find absolute difference between two numbers MYSQL - mysql

What's the best way to find the absolute difference between two numbers in MYSQL so that I may order results? The below works, only if numberA is larger than numberB, but as you can see this is not always the case. Is there a good way to do this with one statement?
SELECT (numberA - numberB) AS spread
FROM table
ORDER BY spread DESC
|-------------------|
| numberA | numberB |
| 5.4 | 2.2 |
| 7.7 | 4.3 |
| 1 | 6.5 |
| 2.3 | 10.8 |
| 4.5 | 4.5 |

As simple as that:
SELECT ABS(numberA - numberB) AS spread
FROM table
ORDER BY spread DESC
Or, if you want to select the pair (numberA, numberB) in descending order of their difference:
SELECT numberA, numberB
FROM table
ORDER BY ABS(numberA - numberB) DESC

MySQL has an ABS() function for that:
select abs(numberA - numberB) as abs_diff
from your_table
ORDER BY abs_diff DESC

Related

MySQL Selection for top x rankings

I want to make a selection in my MySQL database where I have stored numerical values in a specific column.
I have seen some websites that show 10 ten based on some criteria, and I've been wondering if it will be possible to make a selection based on numerical values.
I have my database like so:
| id | name | pts |
+----+-----------+-----+
| 1 | Brad | 3 |
| 2 | Jane | 8 |
| 3 | Jones | 10 |
| 4 | Paty | 15 |
| 5 | Sammy | 2 |
Now my question is, how do I make a query that selects only the top 3 users, based on the pts, such that it returns the result as:
1st Position = Paty => 15pts
2nd Position = Jones => 10pts
3rd Position = Jane => 8pts
?
try this :
SELECT * FROM tablename ORDER BY pts desc limit 3
Your query should use LIMIT to get the top results:
SELECT id, name, points FROM table ORDER BY pts DESC LIMIT 3
shoul do the trick.
Order by will order the table from the highest to the lowest and limit will tell mysql to get only the first three results
You can find more on this topic here for example.
And this is a question very close to your
you can use this query
SELECT CONCAT(`id` , 'Postion = ' , `name` , '=>' ,`pts` , 'pts' ) AS result FROM table ORDER BY pts DESC LIMIT 3
This Question I seen many places anyway the query is.
select top 3 * from tablename order by cols_name desc
This Query brings top 3 row with highest values based on your column.

Is it safe to use LIMIT without ORDER BY

I'm using InnoDB. I need to query to get 10 records from a table is any order.
Is it safe to use LIMIT without ORDER BY? Would it be faster?
If you are not using the ORDER BY then you are not sorting your records, so it will definitely make your data retrieval faster. So if you simply use LIMIT then it would be faster as compared to the data retrieved through ORDER BY. But do note that, in that case the data will not be in any order.
As far as the safety is concerned, I am not sure about which safety you are thinking of, as there is no potential harm in a query which uses only LIMIT and does not uses an ORDER BY clause.
You can also look at the article: ORDER BY … LIMIT Performance Optimization
It depends what you consider as safe- if you want consistent result (meanning, getting the same result everytime as long as the table's content will not change) or if you want specific result (biggests, newest, oldest, whatever)- than this requires order. If by safety you meam that the query wont crush, and you dont care which X results you get- than yes, using limit is fine (this is actually done automatically by many sql tools, like mysql workbench, to speed things up).
In terms of speed- will make it faster without order for two reasons:
ordering takes time.
Using limit allow the server to stop as it finds the first X results. You can see that queries with limit 10 will run faster than limit 100000 on large tables. When you use order, the server must go through all result, so cant stop in the middle.
So yes, using limit without order will make it faster
Yes, you can and yes, it would be faster (assuming the order does not matter to you). order by requires sorting. This means the database has to do more work to get you the result. Most commonly limit is used with order by since want to put some ordering constraints on which 10 records you get (say most recent, highest rank of some sort, etc.)
It's not safe.
Without a order by, the results may not be consistent over consecutive excutions of the same query.
Refer to mysql limit collapse, which result in data interaction
For example:(course_id is the primay key).
Get the first page 10 rows;
select course_id,grade_id from sc_base_course where agency_id = 10000 limit 0,10;
+-----------+----------+
| course_id | grade_id |
+-----------+----------+
| 13 | 1 |
| 6 | 3 |
| 12 | 4 |
| 8 | 2 |
| 7 | 2 |
| 9 | 4 |
| 16 | 1 |
| 1 | 2 |
| 17 | 1 |
| 14 | 5 |
+-----------+----------+
Get the second page 7 rows
select course_id,grade_id from sc_base_course where agency_id = 10000 limit 10,10;
+-----------+----------+
| course_id | grade_id |
+-----------+----------+
| 11 | 4 |
| 12 | 4 |
| 13 | 1 |
| 14 | 5 |
| 15 | 1 |
| 16 | 1 |
| 17 | 1 |
+-----------+----------+
The 3 answers so far are good. But they are not totally correct.
Contrary to the other answers, sometimes leaving out ORDER BY will not make it faster. The optimizer might happen to generate the rows in that order anyway. Examples:
GROUP BY usually orders the results. So, if the ORDER BY would match the GROUP BY, there is no extra effort.
ORDER BY the_primary_key might match the order of fetching. This is almost guaranteed to be the case for InnoDB without a WHERE clause.
"Safe" does not compute.

Finding the 3 smallest numbers in a column

I have a table like this:
| songtitle | songlength |
|------------|-------------|
| 1 | 3:42 |
| 2 | 1:32 |
| 3 | 2:44 |
| 4 | 5:00 |
| 5 | 1:19 |
| 6 | 2:54 |
And I want to get the 3 shortest songs (sorted shortest to longest).
I figure I will need something like LIMIT but I'm not positive. Thanks
Sort the data and limit the number of rows you want to retreive:
select *
from your_table
order by songlength
limit 3;
If you'd like to get the 3 longest songs, simply order the data in descending order:
select *
from your_table
order by songlength desc
limit 3;
Addressing Dwza's comment, quoting from MySQL Reference Manual:
Columns selected for output can be referred to in ORDER BY and GROUP BY clauses using column names, column aliases, or column positions. [...] To sort in reverse order, add the DESC (descending) keyword to the name of the column in the ORDER BY clause that you are sorting by. The default is ascending order; this can be specified explicitly using the ASC keyword.
Use the "SORT" function to sort them natively in MySQL.

Grouping MySQL results

I have the following MySQL query:
SELECT * FROM members_family_view ORDER BY `agelastsept` ASC
Which returns the following results:
I want to be able to change the data returned for display purposes so that instead of agelastsept displaying 7 it would display U8's, 8 would display U9's, 10 would display U11's, 11 would display U12's, 12 would display U13's and 13 would display U14's.
Is this possible in a MySQL query?
try this query
select concat('U', (id+1), '\'s') as Name, total from tbl
SQL FIDDLE:
| NAME | TOTAL |
----------------
| U2's | 50 |
| U3's | 55 |
| U4's | 89 |
You simply need to concatenate:
SELECT
CONCAT("U", agelastsept + 1, "'s") AS 'agelastsept',
total
FROM members_family_view
ORDER BY `agelastsept` ASC
Select CONCAT("U", (agelastsept + 1 ), "'s") as agelastsept,total FROM members_family_view ORDER BY `agelastsept` ASC

How to sample rows in MySQL using RAND(seed)?

I need to fetch a repeatable random set of rows from a table using MySQL. I implemented this using the MySQL RAND function using the bigint primary key of the row as the seed. Interestingly this produces numbers that don't look random at all. Can anyone tell me whats going on here and how to get it to work properly?
select id from foo where rand(id) < 0.05 order by id desc limit 100
In one example out of 600 rows not a single one was returned. I change the select to include "id, rand(id)" and get rid of the rand clause in the where this is what I got:
| 163345 | 0.315191733944408 |
| 163343 | 0.814825518815616 |
| 163337 | 0.313726862253367 |
| 163334 | 0.563177533972242 |
| 163333 | 0.312994424545201 |
| 163329 | 0.312261986837035 |
| 163327 | 0.811895771708242 |
| 163322 | 0.560980224573035 |
| 163321 | 0.310797115145994 |
| 163319 | 0.810430896291911 |
| 163318 | 0.560247786864869 |
| 163317 | 0.310064677437828 |
Look how many 0.31xxx lines there are. Not at all random.
PS: I know this is slow but in my app the where clause limits the number of rows to a few 1000.
Use the same seed for all the rows to do that, like:
select id from foo where rand(42) < 0.05 order by id desc limit 100
See the rand() docs for why it works that way. Change the seed if you want another set of values.
Multiply the decimal number returned by id:
select id from foo where rand() * id < 5 order by id desc limit 100