Find the best match from multiple values and columns in MySQL.
Database:
id star point price
1 12 15 16
2 9 15 16
3 18 10 12
Find closes to this
star point price
10 15 14
Results
id: 2
You need a distance metric. But if you have one then you can just use order by and limit. So, if you use a Euclidean metric:
select t.*
from t
order by pow(star - 10, 2) + pow(point - 15, 2) + pow(price - 14, 2)
limit 1;
Note: The square root is not needed for ordering by the Euclidean metric.
Related
There is mysql Ver 8.0.18 value_table as:
value count
1 3
11 1
12 2
22 5
31 1
34 3
35 1
40 3
46 7
What is query to get a total count for each dozen (1-10 - first dozen,11-20 - second , etc..)
as:
1 3
2 3
3 5
4 8
5 7
Query should be flexible, so when some records added to value_table , for example
51 2
62 3
so, it is not necessary to change a query by adding new range (51-60 - 6-th dozen, etc.)
I think you just want division and aggregation:
select min(value), sum(count)
from t
group by floor(value / 10);
To be honest, I'm not sure if the first column should be min(value) or floor(value / 10) + 1.
In the query below:
SELECT column
FROM table
LIMIT 18 OFFSET 8
how many results will we get as output and from where to where?
It will return 18 results starting on record #9 and finishing on record #26.
Start by reading the query from offset. First you offset by 8, which means you skip the first 8 results of the query. Then you limit by 18. Which means you consider records 9, 10, 11, 12, 13, 14, 15, 16....24, 25, 26 which are a total of 18 records.
Check this out.
And also the official documentation.
OFFSET is nothing but a keyword to indicate starting cursor in table
SELECT column FROM table LIMIT 18 OFFSET 8 -- fetch 18 records, begin with record 9 (OFFSET 8)
you would get the same result form
SELECT column FROM table LIMIT 8, 18
visual representation (R is one record in the table in some order)
OFFSET LIMIT rest of the table
__||__ _______||_______ __||__
/ \ / \ /
RRRRRRRR RRRRRRRRRRRRRRRRRR RRRR...
\________________/
||
your result
You will get output from column value 9 to 26 as you have mentioned OFFSET as 8
It will skip first 8 records and desplays records from 9 to 26
limit 18 : Display/select 18 records
offset 8 : will skip 8 records
if Your table has ids like 1,2,3,4,5,6,7,8,9,10,11.... and so on , so 1 to 8 records will be skipped and records after 9 to 26 ie 18 records will be displayed/selected.
Offset is majorly used to support pagination in MySql SELECT statements.
First the query will execute and then the records after the offset will be returned.
For example: let's say you want to show 10 reviews per page for a product as per the order of ratings (highest first), then below query can be used to get the reviews which will be shown on third page:
Select * from Reviews where productid= order by ratings desc LIMIT 10 OFFSET 20.
I have a data set with orders of tickets. Tickets can be bought in packs of 5, or 3, as well as individually. I need to group the data using the quantity of tickets sold per order, to determine if it was a 5 pack (divisible by five), then 3 pack, or else/then individually (1 or 2 qty). So if I have a quantity of 27, I know that order consisted of five "5 packs", and 2 individual tickets.
SUM(CASE WHEN (id % 5) = 0 THEN 1 ELSE 0 END) fivepack
I have this in my query, but stringing these together for fivepack, and threepack, doesn't eliminate the starting number from the total quantity on the next operation. So a quantity of 27, would yield a result of 5 "five packs" and 9 "three packs", and then 27 "individuals".
So given a quantity, how would you first divide by a large factor, get the remainder and divide by the smaller, then finally handle the remainder?
Edit:
The sample packs provide a discount of the purchase price(not relevant to the technical issue), so the first maximum division needs to occur first. So as Gordon Linoff asked below, in the case of 27 tickets quantity, you would take the maximum number of 5 divisions first, then pass the remainder to try to divide by 3, and then return the final remainder as individuals.
The issue is passing the value of one operation in SQL to the next operation, so so on. So I can do Math1, pass Answer1 to Math2, and then pass Answer2 to Math3.
I don't fully understand why 27 would be 5 five packs and 2 individuals rather than any of the following:
27 individuals
9 3-packs
4 5-packs, 2 3-packs, 1-individual
8 3-packs and 3 individuals
and so on.
But, if you want a greedy approach, you can use the following arithmetic:
select floor(num / 5) as five_packs,
floor( (num - 5 * floor(num / 5)) / 3) as three_packs,
num - 5 * floor(num / 5) - 3 * floor( (num - 5 * floor(num / 5)) / 3) as singles
Here is a SQL Fiddle illustrating the logic.
I'm trying to construct a leaderboard where I return 10 rows ordered by score.
However, I want a specific user (ME) to appear in row 5 - so I want the four scores above the specific user to be higher and the five users below the specific user to be lower scores.
There could be hundreds of rows in the database.
So, in other words, I'm trying to get 10 rows, with the user I want in the middle.
So something like this;
user_id, pos, name, score
10, 1, Rita, 100
50, 2, Sue, 95
30, 3, Bob, 60
90, 4, Billy, 50
**14, 5, ME, 45**
46, 6, Bob, 30
89, 7, Thornton, 20
83, 8, Jeremy, 10
99, 9, Kyle, 5
16, 10, John, 1
I think I could crack it with multiple SQL commands, but I'm absolutely stumped if it can be done in one?
Assuming your pos field is always up to date, you can use the between operator after getting the position of Me in your database.
Using these two queries you can get your desired result:
select #pos:=pos FROM so where user_id=5;
select *
FROM so
where pos between #pos-4
and #pos+5
order by score desc;
First query sets the #pos variable value to position of the row you want.
Second query fetches the result that are between #pos-4 and #pos+5.
Here's the output:
user_id pos name score
3 3 Bob 130
4 4 Billy 120
6 5 Bob2 110
7 6 Joe 100
5 7 Me 90
8 8 Mario 80
9 9 Paul 70
10 10 Jeremy 60
11 11 Kyle 50
12 12 Kane 40
Here's the demo.
You could also do it in a single query, but I think it'd hurt the performance.
select *
FROM so
where pos between (select pos FROM so where user_id=5)-4
and (select pos FROM so where user_id=5)+5
order by score desc;
In the query below:
SELECT column
FROM table
LIMIT 18 OFFSET 8
how many results will we get as output and from where to where?
It will return 18 results starting on record #9 and finishing on record #26.
Start by reading the query from offset. First you offset by 8, which means you skip the first 8 results of the query. Then you limit by 18. Which means you consider records 9, 10, 11, 12, 13, 14, 15, 16....24, 25, 26 which are a total of 18 records.
Check this out.
And also the official documentation.
OFFSET is nothing but a keyword to indicate starting cursor in table
SELECT column FROM table LIMIT 18 OFFSET 8 -- fetch 18 records, begin with record 9 (OFFSET 8)
you would get the same result form
SELECT column FROM table LIMIT 8, 18
visual representation (R is one record in the table in some order)
OFFSET LIMIT rest of the table
__||__ _______||_______ __||__
/ \ / \ /
RRRRRRRR RRRRRRRRRRRRRRRRRR RRRR...
\________________/
||
your result
You will get output from column value 9 to 26 as you have mentioned OFFSET as 8
It will skip first 8 records and desplays records from 9 to 26
limit 18 : Display/select 18 records
offset 8 : will skip 8 records
if Your table has ids like 1,2,3,4,5,6,7,8,9,10,11.... and so on , so 1 to 8 records will be skipped and records after 9 to 26 ie 18 records will be displayed/selected.
Offset is majorly used to support pagination in MySql SELECT statements.
First the query will execute and then the records after the offset will be returned.
For example: let's say you want to show 10 reviews per page for a product as per the order of ratings (highest first), then below query can be used to get the reviews which will be shown on third page:
Select * from Reviews where productid= order by ratings desc LIMIT 10 OFFSET 20.