SQL 服务器中的最大行数和最小行数

Maximum and Minimum Rows Alternatively in SQL Server

这是一名员工 table,

Id    Name     Salary
1       A.J     7000
2       B.S     30000
3       C.K     2000
4       D.O     10000
5       E.L     500

现在我想显示 1st 最高薪水然后 minimum 薪水然后 2nd 最高薪水然后 2nd 最低薪水等等..直到第 n 行。

预期输出,

Id     Name    Salary
2       B.S     30000
5       E.L     500
4       D.O     10000
3       C.K     2000
1       A.J     7000

使用 Row_Number()Count() Fiddle Demo

declare @count int=(select count(1) from Employee);
with cte1 as
    (
    select ROW_NUMBER() over(order by salary desc) as rn,0 Sort,Id,Name,Salary, count(Id) over () cnt from Employee
    union all
    select ROW_NUMBER() over(order by salary) as rn,1 Sort,Id,Name,Salary, count(Id) over () cnt from Employee
    )
    select  top (@count) Id,Name,Salary from cte1 where  rn <= (floor(cnt/2) + cnt%2) order by rn,sort

还有一个没有明确说明的变体 COUNTSQL Fiddle.

也尝试将此行添加到 fiddle 中的示例数据 (6, 'X.Y', 7000)。查询仍然 returns 正确结果。

DECLARE @Employee TABLE (ID int, Name nvarchar(50), Salary money);

INSERT INTO @Employee (ID, Name, Salary) VALUES
(1, 'A.J', 7000),
(2, 'B.S', 30000),
(3, 'C.K', 2000),
(4, 'D.O', 10000),
(5, 'E.L', 500);

WITH
CTE
AS
(
    SELECT *, NTILE(2) OVER (ORDER BY Salary, ID) AS n
    FROM @Employee AS E
)
SELECT
    *
    ,SIGN(n-1.5) AS s
    ,SIGN(n-1.5)*Salary AS ss
    ,ROW_NUMBER() OVER(PARTITION BY n ORDER BY SIGN(n-1.5)*Salary DESC) AS rn
FROM CTE
ORDER BY rn, ss DESC;

结果

ID    Name    Salary      n       s       ss          rn
2     B.S     30000.00    2     1.0    30000.00000    1
5     E.L     500.00      1    -1.0     -500.00000    1
4     D.O     10000.00    2     1.0    10000.00000    2
3     C.K     2000.00     1    -1.0    -2000.00000    2
1     A.J     7000.00     1    -1.0    -7000.00000    3

我在输出中留下了中间列来说明它是如何工作的。

解决方法如下:

--Create dummy employee table
CREATE TABLE tbl_Employee
(
 Id INT,
 Name VARCHAR(100),
 Salary NUMERIC(9, 2)
)
GO

--Insert few dummy rows in the table
INSERT INTO #Employee
(Id, Name, Salary)
VALUES(100, 'John', 7000),
(101, 'Scott', 30000),
(102, 'Jeff', 2000),
(103, 'Jimy', 10000),
(104, 'Andrew', 500),
(105, 'Alister', 100)
GO
--Get data as required
DECLARE @Cnt INT = 0, @SeqLimit INT = 0
SELECT @Cnt = COUNT(1) FROM tbl_employee
SET @SeqLimit = CEILING(@Cnt / 2.0)

SELECT * FROM
(
 SELECT ROW_NUMBER() OVER(ORDER BY Salary DESC) AS SEQ, Id, Name, Salary FROM tbl_employee
)DT1
WHERE SEQ <= @SeqLimit
UNION ALL
SELECT * FROM
(
 SELECT ROW_NUMBER() OVER(ORDER BY Salary ASC) AS SEQ, Id, Name, Salary FROM tbl_employee
)DT2
WHERE SEQ <= @SeqLimit - (@Cnt % 2)
ORDER BY SEQ ASC, Salary DESC

同样的方法可以通过不同的方法实现,您可以在这里找到更多相关信息: http://www.sqlrelease.com/order-max-and-min-value-rows-alternatively-in-sql-server