反转序列

时间:2017-11-06 15:11:50

标签: sql sql-server sql-server-2008 sql-server-2012

这是在采访中向我询问的问题。对于像这样的表(可能有数百或数千个此类记录)

Question Table

恢复Seq的最佳方法是什么,A将是seq 4,B将是seq 1,如下所示:

Result Table

我给了他以下查询(我使用了CTE Just来创建示例场景。在原始情况下它是一个表):

WITH CTE
AS
(
    SELECT
        Seq = 1,Nm = 'A'
    UNION
    SELECT
        Seq = 2,Nm = 'A'
    UNION
    SELECT
        Seq = 3,Nm = 'B'
    UNION
    SELECT
        Seq = 4,Nm = 'B'
)
SELECT
    Seq = ROW_NUMBER() OVER(ORDER BY Seq DESC),
    Seq,
    Nm
    FROM CTE;

是否存在以更有效的方式实现相同的动态查询?

4 个答案:

答案 0 :(得分:2)

怎么样?

select seq, (case when nm = 'B' then 'A' else 'B' end) as nm
from t;

答案 1 :(得分:1)

如果我将表的计数保存到声明的变量,那么我可以使用子查询来获得反向的第二列。 SQL Server执行计划表明批处理成本低于ROWNUMBER()。

DECLARE @tablename TABLE(seq int PRIMARY KEY, Nm char(1))
INSERT INTO @tablename VALUES (1,'A'), (2,'A'), (3,'B'), (4,'B')

DECLARE @count int = (SELECT COUNT(*) FROM @tablename)

SELECT seq
      ,(SELECT Nm 
          FROM @tablename T2
         WHERE T2.seq = @count +1 - T1.seq) AS [Nm]
  FROM @tablename T1

答案 2 :(得分:0)

替代查询,不使用OVER子句

SELECT
    (SELECT MAX(mytable.Seq) FROM mytable) - mytable.Seq + 1 As Seq,
    Nm
FROM mytable
ORDER BY mytable.Seq DESC

答案 3 :(得分:0)

我不认为在这里帮助处理面试问题是合适的,但由于这一点非常不现实,而且这里有很多复杂的答案,我提出了这个更简单的解决方案:

DECLARE @MaxSeq INT;
SELECT @MaxSeq = MAX(Seq) FROM Table;


UPDATE Table 
Set Seq = @MaxSeq - Seq + 1