tags:

views:

61

answers:

4

if i had a query such as

select * from tbl_foo where name = 'sarmen'

and this table has multiple instances of name = sarmen how can i virtually assign row numbers to each row without having to create a column that auto incriments? i have a reason for what im doing and dont need an auto_incrimented col in my example.

so if each row is assign a virtual row number through sql or maybe php i will be able to print out the first row or the last row anytime i need to.

thnx

+2  A: 

To return only one row use LIMIT 1:

SELECT *
FROM tbl_foo
WHERE name = 'sarmen'
LIMIT 1

In doesn't makes sense to say 'first row' or 'last row' unless you have an ORDER BY clause. Assuming you add an ORDER BY clause then you can use LIMIT in the following ways:

  • To get the first row use LIMIT 1.
  • To get the 2nd row you can use limit with an offset: LIMIT 1, 1.
  • To get the last row invert the order (change ASC to DESC or vice versa) then use LIMIT 1.
Mark Byers
Actually, it does make sense to refer to 'last row' and 'first row.' You just have to understand a few things about databases. Like the fact that you should use ORDER BY if you need the result set to be sorted in a certain fashion.
George Marian
@George Marian: Yes, that's why I wrote "unless you have an ORDER BY clause".
Mark Byers
I meant that as an expansion of your answer and only provided one example: the same one you provided. That said, the result set is represented as rows, no matter what the order. We need to understand the differences between a result set and a table. I may very well not care what order they're in, but still want to refer to the first or last row of that result set. My apologies for being pedantic, but that's typically necessary in our industry.
George Marian
thanks but i was looking to set each row as a variable. i do know about the limit clause and wasnt looking for that.
eminem
@eminem: OK, it's your choice. You should be aware that for selecting only the first or last row (as you said in the question) using and ORDER BY and LIMIT 1 can be *much* faster than numbering all the rows and then filtering. The latter will typically result in a table scan.
Mark Byers
whats a table scan
eminem
@eminem: It's the least efficient means of finding data. However, the query you provided could use an index (if one existed) on the `name` column to make queries using the `name` column more efficient.
OMG Ponies
the reason why i wanted to do it the way i specified was because i didnt want to write the query twice to show information that i needed. using join was messing up the data output i wanted. maybe i have another solution? i dont know. can i contact u outside of this place? or would you like me to edit this question and rewrite what im performing so that you can better understand what im trying to do
eminem
@eminem: OMG Ponies is right: because of the WHERE in your query the result set will probably only be small anyway, so I guess performance is not an issue here. If you want to make a substantial change to your question which will result in a completely different answer I'd say that it is usually better to create a new question instead of editing the current one. Editing the question would mean that the existing answers won't make sense.
Mark Byers
A: 

use the pseudocolumn ROWNUM

Randy
That'd work for Oracle, not MySQL
OMG Ponies
yep - i'm definitely an Oracle guy - sorry
Randy
+3  A: 

You didn't specify how the order is determined, but this will give you a rank value in MySQL:

SELECT t.*,
       @rownum := @rownum +1 AS rank
  FROM TBL_FOO t
  JOIN (SELECT @rownum := 0) r
 WHERE t.name = 'sarmen'

Then you can pick out what rows you want, based on the rank value.

OMG Ponies
thanks, what is this type of query called i would like to learn more about it
eminem
i tried this but the virtual rank column came out null. maybe i can do a query and add each row to an array and get the 0th item? (using php)
eminem
@eminem: Updated query, try now. As for learning this - this is a hack until MySQL supports analytic/rank/windowing functions.
OMG Ponies
A: 

You can get the total number of rows containing a specific name using:

SELECT COUNT(*) FROM tbl_foo WHERE name = 'sarmen'

Given the count, you can now get the nth row using:

SELECT * FROM tbl_foo WHERE name = 'sarmen' LIMIT (n - 1), 1

Where 1 <= n <= COUNT(*) from the first query.

Example:

getting the 3rd row

SELECT * FROM tbl_foo WHERE name = 'sarmen' LIMIT 2, 1
Anax