tags:

views:

130

answers:

3

I'm trying to build a specific sql query but i have no idea how to implement what i want.
My database looks like this:

Col1 Col2  
"a"   5  
"b"   7  
"a"   8  
"a"   7  
"b"   5  
"b"   7  
"c"   3  
"a"   4  
"b"   3  
"b"   4  
"c"   1 

And I want a query that returns something like this:

"a"   8  
"a"   7  
"b"   7  
"b"   7  

In words: the 2 highest values of the first x strings.

And only putting a limit after sorting doesn't work, because the order by refers to the whole result and not only to one "group" of the result. I hope you understand what i'm up to.

A: 
select tbl.col1, tbl.col2 from tbl inner join
(select col2 from tbl order by col2 desc Limit 2) as t1 on
t1.col2 = tbl.col2 order by tbl.col1,tbl.col2
Samiksha
he is on SQLite, there is no `TOP` there
Pentium10
Pentium10, thanks.. Modified the query
Samiksha
@Samiksha: This won't work unfortunately. Check out @soren's solution.
Daniel Vassallo
A: 

If you can, use a higher-level library like Hibernate for Java, or Spring JDBC template. There are other possibilities in other languages. Don't bother writing SQL in your application, unless you want to lose time.

Edit 1: of course, you may have no choice. You may be interacting with something you didn't write. But if you're creating your own db, when you integrate low-level, bloated, unmaintainable, RDBMS-specific SQL queries in your app, it may be a sign that you are doing something wrong. I'd rather use Hibernate and have the app run a bit slower than spending my development time fixing SQL code. I think "complicated" is something to be avoided in general, if you want to deliver real-world, maintainable applications.

Pierre Gardin
I don't understand why someone downrated this. It doesn't answer to the question but points the user to a better approach to solve his problem. If I were the asker, I'd prefer an answer like this all the times.
Matteo Mosca
@Matteo Mosca: I sympathize because this is one of those tasks that isn't particularly relational (the data posted doesn't even have a key!) However, "Don't bother writing SQL in your application" is a bit of a generalization, don't you think?
onedaywhen
Well, I think that if I can work on a higher level abstraction (let's say Linq with Entity Framework) that still produces quality SQL underneath, why should I ever bother writing sql for my app?Different story if you need to write sql for other needs, such views to be stored directly on the db, stored procedures, etc. but nowaday for a .Net application, if you can use Linq and and ORM, Sql is really deprecated. That's just my opinion anyway.
Matteo Mosca
I cannot see why one would need to do these kind of queries. If, as I think, the "a" and "b" 's refer to some kind of "type", then there is a lot of redundancy in the database and it is poorly designed. It would be simpler to have the types in a separate table and a reference to them in the first table. Then one would get all the types from the second table and issue one query/table to get the first n with the highest score for each type.
Pierre Gardin
+1  A: 

It ain't pretty, but..

SELECT * FROM 
  (SELECT DISTINCT col1, 
          (SELECT col2 FROM tbl WHERE tbl.col1 = a.col1 ORDER BY col2 DESC LIMIT 1) FROM tbl a

  UNION ALL
   SELECT DISTINCT col1,
          (SELECT col2 FROM tbl WHERE tbl.col1 = a.col1 ORDER BY col2 DESC LIMIT 1 offset 1) FROM tbl a)
ORDER BY 1,2 DESC;
Soren
I have to agree with Pierre Gardin, though. Don't bother writing SQL (especially SQL this ugly) unless you want to lose/waste time. I have to admire, though, that you managed to make it so that it was my time rather than your own that was wasted. :)
Soren
Ah, yeah, good catch on the typo. I've not yet completely mastered the ancient art of cut and paste, apparently. :)
Soren
@Soren +1 for the ancient art comment. It will be FB status of the day, hope you don't mind my copy n paste
Hemal Pandya