I have a simple table:
ID | Name
0183 namez
2543 etc
2654 etc
4364 namez
3246 namey
3745 namew
3464 namem
7524 etc
2459
2457
0845
9325
I need to be able to select the 6th thru 10th rows or the 4th thru 25th or whatever, so that I can select only the rows that I need without using any kind of Id column, also it's alway Xth "thru" Yth, because I'm not hardcoding an column names here, I can't use order by but have to use natural order. Is this even possible? Thanks for any help.
you need to pass a LIMIT clause to your SELECT query. In MySQL this would be:
SELECT * FROM simpletable LIMIT 5, 5;
NOTE:
the first number is the offset, it needs to be the first row minus one, (i.e. 6 - 1).
the second is the number of rows returned, this needs to be last row - offset (i.e. 10 - 5).
SEE: http://dev.mysql.com/doc/refman/5.0/en/select.html
SELECT *
FROM tables
ORDER BY ID
LIMIT 5, 5
You can do the following:
SELECT * FROM tables ORDER BY ID LIMIT 4, 10
Related
I am trying to query a dataset from a single table, which contains quiz answers/entries from multiple users. I want to pull out the highest scoring entry from each individual user.
My data looks like the following:
ID TP_ID quiz_id name num_questions correct incorrect percent created_at
1 10154312970149546 1 Joe 3 2 1 67 2015-09-20 22:47:10
2 10154312970149546 1 Joe 3 3 0 100 2015-09-21 20:15:20
3 125564674465289 1 Test User 3 1 2 33 2015-09-23 08:07:18
4 10153627558393996 1 Bob 3 3 0 100 2015-09-23 11:27:02
My query looks like the following:
SELECT * FROM `entries`
WHERE `TP_ID` IN('10153627558393996', '10154312970149546')
GROUP BY `TP_ID`
ORDER BY `correct` DESC
In my mind, what that should do is get the two users from the IN clause, order them by the number of correct answers and then group them together, so I should be left with the 2 highest scores from those two users.
In reality it's giving me two results, but the one from Joe gives me the lower of the two values (2), with Bob first with a score of 3. Swapping to ASC ordering keeps the scores the same but places Joe first.
So, how could I achieve what I need?
You're after the groupwise maximum, which can be obtained by joining the grouped results back to the table:
SELECT * FROM entries NATURAL JOIN (
SELECT TP_ID, MAX(correct) correct
FROM entries
WHERE TP_ID IN ('10153627558393996', '10154312970149546')
GROUP BY TP_ID
) t
Of course, if a user has multiple records with the maximal score, it will return all of them; should you only want some subset, you'll need to express the logic for determining which.
MySql is quite lax when it comes to group-by-clauses - but as a rule of thumb you should try to follow the rule that other DBMSs enforce:
In a group-by-query each column should either be part of the group-by-clause or contain a column-function.
For your query I would suggest:
SELECT `TP_ID`,`name`,max(`correct`) FROM `entries`
WHERE `TP_ID` IN('10153627558393996', '10154312970149546')
GROUP BY `TP_ID`,`name`
Since your table seems quite denormalized the group by name-par could be omitted, but it might be necessary in other cases.
ORDER BY is only used to specify in which order the results are returned but does nothing about what results are returned - so you need to apply the max()-function to get the highest number of right answers.
I'm trying to find an elegant way to write a query that only returns enough rows for a certain column to add up to at least n.
For example, let's say n is 50, and the table rows look like this:
id count
1 12
2 13
3 5
4 18
5 14
6 21
7 13
Then the query should return:
id count
1 12
2 13
3 5
4 18
5 14
Because the counts column adds up to n > 50. (62, to be exact)
It must return the results consecutively starting with the smallest id.
I've looked a bit into accumulators, like in this one: MySQL select "accumulated" column
But AFAIK, there is no way to have the LIMIT clause in an SQL query limit on an SUM instead of a row count.
I wish I could say something like this, but alas, this is not valid SQL:
SELECT *
FROM elements
LIMIT sum(count) > 50
Also, please keep in my the goal here is to insert the result of this query into another table atomically in an automated, performance efficient fashion, so please no suggestions to use a spreadsheet or anything that's not SQL compatible.
Thanks
There are many ways to do this. One is by using Correlated Subquery
SELECT id,
count
FROM (SELECT *,
(SELECT Isnull(Sum(count), 0)
FROM yourtable b
WHERE b.id < a.id) AS Run_tot
FROM yourtable a) ou
WHERE Run_tot < 50
Here is a table:
5000
4900
4800
4700
3800
3600
2000
1900
1600
1000
The table does not have identification numbers.
The table is sorted by the decay, the greatest value from above.Question. How to make a mysql query to find a value of 5 on the list item? The column ID, no ...
Sorry for my bad english.
Thanks!
I am going to interpret this as finding the fifth value in the list. You can do this using limit:
select t.*
from t
order by col desc
limit 4, 1;
Do you mean you want to find a row which had value 5?
SELECT *
FROM TABLE_NAME
WHERE ID = 5
or if you mean you want the fifth element in the list,
SELECT *
FROM TABLE_NAME
LIMIT 5,1
Is it possible to sort in MySQL by "order by" using a predefined set of column values (ID) like order by (ID=1,5,4,3) so I would get records 1, 5, 4, 3 in that order out?
UPDATE: Why I need this...
I want my records to change sort randomly every 5 minutes. I have a cron task to update the table to put different, random sort order in it.
There is just one problem! PAGINATION.
I will have visitors who come to my page, and I will give them the first 20 results. They will wait 6 minutes, go to page 2 and have the wrong results as the sort order has already changed.
So I thought that if I put all the IDs into a session on page 2, we get the correct records even if the sorting had already changed.
Is there any other better way to do this?
You can use ORDER BY and FIELD function.
See http://lists.mysql.com/mysql/209784
SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)
It uses Field() function, Which "Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found" according to the documentation. So actually you sort the result set by the return value of this function which is the index of the field value in the given set.
You should be able to use CASE for this:
ORDER BY CASE id
WHEN 1 THEN 1
WHEN 5 THEN 2
WHEN 4 THEN 3
WHEN 3 THEN 4
ELSE 5
END
On the official documentation for mysql about ORDER BY, someone has posted that you can use FIELD for this matter, like this:
SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)
This is untested code that in theory should work.
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC
If I had 10 registries for example, this way the ID 1, 5, 4 and 3 will appears first, the others registries will appears next.
Normal exibition
1
2
3
4
5
6
7
8
9
10
With this way
8
5
4
3
1
2
6
7
9
10
There's another way to solve this. Add a separate table, something like this:
CREATE TABLE `new_order` (
`my_order` BIGINT(20) UNSIGNED NOT NULL,
`my_number` BIGINT(20) NOT NULL,
PRIMARY KEY (`my_order`),
UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;
This table will now be used to define your own order mechanism.
Add your values in there:
my_order | my_number
---------+----------
1 | 1
2 | 5
3 | 4
4 | 3
...and then modify your SQL statement while joining this new table.
SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order;
This solution is slightly more complex than other solutions, but using this you don't have to change your SELECT-statement whenever your order criteriums change - just change the data in the order table.
If you need to order a single id first in the result, use the id.
select id,name
from products
order by case when id=5 then -1 else id end
If you need to start with a sequence of multiple ids, specify a collection, similar to what you would use with an IN statement.
select id,name
from products
order by case when id in (30,20,10) then -1 else id end,id
If you want to order a single id last in the result, use the order by the case. (Eg: you want "other" option in last and all city list show in alphabetical order.)
select id,city
from city
order by case
when id = 2 then city else -1
end, city ASC
If i had 5 city for example, i want to show the city in alphabetical order with "other" option display last in the dropdown then we can use this query.
see example other are showing in my table at second id(id:2) so i am using "when id = 2" in above query.
record in DB table:
Bangalore - id:1
Other - id:2
Mumbai - id:3
Pune - id:4
Ambala - id:5
my output:
Ambala
Bangalore
Mumbai
Pune
Other
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
I have a sql statement that brings back ids. Currently I am ordering the id's with the usual "ORDER BY id". What I need to be able to do is have the query order the first 3 rows by specific id's that I set. The order the remaining as it is currently. For example, I want to say the first 3 rows will be id's 7,10,3 in that order, then the rest of the rows will be ordered by the id as usual.
right now i just have a basic sql statement...
SELECT * from cards ORDER BY card_id
SELECT *
FROM cards
ORDER BY
CASE card_id WHEN 7 THEN 1 WHEN 10 THEN 2 WHEN 3 THEN 3 ELSE 4 END,
card_id
A bit shorter than Quassnoi's query, with FIELD :
-- ...
ORDER BY FIELD(card_id, 3, 10, 7) DESC
You have to invert the order because of the DESC, I didn't find a way to do it more naturally.