【问题标题】:Adding a rank to first row of each group为每组的第一行添加排名
【发布时间】:2016-03-18 17:29:06
【问题描述】:

这是返回我想要的,但有没有更简单、更优雅的方法?

IF OBJECT_ID('TEMPDB..#test') IS NOT NULL DROP TABLE #test;
CREATE TABLE #test
(
    userAcc VARCHAR(100),
    game VARCHAR(100),
    amount INT
);

INSERT INTO #test
values
    ('jas', 'x', 10),
    ('jas', 'y', 100),
    ('jas', 'z', 20),
    ('sam', 'j', 10),
    ('sam', 'q', 5);



--initial table sample
SELECT  userAcc,
        game,
        amount 
FROM    #test;


WITH 
X AS
(
    SELECT  rn = ROW_NUMBER() OVER (PARTITION BY userAcc ORDER BY game),
            userAcc,
            game,
            amount, 
            rk = RANK() OVER (PARTITION BY userAcc ORDER BY amount DESC)
    FROM    #test
),
Y AS
(
    SELECT  RK,userAcc,
            game,
            targ = rn
    FROM    X
    WHERE   rk = 1
)
SELECT  X.userAcc,
        X.game,
        X.amount,
        ISNULL(Y.targ,0) 
FROM    X 
        LEFT OUTER JOIN Y
        ON
        X.userAcc = Y.userAcc AND
        X.rn = Y.rk
ORDER BY X.userAcc,X.rn;

它返回这个:

这是初始表:

脚本的作用是这样的:

  1. 向原始表添加新列
  2. 在新列中,为每个 userAcc 添加最高金额的游戏排名。
  3. 排名是用户游戏中数量最多的游戏的字母顺序。所以对于 jas,他的最高比赛是 y,在他的比赛中排名第二。
  4. 在第 3 步中找到的排名应该只针对相应用户的第一个字母游戏。

【问题讨论】:

  • 您应该编辑问题并提供结果。
  • @GordonLinoff ....现在会做

标签: sql tsql sql-server-2012


【解决方案1】:

您不需要join。您可以使用累积。

如果我理解正确:

 select userAcc, game, amount,
        isnull( (case when rn = 1
               then max(case when rk = 1 then rn end) over (partition by userAcc)
           end),0) as newcol
  from (select t.*,
               ROW_NUMBER() OVER (PARTITION BY userAcc ORDER BY game) as rn,
               RANK() OVER (PARTITION BY userAcc ORDER BY amount DESC) as rk
        from #test t
       ) t
  order by userAcc;

【讨论】:

  • 非常优雅的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 2015-09-04
  • 1970-01-01
相关资源
最近更新 更多