Top Dense_Rank基于其他字段的行

时间:2016-01-07 23:08:18

标签: sql sql-server

我在sql中绑定了几个表,我试图仅显示使用DENSE RANK制定的列中的MAX编号,但是在拉取TOP行时我需要记住其他两个字段。

以下是我的结果示例:
| sa_id |价格|门槛| role_id | RK
1 | 37E41 | 40.00 | NULL | A38D67A | 1
2 | 37E41 | 40.00 | NULL | 46B9D4E | 1
3 | 1CFC1 | 40.00 | NULL | 58C1E03 | 1
4 | BF0D3 | 40.00 | NULL | 28D465B | 1
5 | F914B | 40.00 | NULL | 2920EBD | 1
6 | F3CA1 | 40.00 | NULL | D5E7584 | 1
7 | 0D8C1 | 40.00 | NULL | EECDB5A | 1
8 | A6503 | 40.00 | NULL | B680CB4 | 1
9 | 9BB96 | 40.00 | 0.01 | D66E612 | 1
10 | 9BB96 | 40.00 | 20.03 | D66E612 | 2
11 | 9BB96 | 40.00 | 40.03 | D66E612 | 3
12 | 9BB96 | 40.00 | 60.03 | D66E612 | 4
13 | 9BB96 | 40.00 | 80.03 | D66E612 | 5个

我希望完成的是使用rk的最高值(使用DENSE RANK计算)显示此屏幕截图中的所有列,其中 price>阈值和sa_id& role_id是唯一的。

在这种情况下,我只想显示以下行:1,2,3,4,5,6,7,8,10

这可能吗?

SELECT 
   servicerate_audit_id                 as sa_id
  ,ticket_price                         as price
  ,threshold_threshold/100.00           as threshold
  ,charge_role.chargerole_id            as role_id
  ,DENSE_RANK() OVER(
    PARTITION BY threshold_audit_id
    ORDER BY
        ISNULL(threshold_threshold,9999999), 
        threshold_threshold
        )                               as rk
FROM sts_service_charge_rate
   INNER JOIN ts_threshold
     ON threshold_id = servicerate_threshold_id
   INNER JOIN ts_charge_role as charge_role
     ON chargerole_id = servicerate_charge_role_id

1 个答案:

答案 0 :(得分:0)

如果您可以修改原始查询:

SELECT *
FROM (
  SELECT 
     servicerate_audit_id                 as sa_id
    ,ticket_price                         as price
    ,threshold_threshold/100.00           as threshold
    ,charge_role.chargerole_id            as role_id
    ,DENSE_RANK() OVER(
      PARTITION BY threshold_audit_id
      ORDER BY
          ISNULL(threshold_threshold,9999999), 
          threshold_threshold
          )                               as rk
    ,DENSE_RANK() OVER(
      ORDER BY
          ISNULL(threshold_threshold,9999999) DESC, 
          threshold_threshold DESC
          )                               as rk_inverse
  FROM sts_service_charge_rate
     INNER JOIN ts_threshold
       ON threshold_id = servicerate_threshold_id
     INNER JOIN ts_charge_role as charge_role
       ON chargerole_id = servicerate_charge_role_id
) t
WHERE price > COALESCE(threshold, 0)
AND t.rk_inverse = 1

观察我刚添加了您的排名的反向计算,并针对每个分区的前rk_inverse进行了过滤。我假设PARTITION BY threshold_audit_id和您对具有唯一(sa_id, role_id)元组的要求在功能上是相关的。否则,您的rk_inverse计算需要考虑不同的PARTITION BY条款。

如果您无法修改原始查询:

您可以计算另一个窗口函数,该函数按照您的分区rk为您的(sa_id, role_id)值下降(最高的第一个),然后只为每个分区选择前一个:

SELECT sa_id, price, threshold, role_id, rk
FROM (
  SELECT result.*, row_number() OVER (PARTITION BY sa_id, role_id ORDER BY rk DESC) rn
  FROM (... original query ...)
  WHERE price > COALESCE(threshold, 0)
) t
WHERE rn = 1