MySQL select the nearest lower value in table - mysql

I have an SQL table that stores running times and a score associated with each time on the table.
/////////////////////
/ Time * Score /
/ 1531 * 64 /
/ 1537 * 63 /
/ 1543 * 61 /
/ 1549 * 60 /
/////////////////////
This is an example of 4 rows in the table. My question is how do I select the nearest lowest time.
EXAMPLE: If someone records a time of 1548 I want to return the score for 1543 (not 1549) which is 61.
Is there an SQL query I can use to do this thank you.

Use SQL's WHERE clause to filter the records, its ORDER BY clause to sort them and LIMIT (in MySQL) to obtain only the first result:
SELECT Score
FROM my_table
WHERE Time <= 1548
ORDER BY Time DESC
LIMIT 1
See it on sqlfiddle.

Related

mySql difference performance in a where query

I have a table with 95084 rows. I found this two perfomance differences:
EXPAIN SELECT * FROM sensor WHERE fecha >= '2022-07-16 10:00:00'; It requires 32 rows.
EXPAIN SELECT * FROM sensor WHERE DATE(fecha) = '2022-07-16' AND HOUR(fecha) >= '10:00:00'; That grows up to 95084 rows.
How Mysql works in that way and why this difference?. Thank you

Optimizing MySQL query with a composite index

I have a table which currently has about 80 million rows, created as follows:
create table records
(
id int auto_increment primary key,
created int not null,
status int default '0' not null
)
collate = utf8_unicode_ci;
create index created_and_status_idx
on records (created, status);
The created column contains unix timestamps and status can be an integer between -10 and 10. The records are evenly distributed regarding the created date, and around half of them are of status 0 or -10.
I have a cron that selects records that are between 32 and 8 days old, processes them and then deletes them, for certain statuses. The query is as follows:
SELECT
records.id
FROM records
WHERE
(records.status = 0 OR records.status = -10)
AND records.created BETWEEN UNIX_TIMESTAMP() - 32 * 86400 AND UNIX_TIMESTAMP() - 8 * 86400
LIMIT 500
The query was fast when the records were at the beginning of the creation interval, but now that the cleanup reaches the records at the end of interval it takes about 10 seconds to run. Explaining the query says it uses the index, but it parses about 40 million records.
My question is if there is anything I can do to improve the performance of the query, and if so, how exactly.
Thank you.
I think union all is your best approach:
(SELECT r.id
FROM records r
WHERE r.status = 0 AND
r.created BETWEEN UNIX_TIMESTAMP() - 32 * 86400 AND UNIX_TIMESTAMP() - 8 * 86400
LIMIT 500
) UNION ALL
(SELECT r.id
FROM records r
WHERE r.status = -10 AND
r.created BETWEEN UNIX_TIMESTAMP() - 32 * 86400 AND UNIX_TIMESTAMP() - 8 * 86400
LIMIT 500
)
LIMIT 500;
This can use an index on records(status, created, id).
Note: use union if records.id could have duplicates.
You are also using LIMIT with no ORDER BY. That is generally discouraged.
Your index is in the wrong order. You should put the IN column (status) first (you phrased it as an OR), and put the 'range' column (created) last:
INDEX(status, created)
(Don't give me any guff about "cardinality"; we are not looking at individual columns.)
Are there really only 3 columns in the table? Do you need id? If not, get rid of it and change to
PRIMARY KEY(status, created)
Other techniques for walking through large tables efficiently.

MySQL get new data

How I can get 100 new records everyday from a database comprised of 10,000 rows?
note : every day new 100 rows not edited
My current query is:
SELECT * FROM `invoices` WHERE DATE(`ModifiedTime`)=CURDATE()) Limit 100
How i can show 100 rows every day ?
The additional ")" after the curdate() function was removed to prevent the syntax error. See SQL Fiddle demo
Before
SELECT * FROM `invoices` WHERE DATE(`ModifiedTime`)=CURDATE()) Limit 100
After
SELECT * FROM `invoices` WHERE DATE(`ModifiedTime`)=CURDATE() Limit 100

Group by 2 mintues mysql

Mysql Table:
I want to take sum of acceleCount for 2 minutes intervals.
Query:
select time div 120000 as TwoMinutes,
sum(acceleCount) as Sum
from acceleTable
group by time div 120000
Result:
Here the twoMinutes column timestamp is meaning less. I want it to have a timestamp which is within the considering two minutes.
Any thoughts on how to change the sql query?
Bring the timestamps to a common denominator by dividing, rounding and multiplying:
SELECT
(ROUND(time / 120) * 120),
sum(acceleCount)
FROM acceleTable
GROUP BY (ROUND(time / 120) * 120)
A little optimized way to do it
SELECT (ROUND(time / 120000) * 120000) AS timekey, sum(acceleCount)
FROM acceleTable
GROUP BY timekey

How do I insert a random value into mysql?

It looks like RAND is what I need but I'm having a bit of trouble understanding how it works.
I need to insert a random number between 60 and 120 into a couple thousand rows. Table name is: listing and the column name is: hits
Could you please help?
To make a random integer between 60 and 120, you need to do a bit of arithmetic with the results of RAND(), which produces only floating point values:
SELECT FLOOR(60 + RAND() * 61);
So what's going on here:
RAND() will produce a value like 0.847269199. We multiply that by 61, which gives us the value 51.83615194. We add 60, since that's your desired offset above zero (111.83615194). FLOOR() rounds the whole thing down to the nearest whole number. Finally, you have 111.
To do this over a few thousand existing rows:
UPDATE table SET randcolumn = FLOOR(60 + RAND() * 61) WHERE (<some condition if necessary>);
See the MySQL docs on RAND() for more examples.
Note I think I have the arithmetic right, but if you get values of 59 or 121 outside the expected range, change the +60 up or down accordingly.
Here is how to get the random number in a range. The following can bit a bit ambiguous simply because the 61 is actually your max value (120) minus your min value (60) + 1 to get inclusive results.
SELECT FLOOR(60 + (RAND() * 61));
SELECT FLOOR(MIN_Value + (RAND() * (MAX_Value - MIN_Value) + 1);
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand
UPDATE X SET C = FLOOR(61 * RAND() + 60) WHERE ...;
to get a number between 60 and 120 (including 60 and 120);
RAND() creates a number in the interval [0;1) (that is excluding 1). So 61 * RAND() yields a number in [0, 61). 61 * RAND() + 60 is in [60;121) By rounding down you ensure that your number is indeed in [60;120].
When I faced this kind of issue, I tried manual, but I have over 500 lines,
I logically brought a trick which helped me, because if you run RAND on query,
you might end up getting error report due to Duplicates, OR PRIMARY KEY issue, especially if that column is a PRIMARY KEY and AUTO INCREMENT.
Firstly - I renamed the column in question, e.g. mine was ID -> IDS
Secondly - I created another column and Called it ID
Thirdly - I RAN this code
UPDATE history SET id = FLOOR( 217 + RAND( ) *2161 )
This created a random numbers automatically, later i deleted the renamed IDS colume
credit FROM MICHAEL.
Thank you