【问题标题】:Advanced grouping without using a sub query不使用子查询的高级分组
【发布时间】:2010-11-01 09:12:43
【问题描述】:

这是我拥有的数据样本。

-ID-        -Rank-      -Type-      -Status-    -Amount-
1142474     2       Under Offer Approved    23
1148492     1       Present     Current     56
1148492     2       Under Offer Approved    3
2273605     1       Present     Current     24

如果 ID 相同,我只想要排名最高的记录。所以查询的最终结果。

-ID-        -Rank-      -Type-      -Status-    -Amount-
1142474     2       Under Offer Approved    23
1148492     1       Present     Current     56
2273605     1       Present     Current     24

现在获取原始数据集是一项昂贵的操作,所以不想想要做一个按ID分组和然后 mins 排名然后重新加入 到数据集。因此,查询需要以另一种方式工作。

干杯 安东尼

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    这将起作用:

    with temp as (
    select *, row_number() over (partition by id order by rank) as rownum
    from table_name
    )
    select * from temp where rownum = 1
    

    将为每个 id 提供一条记录,其中 rank 代表最少的数字

    【讨论】:

      【解决方案2】:
      SELECT * FROM TheTable
      WHERE 1 = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Rank DESC)
      

      【讨论】:

      • 这是我的第一直觉。也许OP会发布一些计时结果。
      • 仅作记录,在我的情况下,这种情况是一个错误 - “窗口函数只能出现在 SELECT 或 ORDER BY 子句中。”所以我不得不将 over 部分放在子查询中,将 where 部分放在外部查询中。
      【解决方案3】:
      select t1.id
             , t1.rank
             , t1.type
             , t1.status
             , t1.amount
      
      from   my_table t1 
      
             left outer join my_table as t2 
             on t1.id = t2.id 
          and 
             t2.rank < t1.rank 
      
      where  t2.id is null
      

      【讨论】:

      • @Anthony:与 t2 的连接也称为自连接。它是同一张表的另一个副本。它起作用的原因是我们在谓词(连接条件和 WHERE 子句)中指定我们要排除除每个 id 的排名靠前的项目之外的所有内容。
      • @adam:问题是从 my_table 中取出数据非常昂贵(即 2 到 6 秒之间),因此我想避免再次加入表中......
      • 我所做的(即使我真的不想这样做),我已将结果放入临时表中,然后将临时表连接到自身...
      • 嗯,这可能是要走的路。看看其他 SO 用户对将复杂查询分解为步骤的看法:stackoverflow.com/questions/754527/best-way-to-test-sql-queries/…
      • 您尝试过 Alex 的解决方案了吗? stackoverflow.com/questions/968305/…
      【解决方案4】:

      一般可用的选项包括:

      • 将图示数据存储在临时表中,然后查询临时表。
      • 使用 WITH 子句定义复杂查询,然后让 DBMS 对查询进行排序。

      WITH 子句有效地允许您为子查询命名;优化器将尽可能避免重新评估它。 TEMP 表解决方案可能是最简单的。这将对 ID 和 MIN(rank) 进行 GROUP BY 并加入。

      【讨论】:

        【解决方案5】:

        为什么获取数据集如此昂贵,我在这里没有看到非常复杂的东西。你有你需要的索引,查询是否使用它们?统计数据是否过时?

        【讨论】:

        • 出于问题的目的,我已经简化了场景。基本上,该表是一个 Table_valued 函数,它联合了来自其他 2 个 Table_valued 函数的结果,每个函数使用大约 6 个临时表来构建结果。这是由于数据库中存在的规范化级别以及需要导出多少数据来构建数据图。实际上,这些数据应该在物化视图或类似的东西中捕获。但是我不能在这个发布周期中做任何这样的改变。欢呼
        猜你喜欢
        • 2012-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-06
        • 1970-01-01
        • 2019-11-04
        相关资源
        最近更新 更多