I'm not expert in MYSQL,
I have a list of videos, (ID,ANIME_ID,TIME)
I want to select top 25 rows ordered by TIME without repeating same ANIME_ID
I mean only top TIMEs of each ANIME_ID and ordered by TIME not by ANIME_ID
Since you're using mysql, you can just use group by for this -- however, realize this will just return an arbitrary id if ties exist:
select id, anime_id, max(time) time
from videos
group by anime_id
order by max(time) desc
limit 25
Condensed Fiddle Demo
If you need a specific id for ties, you can establish a row number using user-defined variables and filter accordingly.
You should use:
Select distinct(anime_id) order by time limit 25
Related
let's say I have a table CData with the columns CName, Amount1, Amount2.
Now I want to use a query to get calculate the difference between Amount1 and Amount2 for each distinct CName and, as a result of the query, get the ~1000 rows with the biggest difference and the 1000~ rows with the smallest (or most negative) difference. It doesn't matter if the results come in one table or two.
1) I am aware of the function TOP and so I could do this with two queries and sort by Difference (once ascending, once descending). Is there a way to do this in one query, though? This would save some time.
2) General question: When I define a field in my query (in this example "Difference"), can I somehow use it to, for example, sort the data by it? Like this (well, it's not working, but to give you an idea of what I mean):
SELECT CData.CName, CData.Amount2-CData.Amount1 AS Difference
FROM CData
GROUP BY CData.CName
ORDER BY Difference
Or do I always have to do the following:
...
ORDER BY CData.Amount2-CData.Amount1
Not much of a difference in this example, I just wanted to know if that's possible in general.
Sort the first time ASC (Ascending) and the second time DESC (Descending)
SELECT TOP 1000
CData.CName,
CData.Amount2 - CData.Amount1 AS Difference
FROM CData
GROUP BY CData.CName
ORDER BY CData.Amount2 - CData.Amount1 ASC
SELECT TOP 1000
CData.CName,
CData.Amount2 - CData.Amount1 AS Difference
FROM CData
GROUP BY CData.CName
ORDER BY CData.Amount2 - CData.Amount1 DESC
which aggregate functino do you want to perform for your differences? Avg? Sum?
SELECT CName, avg(Amount2-Amount1) AS Difference
FROM CData
GROUP BY CName
btw, to do it in 'one' query, you could use a union query on two subqueries, one with the TOP 1000 asc, one with the TOP 1000 desc
looks like Access is not allowing you to use an alias in the ORDER BY Clause, if you use the QBE grid you can change the format from the UI to SQL and it repeats the calculation in the ORDER BYclause.
Hi, John.
Check out the SO tour for instructions on how to use options such as formatting code.
Not sure if this will work for you, but you can try something like:
select * from
(SELECT TOP 3
CName, Date_Sale, Sum(Amount) AS SumA, 99999-Sum(Amount) as srt
FROM
Data
GROUP BY
CName, Date_Sale
UNION
SELECT TOP 3
CName, Date_Sale, Sum(Amount) AS SumA, Sum(Amount) as srt
FROM
Data
GROUP BY
CName, Date_Sale) u
order by
srt
I'm creating a list for best movies which are based on the users votes like imdb. I have done the list with this sql query:
SELECT data_id, COUNT(point), SUM(point)
FROM voting_table
WHERE data_type='1'
GROUP BY data_id
order by SUM(point)/COUNT(point)
DESC limit 100
This works well but i want also the number of votes(point) affect the order. I mean if a movie gets average of 8 with 10 votes and another movie gets average of 8 but with 5 votes. The one which has more votes should be listed higher than the other one. How can i do it? And is the query i wrote is efficent for server performance?
There is function AGV, I suggest you use that.
sort by avg, then by count or sum
...
ORDER BY AVG(point) DESC, COUNT(point) DESC
...
As of performance, there is not much you can do wihout complicating data structure.
It should be fine as it is unless your site si going to be as popular as imdb.
If your voting table grows past the point where speedup is needed then you need to start precalculating stuff (for real time updates using triggers that update score in movies table or some other intermediate table dedicated for that, other methods)
Just add the second order you want separated by comma .try this
SELECT data_id, COUNT(point), SUM(point)
FROM voting_table
WHERE data_type='1'
GROUP BY data_id
order by SUM(point)/COUNT(point) ,COUNT(point)
DESC limit 100
Try changing your order by clause to be:
order by SUM(point)/COUNT(point) desc, COUNT(point) desc
As it stands, your query appears to be efficient.
I have a query that looks like this:
SELECT article FROM table1 ORDER BY publish_date LIMIT 20
How does ORDER BY work? Will it order all records, then get the first 20, or will it get 20 records and order them by the publish_date field?
If it's the last one, you're not guaranteed to really get the most recent 20 articles.
It will order first, then get the first 20. A database will also process anything in the WHERE clause before ORDER BY.
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
With one argument, the value specifies the number of rows to return from the beginning of the result set:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.
All details on: http://dev.mysql.com/doc/refman/5.0/en/select.html
Just as #James says, it will order all records, then get the first 20 rows.
As it is so, you are guaranteed to get the 20 first published articles, the newer ones will not be shown.
In your situation, I recommend that you add desc to order by publish_date, if you want the newest articles, then the newest article will be first.
If you need to keep the result in ascending order, and still only want the 10 newest articles you can ask mysql to sort your result two times.
This query below will sort the result descending and limit the result to 10 (that is the query inside the parenthesis). It will still be sorted in descending order, and we are not satisfied with that, so we ask mysql to sort it one more time. Now we have the newest result on the last row.
select t.article
from
(select article, publish_date
from table1
order by publish_date desc limit 10) t
order by t.publish_date asc;
If you need all columns, it is done this way:
select t.*
from
(select *
from table1
order by publish_date desc limit 10) t
order by t.publish_date asc;
I use this technique when I manually write queries to examine the database for various things. I have not used it in a production environment, but now when I bench marked it, the extra sorting does not impact the performance.
You could add [asc] or [desc] at the end of the order by to get the earliest or latest records
For example, this will give you the latest records first
ORDER BY stamp DESC
Append the LIMIT clause after ORDER BY
If there is a suitable index, in this case on the publish_date field, then MySQL need not scan the whole index to get the 20 records requested - the 20 records will be found at the start of the index. But if there is no suitable index, then a full scan of the table will be needed.
There is a MySQL Performance Blog article from 2009 on this.
You can use this code
SELECT article FROM table1 ORDER BY publish_date LIMIT 0,10
where 0 is a start limit of record & 10 number of record
LIMIT is usually applied as the last operation, so the result will first be sorted and then limited to 20. In fact, sorting will stop as soon as first 20 sorted results are found.
Could be simplified to this:
SELECT article FROM table1 ORDER BY publish_date DESC FETCH FIRST 20 ROWS ONLY;
You could also add many argument in the ORDER BY that is just comma separated like: ORDER BY publish_date, tab2, tab3 DESC etc...
the table videos has the folowing feels
id,average,name
how can i write the query, to select the name of video, which have the max average!!!
i can do that vith two queries, by selecting the max(avege) from the table, and then find out the name, where ihe average equal to max!!! but i want to do that in one query!!!
help me please!!!
You don't need a group by for this, you just want to select the highest average!
SELECT * FROM videos ORDER BY average DESC LIMIT 1;
You can use an ORDER BY with a LIMIT:
SELECT id, average, name FROM videos ORDER BY average DESC LIMIT 1
ORDER BY average DESC orders the rows in order of descending average (i.e. the first row will have an average equal to MAX(average)). LIMIT 1 causes only the first row to be returned.
SELECT id,name,MAX(average) FROM videos;
All fields you choose to SELECT will be returned. Getting more data back is just a case of SELECTing more fields.
What's the most efficient way to select the last n number of rows in a table using mySQL? The table contains millions of rows, and at any given time I don't know how large the table is (it is constantly growing). The table does have a column that is automatically incremented and used as a unique identifier for each row.
SELECT * FROM table_name ORDER BY auto_incremented_id DESC LIMIT n
Actually the right way to get last n rows in order is to use a subquery:
(SELECT id, title, description FROM my_table ORDER BY id DESC LIMIT 5)
ORDER BY tbl.id ASC
As this way is the only I know that will return them in right order. The accepted answer is actually a solution for "Select first 5 rows from a set ordered by descending ID", but that is most probably what you need.
(Similar to "marco"s answer,)
my fav is the max()-function of MySQL too, in a simple one-liner, but there are other ways of sure:
SELECT whatever FROM mytable WHERE id > (SELECT max(id)-10 FROM mytable);
... and you get "last id minus 10", normally the last 10 entries of that table.
It's a short way, to avoid the a error 1111 ("Invalid use of group function") not only if there is a auto_increment-row (here id).
The max()-function can be used many ways.
Maybe order it by the unique id descending:
SELECT * FROM table ORDER BY id DESC LIMIT n
The only problem with this is that you might want to select in a different order, and this problem has made me have to select the last rows by counting the number of rows and then selecting them using LIMIT, but obviously that's probably not a good solution in your case.
Use ORDER BY to sort by the identifier column in DESC order, and use LIMIT to specify how many results you want.
You would probably also want to add a descending index (or whatever they're called in mysql) as well to make the select fast if it's something you're going to do often.
This is a lot faster when you have big tables because you don't have to order an entire table.
You just use id as a unique row identifier.
This is also more eficient when you have big amounts of data in some colum(s) as images for example (blobs). The order by in this case can be very time and data consuming.
select *
from TableName
where id > ((select max(id) from TableName)-(NumberOfRowsYouWant+1))
order by id desc|asc
The only problem is if you delete rows in the interval you want. In this case you would't get the real "NumberOfRowsYouWant".
You can also easily use this to select n rows for each page just by multiplying (NumberOfRowsYouWant+1) by page number when you need to show the table backwards in multiple web pages.
Here you can change table name and column name according your requirement . if you want to show last 10 row then put n=10,or n=20 ,or n=30 ...etc according your requirement.
select * from
(select * from employee
Order by emp_id desc limit n)
a Order by emp_id asc;