【问题标题】:Order by pairs of values按值对排序
【发布时间】:2015-05-11 18:02:40
【问题描述】:

我有一组排名,按组和排名排序:

Group | Rank
------------
  A   |  1
  A   |  2
  A   |  3
  A   |  4
  A   |  5
  A   |  6
  B   |  1
  B   |  2
  B   |  3
  B   |  4
  C   |  1
  C   |  2
  C   |  3
  C   |  4
  C   |  5
  D   |  1
  D   |  2
  D   |  3
  D   |  4

我想交错各组,按组和排名排序,一次每组 n 个排名(这里,n=2):

Group | Rank
------------
  A   |  1
  A   |  2
  B   |  1
  B   |  2
  C   |  1
  C   |  2
  D   |  1
  D   |  2
  A   |  3
  A   |  4
  B   |  3
  B   |  4
  C   |  3
  C   |  4
  D   |  3
  D   |  4
  A   |  5
  A   |  6
  C   |  5

我已经通过循环和表变量达到了预期的结果(代码粘贴在这里,因为我在 SQL Fiddle 中遇到了非描述性语法错误):

CREATE TABLE Rankings([Group] NCHAR(1), [Rank] INT)

INSERT Rankings
VALUES 
('A',1),
('A',2),
('A',3),
('A',4),
('A',5),
('A',6),
('B',1),
('B',2),
('B',3),
('B',4),
('C',1),
('C',2),
('C',3),
('C',4),
('C',5),
('D',1),
('D',2),
('D',3),
('D',4)

-- input
DECLARE @n INT = 2 --number of group rankings per rotation
-- output
DECLARE @OrderedRankings TABLE([Group] NCHAR(1), Rank INT)

-- 

-- in-memory rankings.. we will be deleting used rows
DECLARE @RankingsTemp TABLE(GroupIndex INT, [Group] NCHAR(1), Rank INT)
INSERT @RankingsTemp 
SELECT 
  ROW_NUMBER() OVER (PARTITION BY Rank ORDER BY [Group]) - 1 AS GroupIndex,
  [Group],
  Rank
FROM Rankings
ORDER BY [Group], Rank

-- loop variables
DECLARE @MaxGroupIndex INT = (SELECT MAX(GroupIndex) FROM @RankingsTemp)
DECLARE @RankingCount INT = (SELECT COUNT(*) FROM @RankingsTemp)
DECLARE @i INT

WHILE(@RankingCount > 0)
BEGIN
  SET @i = 0;
  WHILE(@i <= @MaxGroupIndex)
  BEGIN
    INSERT INTO @OrderedRankings
    ([Group], Rank)
    SELECT TOP(@n)
      [Group],
      Rank
    FROM @RankingsTemp
    WHERE GroupIndex = @i;

    WITH T AS (
      SELECT TOP(@n) *
      FROM @RankingsTemp
      WHERE GroupIndex = @i
    );
    DELETE FROM T

    SET @i = @i + 1;
  END
  SET @RankingCount = (SELECT COUNT(*) FROM @RankingsTemp)
END

SELECT @RankingCount as RankingCount, @MaxGroupIndex as MaxGroupIndex

-- view results
SELECT * FROM @OrderedRankings

如何使用基于集合的方法(无循环、无表变量)实现所需的排序?

我使用的是 SQL Server Enterprise 2008 R2。

编辑:为了澄清,我需要每组不超过n 行才能连续出现。此查询的目标是产生一个排序,当顺序读取时,提供每个组的相等表示(一次 n 行),相对于排名。

【问题讨论】:

  • 将排名除以 2 作为新列向上取整,然后按其排序,然后分组然后排名。 1/2 = 1 2/2=1 3/2=2 4/2=2 等等...Ceiling(value)我相信是语法或Ceiling(rank/2)

标签: sql sql-server sql-server-2008 sql-order-by


【解决方案1】:

可能是这样的...SQL FIDDLE

Order by
 Ceiling(rank*1.0/2), group, rank

上面的工作小提琴(列名略有变化)

更新:被 int math 烧毁了……现在应该可以工作了。通过乘以 1.0 将 int 强制为小数,因此隐式转换不会丢弃我需要正确舍入的余数。

【讨论】:

  • 不错!比我的建议优雅得多。
  • 谢谢,但这并不能产生理想的结果(请参阅我的问题的编辑)
  • 只需将 rank/2 替换为 rank/n。实际上,可能要使用rank*1.0/n,否则使用整数除法。
  • 哇,做到了。简单有效。谢谢!
  • 处理 n 只需根据需要更改 2 虽然变量但我猜@jonathanWilson 已经得到了那部分。
【解决方案2】:

假设您的等级数量相对较少,这将起作用:

Order by
  case when rank <= n then 10
    when rank <= 2*n then 20
    when rank <= 3*n then 30
    when rank <= 4*n then 40
    when rank <= 5*n then 50 --more cases here if needed
    else 100 
  end
, group
, rank

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    相关资源
    最近更新 更多