【问题标题】:sql server - returning text for multiple vendors based on average valuessql server - 根据平均值返回多个供应商的文本
【发布时间】:2013-11-18 21:30:09
【问题描述】:

我有一张表格,给出了各个供应商/地区的评级。格式如下。

我想知道,对于每个不同的月份,以及供应商 (exp_id)

评分最高和最低的pickup_ward_text是什么

我的预期输出类似于:

[年][月][exp_id] [最高评分pickup_ward] [最低评分pickup_ward]

“评分”是 rating_driver、rating_punctuality 和 rating_vehicle 的平均值

我完全不知道如何实现这一点,我试图正确地越过下表的第一行。一个

Year    Month   exp_id  RATING_DRIVER   RATING_PUNCTUALITY  RATING_VEHICLE  booking_id  pickup_date ratingjobref    rating_date PICKUP_WARD_TEXT
2013       10    4            5.00       5.00                      5.00     1559912    30:00.0    1559912       12/10/2013 18:29       N4

【问题讨论】:

  • 哪个版本的 SQL?
  • 道歉,MSSQL Server 2012
  • 有趣的问题,做起来没那么难,关键是效率。
  • 不管怎样,我最好的计划是两个临时的#tables - 一个代表最好的和最坏的,然后将它们加入我的桌子。不过,计算出最好的或最差的,并正确分组,让我很困惑。

标签: sql sql-server max case rank


【解决方案1】:

使用 row_number() 来查找最小值或最大值有一个常见的模式。您可以将它们与一些小技巧结合起来:

select
    year,
    month,
    exp_id,
    max(case rn1 when 1 then pickup_ward_text end) as min_pickup_ward_text,
    max(case rn2 when 1 then pickup_ward_text end) as max_pickup_ward_text
from (
    select
        year,
        month,
        exp_id,
        pickup_ward_text,
        row_number() over (
            partition by year, month, exp_id 
            order By rating_driver + rating_punctuality + rating_vehicle
        ) rn1,
        row_number() over (
            partition by year, month, exp_id 
            order By rating_driver + rating_punctuality + rating_vehicle desc
        ) rn2
    from
        mytable
    ) x
where
    rn1 = 1 or rn2 = 1 -- this line isn't necessary, but might make things quicker
group by
    year,
    month,
    exp_id
order by
    year,
    month,
    exp_id

为每个部分和内部连接它们创建两个派生表实际上可能会更快。一些测试是有序的:

select
    n.year,
    n.month,
    n.exp_id,
    n.pickup_ward_text as min_pickup_ward_text,
    x.pickup_ward_text as max_pickup_ward_text
from (
    select
        year,
        month,
        exp_id,
        pickup_ward_text,
        row_number() over (
            partition by year, month, exp_id 
            order By rating_driver + rating_punctuality + rating_vehicle
        ) rn
    from
        mytable
    ) n
    inner join (
    select
        year,
        month,
        exp_id,
        pickup_ward_text,
        row_number() over (
            partition by year, month, exp_id 
            order By rating_driver + rating_punctuality + rating_vehicle desc
        ) rn
    from
        mytable
    ) x
    on n.year = x.year and n.month = x.month and n.exp_id = x.exp_id
where
    n.rn = 1 and
    x.rn = 1 
order by
    year,
    month,
    exp_id

【讨论】:

  • 这真是太聪明了。
  • 我不确定 2012 年是否可以看穿案例陈述以提高效率。
  • 哇 - 非常狡猾,分区部分的行号是我需要查看的很多事情的症结所在。我现在更有信心了,知道您是如何做到的,而且我喜欢使用行号技巧从“中间人”表中选择输出 - 非常感谢
  • 两者都在一秒钟内返回 624 行,抱歉我不能在测试中提供更多帮助.. :)
  • @finngeraghty 有了这几行,选择你觉得更容易理解的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 2013-03-24
相关资源
最近更新 更多