Guys i have this structure in a table:
The table holds a history of prices for set of Market Links connected to Exchanges. The data is continuously growing - every x seconds new prices are added.
I need to find out which MarketLink is currently the cheapest (ASK price)
What should be the query?
You need to order your result by latest time ie. epoch
SELECT id,MarketLink,MIN(Ask) from tbl_name ORDER by epoch DESC LIMIT 0 ;
I think this is what you're looking for. Hope it helps you out.
SELECT MIN(Ask) cheapest from tbl_name;
EDIT
In order to achieve this, You'll have to keep track of the records that you've already scanned, say for example you can use ID or a timestamp, every time you query. So while querying, what you're supposed to do is, use that ID or a timestamp as a benchmark and check for the Min(Ask) after that Id or timestamp.
Related
I'm curious about what the best approach for this might be.
Currently, I have a dummy table that stores each time a person clocked in to work. It repeats a lot of info about that employee in each row, e.g. their name, their employee id, position, etc. The main thing different, of course, is the time stamp.
If I want the latest date each employee clocked in, I'm wondering how I would do it via a drop duplicates approach. E.g. in Python, I would sort by date in descending order, and then drop_duplicates on the employee ID column. I'm wondering what the equivalent in SQL is, that isn't the greatest-n-per-group method.
As #Gordon Linoff said if you can share your data table we will be able help you better. But you can try using the MAX Keyword. Like
Select * from your_table t
Where CheckinDate = (select MAX(CheckinDate) from your_table where employeeId = t.employeeId)
SELECT * FROM dogs order by rand(dayofyear(CURRENT_DATE)) LIMIT 1
It seems to me that it orders a database by a random number, and this number changes every day. This is a guess, as it'll take me a day to find out if this is true!
How can I change this query to order a database by a new random number every minute rather than every day? I tried this:
SELECT * FROM dogs order by rand(minuteofhour(CURRENT_DATE)) LIMIT 1
but it didn't work :(
Thanks for your time!
A random number generator (RNG) usually needs a 'seed value', a value that is used to generate random numbers. If the seed value is always the same, the sequence of random numbers is always the same. This explains why it changes every day.
The easiest way to solve your problem (change it to every minute) is to find a seed value that changes every minute. A good one would be ROUND(UNIX_TIMESTAMP()/60).
SELECT * FROM dogs order by rand(ROUND(UNIX_TIMESTAMP()/60)) LIMIT 1
I am not good at mysql. but are you sure is there a function minuteofhour in mysql?
The idea of query is to pick a random record from database.
you can do this by:
SELECT * FROM dogs order by rand(20) LIMIT 1
it will order by column "a random number from 1-20"
Use combo of MySQL's funcs MINUTE() and NOW(). NOW will return current date, and MINUTE extracts minute value from it.
I'm creating a site where all of the users have a score that is updated everyday. I can easily create rankings from this score, however I'd like to be able to create a "Hot" list of the week or month, etc..
My brute force design would be each day for every user, calculate their score and put it into the "Scores" table. So everyday the Scores table would increase by how many users there are. I could rank users by their score deltas over whatever time period.
While I believe this would technically work I feel like there has to be a more sophisticated way of doing this, right? Or not? I feel like a Scores table that increases everyday by how many users there are can't be the way other sites are doing it.
You get the most flexibility by not storing any snapshots of score at all. Instead, record incremental scores, as they happen.
If you have tables like this:
USER
user_id
name
personal_high_score
{anything else that you store once per user}
SCORE_LOG
score_log_id
user_id (FK to USER)
date_time
scored_points
Now you can get a cumulative score for a user as of any point in time with a simple query like:
select sum(scored_points)
from SCORE_LOG
where user_id = #UserID
and date_time <= #PointInTime
You can also easily get top ranking scorers for a time period with something like:
select
user_id
, sum(scored_points)
from SCORE_LOG
group by
user_id
where date_time >= #StartOfPeriod
and date_time <= #EndOfPeriod
order by
sum(scored_points) desc
limit 5
If you get to production and find that you're having performance issues in practice, then you could consider denormalizing a snapshot of whatever statistics make sense. The problem with these snapshot statistics is that they can get out of sync with your source data, so you'll need a strategy for recalculating the snapshots periodically.
It's pretty much a truism (consider it a corollary of Murphy's Law) that if you have two sources of truth you'll eventually end up with two "truths".
Barranka was on the right track with his comment, you need to make sure you are not duplicating any of the data wherever possible.
However, if you are looking to be able to revert back to some old users score or possibly be able to pick out a day and see who was top at a certain point i.e. dynamic reporting, then you will need to record each record separately next to a date. Having a separate table for this would be useful as you could deduce the daily score from the existing user data via SQL and just enter it in to the table whenever you want.
The decision you have is how many users record do you want to maintain in the history and how long. I have written the below with the idea that the "hot list" would be the top 5 users, you could have a CRON job or scheduled task running each day/month to run the inserts and also clean out very old data.
Users
id
username
score
score_ranking
id
user_id (we normalise by using the id rather than all the user info)
score_at_the_time
date_of_ranking
So to generate a single data ranking you could insert into this table. Something like:
INSERT INTO
`score_ranking` (`user_id`, `score_at_the_time`, `date_of_ranking`)
SELECT
`id`, `score`, CURDATE()
FROM
`users`
ORDER BY
`score` DESC
LIMIT
5
To read the data for a specific date (or date range) you could then do:
SELECT * FROM score_ranking
WHERE date_of_ranking = 'somedate'
ORDER BY score_at_the_time DESC
I have a table with more than 1 million records. The problem is that the query takes too much times, like 5 minutes. The "ORDER BY" is my problem, but i need the expression in the query order by to get most popular videos. And because of the expression i can't create an index on it.
How can i resolve this problem?
Thx.
SELECT DISTINCT
`v`.`id`,`v`.`url`, `v`.`title`, `v`.`hits`, `v`.`created`, ROUND((r.likes*100)/(r.likes+r.dislikes),0) AS `vote`
FROM
`videos` AS `v`
INNER JOIN
`votes` AS `r` ON v.id = r.id_video
ORDER BY
(v.hits+((r.likes-r.dislikes)*(r.likes-r.dislikes))/2*v.hits)/DATEDIFF(NOW(),v.created) DESC
Does the most popular have to be calculated everytime? I doubt if the answer is yes. Some operations will take a long time to run no matter how efficient your query is.
Also bear in mind you have 1 million now, you might have 10 million in the next few months. So the query might work now but not in a month, the solution needs to be scalable.
I would make a job to run every couple of hours to calculate and store this information on a different table. This might not be the answer you are looking for but I just had to say it.
What I have done in the past is to create a voting system based on Integers.
Nothing will outperform integers.
The voting system table has 2 Columns:
ProductID
VoteCount (INT)
The votecount stores all the votes that are submitted.
Like = +1
Unlike = -1
Create an Index in the vote table based on ID.
You have to alternatives to improve this:
1) create a new column with the needed value pre-calculated
1) create a second table that holds the videos primary key and the result of the calculation.
This could be a calculated column (in the firts case) or modify your app or add triggers that allow you to keep it in sync (you'd need to manually load it the firs time, and later let your program keep it updated)
If you use the second option your key could be composed of the finalRating plus the primary key of the videos table. This way your searches would be hugely improved.
Have you try moving you arithmetic of the order by into your select, and then order by the virtual column such as:
SELECT (col1+col2) AS a
FROM TABLE
ORDER BY a
Arithmetic on sort is expensive.
I have a table lead and there is a field called added_on (datatype timestamp), I want to to fetch only the leads which are interested in a particular product and the reports should come monthly.
interested_in is a field in the lead table where the interested product's id will be stored as a comma separated values.
and $prod_id is stored with a product id which has to be checked.
the below query works fine just to fetch out the leads which are interested in a particular product. but i want the results to come month by month.
select*from lead where find_in_set('$prod_id',interested_in)
Please guide me what i have to do to achieve that
TRY
WHERE MONTH(added_on) = $giveMonthNumber
OR
WHERE MONTHNAME(added_on) = $givenMonthName;
Reference :
MySQL date time functions
Do this:
select * from lead where find_in_set('$prod_id',interested_in) group by added_on