for example i have a table like this :
name rating
matei 124
andrei 20
serj 25
john 190
mike 96
andy 245
tom 73
i need to output something like this(order by rating):
john's position is 2; or, tom's position is 5; (i don't need to get all result , just one )
How can I achieve this?
Thanks in advance
Generally order of rows in a query result is not guaranteed by MySQL unless ordering is explicitly specified with ORDER BY clause. If you have some separate ordering column, you may use query like the following:
SELECT count(1) as position
FROM table
WHERE order_column <= {john's order_column value};
If you don't have ordering column, I'd recommend you to define first, what does "john's position" and "tom's position" mean.
UPDATE:
AFAIU, you want to get position in list sorted by rating (sorry, I initially did not get it). So, rating would be your order_column. In this case, you should decide, how do you calculate position, if two guys have equal rating (who's position is higher?).
So, the query may look in the following way:
SELECT count(1) as position
FROM table
WHERE
rating > (SELECT rating FROM table WHERE id={user's ID});
SELECT COUNT(*) + 1
FROM users
WHERE (rating, name) <
(
SELECT rating, name
FROM users
WHERE name = 'john'
)
Note that if you will have duplicates on both name and rating, this query will assign the same rating to both of them.
Tables are more formally known as relations in database literature - they are not guaranteed to be ordered (they are sets of "tuples"), so your question doesn't make sense. If you need to rely on an order/position, you need to define an additional column (like an auto-incrementing ID column) to capture and store that info.
Is this any help > http://craftycodeblog.com/2010/09/13/rownum-simulation-with-mysql/ ?
Would offset not work like so?
SELECT * FROM Table ORDER BY rating DESC LIMIT 1,6
This would return 1 row that has been off setted by 6 rows ? or am I mistaken, the syntax would be
SELECT * FROM Table ORDER BY rating DESC LIMIT 1 , {{POS}}
Related
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
Im currently working on a project that requires MySql database and im having a hard time constructing the query that i want get.
i want to get the previous 10 rows from the specific WHERE condition on my mysql query.
for example
My where is date='December';
i want the last 10 months to as a result.
Feb,march,april,may,june,july,aug,sept,oct,nov like that.
Another example is.
if i have a 17 strings stored in my database. and in my where clause i specify that WHERE strings='eyt' limit 3
Test
one
twi
thre
for
payb
six
seven
eyt
nayn
ten
eleven
twelve
tertin
fortin
fiftin
sixtin
the result must be
payb
six
seven
Thanks in advance for your suggestions or answers
If you are using PDO this is the right syntax:
$objStmt = $objDatabase->prepare('SELECT * FROM calendar ORDER BY id DESC LIMIT 10');
You can change ASC to DESC in order to get either the first or the last 10.
Here's a solution:
select t.*
from mytable t
inner join (select id from mytable where strings = 'eyt' order by id limit 1) x
on t.id < x.id
order by t.id desc
limit 3
Demo: http://sqlfiddle.com/#!9/7ffc4/2
It outputs the rows in descending order, but you can either live with that, or else put that query in a subquery and reverse the order.
Re your comment:
x in the above query is called a "correlation name" so we can refer to columns of the subquery as if they were columns of a table. It's required when you use a subquery as a table.
I chose the letter x arbitrarily. You can use anything you like as a correlation name, following the same rules you would use for any identifier.
You can also optionally define a correlation name for any simple table in the query (like mytable t above), so you can refer to columns of that table using a convenient abbreviated name. For example in t.id < x.id
Some people use the term "table alias" but the technical term is "correlation name".
In my mysql table one of the field has values like (1|2|3) stored in it.
id Skills
---- --------
1 1|2|3|5
2 2|4|5
3 4|6|3
4 5|2|3|1
I want to search and list the id's based on the skills matched. If i want to list the id's of the skill which contains 3, i have to list the ids 1,3,4. Like if i want to list the id's of the skill which contains 1,5 (either 1 nor 5 or both)(like mulitple values 1,4,3) then i want to list 1,2,4(i want to list 2 also). Any help could be greatly appreciated.
Thanks in advance.
Use FIND_IN_SET
select id
from your_table
where find_in_set('3', replace(skills, '|',',') > 0
select id
from your_table
where find_in_set('3', replace(skills, '|',',')) > 0
or find_in_set('5', replace(skills, '|',',')) > 0
But you should actually change your DB structure. Always store single values in a column to avoid such problems!
This may help:
SELECT * FROM YOUR_TABLE
WHERE Skills REGEXP '[[:<:]]1[[:>:]]' = 1
OR Skills REGEXP '[[:<:]]5[[:>:]]' = 1
hi I'm looking for a way to only show a matching set of mysql results only once. can anyone tell me how to do this?
here's an example of what i'm trying to achieve:
id | profile_id | viewed_profile_id | date_viewed
1 4 7 00:00:00
2 5 6 00:00:00
1 4 7 00:00:00
so if profile_id and viewed_profile_id match then to only show one result for those matching columns rather than twice or three times or however many times it appears in the database?
Use the DISTINCT keyword:
SELECT DISTINCT id, profile_id, viewed_profile_id, date_viewed
FROM myTable
This will show only one row for each unique combination of the columns selected.
Or, reading into your question a lot (since you only want to match profile_id and viewed_profile_id), if you want to show the latest date viewed for each viewer, you can use GROUP BY and select the MAX date viewed. I am also assuming there is data in date_viewed and it is sortable:
SELECT profile_id, viewed_profile_id, MAX(date_viewed)
FROM myTable
GROUP BY profile_id, viewed_profile_id
DISTINCT helps to eliminate duplicates. If a query returns a result that contains duplicate rows, you can remove duplicates to produce a result set in which every row is unique. To do this, include the keyword DISTINCT after SELECT and before the output column list
http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
SELECT DISTINCT(` profile_id`),`viewed_profile_id`,`id`,`date_viewed` FROM `tableName` GROUP BY `viewed_profile_id`
try this:
$query = "SELECT * FROM TABLENAME WHERE profile_id = '$PROFILEIDVALUE' AND viewed_profile_id = '$VIEWEDIDVALUE' LIMIT 0, 1"
Depending upon the ORDER you want use can use ORDER BY id DESC/ASC
I hope this would be useful
In a MySQL table, I would like to take 10 records with DISTINCT values.
I am using Zend Framework.
$select = $this->getAdapter()->select()
->from('table', 'column')->group('column')
->limit(10, 0);
This is the query generated by the above code.
SELECT table.column FROM
table GROUP BY column LIMIT 10
What happens here is that MySQL is taking 10 records first and then applying the group by. So finally, I am getting only 7 records.
How to apply DISTINCT first and then take 10 records from it?
Test that SQL against a table -- MySQL applies the limit last, so doesn't do what you're saying. eg test against
a0 a1
1 1
2 1
3 2
4 2
and do select A.a1 from A group by a1 limit 2. You should see 1, 2, not 1, 1.
[I wanted to say this as a 'comment' rather than an 'answer', but couldn't]
I'm not 100% sure what you are trying to do.
But if i am reading it correct you need 10 records with a certain criteria and then apply the group. not the other way around.
Can't you use WHERE in this case?
SELECT table.column FROM table WHERE "criteria" GROUP BY column LIMIT 10
Regards
Mike
This may help you (I didn't test it but so I'm not sure it's working)
SELECT DISTINCT column FROM table LIMIT 10
If it's not working, you may use a temporary table (like (SELECT column FROM table) TEMP), which will select the distinct elements, then a query which will select the first ten results into this table.
Hope this'll help :)
In ZF, You should use distinct() method into Your query chain :
$select = $this->getAdapter()->select()
->distinct()
->from('table', 'column')
->limit(10, 0);
SELECT DISTINCT column
FROM table
LIMIT 10
GROUP BY column
Not sure how to get it into classes though...