复杂的SQL查询

3
我正在尝试构建一个特定的SQL查询,但不知道如何实现我想要的内容。
我的数据库看起来是这样的:
Col1 Col2  
"a"   5  
"b"   7  
"a"   8  
"a"   7  
"b"   5  
"b"   7  
"c"   3  
"a"   4  
"b"   3  
"b"   4  
"c"   1 

我想要一个查询,返回类似以下的内容:
"a"   8  
"a"   7  
"b"   7  
"b"   7  

用文字来表述:前 x 个字符串中的两个最高值。
而仅仅在排序后加上限制是行不通的,因为 order by 是针对整个结果而不仅仅是结果的一个“组”。希望您能理解我的意思。

“the first x strings” 按什么顺序排序?按 col2 最高的顺序吗? - Blorgbeard
没错,但这并不重要。我不理解的是结果的切割。 - Simon Lenz
3个回答

1

它不太好看,但是...

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;

1
我必须同意Pierre Gardin的观点。除非你想浪费时间,否则不要费心编写SQL(尤其是这么丑陋的SQL)。不过我不得不佩服你,你成功地让我的时间被浪费了,而不是你自己的时间。 :) - Soren
1
啊,是的,你发现了笔误。显然我还没有完全掌握剪切和粘贴这门古老的艺术技巧。 :) - Soren
+1 为古老的艺术评论点赞。这将成为今天的 FB 状态,希望你不介意我复制粘贴。 - Miserable Variable

0
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

他正在使用SQLite,那里没有“TOP”。 - Pentium10

-1

如果可以的话,使用像Java中的Hibernate或Spring JDBC模板这样的高级库。其他语言也有其他可能性。除非你想浪费时间,否则不要在应用程序中编写SQL。

编辑1:当然,你可能没有选择。你可能正在与你没有编写的东西交互。但是,如果你创建自己的数据库,并将低级、臃肿、难以维护、特定于RDBMS的SQL查询集成到应用程序中,这可能表明你正在做错事情。我宁愿使用Hibernate,让应用程序运行得慢一点,也不愿花费开发时间来修复SQL代码。我认为,“复杂”总体上是要避免的,如果你想提供真实世界可维护的应用程序。


我不明白为什么有人会给这个评分。虽然它没有直接回答问题,但是指出了一个更好的解决方法。如果我是提问者,我会一直喜欢这样的回答。 - Matteo Mosca
2
@Matteo Mosca:我感同身受,因为这是一项不太关系型的任务(发布的数据甚至没有键!)。然而,“不要在应用程序中编写 SQL”有点笼统,你觉得呢? - onedaywhen
我认为,如果我可以在更高层次的抽象上工作(比如使用Entity Framework的Linq),它仍然可以产生优质的SQL,那么为什么我还要费心编写应用程序的SQL呢?当然,如果您需要为其他需求编写SQL,例如直接存储在数据库中的视图、存储过程等,则情况就不同了。但是现在对于.NET应用程序来说,如果您可以使用Linq和ORM,那么SQL确实已经过时了。这只是我的个人观点。 - Matteo Mosca
我不明白为什么需要执行这类查询。如果像我想的那样,“a”和“b”指的是某种“类型”,那么数据库中会有很多冗余数据,因此设计得很差。更简单的方法是将类型存储在单独的表中,并在第一个表中引用它们。然后可以从第二个表获取所有类型,并发出一个查询/表来获取每种类型得分最高的前n个。 - Pierre Gardin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接