【问题标题】:Getting the first of a GROUP BY clause in SQL在 SQL 中获取第一个 GROUP BY 子句
【发布时间】:2010-04-02 05:12:02
【问题描述】:

我正在尝试为 Rails 应用程序实现单列区域化,但由于需要复杂的 SQL,我遇到了一些令人头疼的问题。对于这个系统,一个地区可以用一个国家代码(例如us)表示一个大写的大陆代码(例如NA),或者它可以是NULL,表示“默认”信息。我需要按一些相关信息(例如外键)对这些项目进行分组(我们称之为external_id)。

给定一个国家及其大陆,我需要能够仅选择最具体的可用区域。因此,如果存在带有国家代码的记录,我会选择它们。如果,不是我想要带有大陆代码的记录。如果不是这样,我想要带有NULL 代码的记录,以便我可以接收默认值。

到目前为止,我认为我可以使用生成的CASE 语句来获得任意排序顺序。像这样的:

SELECT *, CASE region 
            WHEN 'us' THEN 1 
            WHEN 'NA' THEN 2 
            ELSE 3 
          END AS region_sort 
          FROM my_table 
          WHERE region IN ('us','NA') OR region IS NULL 
          GROUP BY external_id 
          ORDER BY region_sort

问题在于,如果没有聚合函数,GROUP BY 为给定行返回的实际数据似乎是无法控制的。如何处理此查询以使其仅返回region_sort 有序组的第一条记录

【问题讨论】:

  • 您想要按地区聚合还是每个地区的第一行或其他什么?
  • 我希望每个 external_id 有一个结果(这可能是多个结果的总数),这是该 external_id 可用区域中最具体的。因此,如果有两个 external_id=3 的模型,如果同时存在“us”和 NULL,我只想要一个“us”。

标签: sql ruby-on-rails


【解决方案1】:

仅第一条记录还是仅第一记录?从您写的内容中甚至不清楚是否有多个记录。

在任何情况下,您似乎都在向后弯腰在一个查询中执行此操作,但数据库结构并未为此优化。如果只有 3 个级别,而您想要最具体的,为什么不这样做:

SELECT * FROM my_table WHERE region = 'us' GROUP BY external_id

如果返回某些内容,则停止,否则您有条件地再运行 1 或 2 个查询。

我可能是错的,但我的直觉认为这会产生更好的整体性能,尽管我认为这取决于你的数据库的细节。

【讨论】:

  • 抱歉,解释起来有点混乱,因为它一开始就很复杂。问题是我希望所有三个特异性级别都可能有有效的结果,即一些具有“us”区域,一些具有“NA”和一些具有 NULL。我想在一个查询中完成,否则我必须手动组合它们,这绝对不理想。
猜你喜欢
  • 1970-01-01
  • 2022-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 2018-09-07
相关资源
最近更新 更多