假设下表
ID Name RowNumber
2314 YY 1
213 XH 2
421 XD 3
123 AA 4
213 QQQ 5
12 WW 6
312 RR 7
123 GG 8
12 F 9
12 FF 10
312 VV 11
12 BB 12
32 NN 13
43 DD 14
53 DD 15
658 QQQQ 16
768 GGG 17
我想根据
条件用空字符串替换Name
字段
例如,如果用户输入5,则只保留5个值,结果应为(或类似) -
ID Name RowNumber
2314 YY 1
213 2
421 3
123 AA 4
213 5
12 6
312 7
123 GG 8
12 9
12 10
312 11
12 12
32 NN 13
43 14
53 15
658 16
768 GGG 17
可能会有更多的记录。
我正在使用SQL Server
答案 0 :(得分:1)
以下内容适用于SQL Server 2012+,因为它使用running / cumulative SUM
。该查询假定RowNumber
列中的值是从1行到总行数而没有间隙。如果您的数据不是这样,您可以使用ROW_NUMBER
生成它们。
N
与总行数(CTE_Ratio
)的比率CTE_Groups
)CTE_Final
)Name
要更好地理解它的工作方式,将中间列(Ratio,GroupNumber,rn)包含在输出
中示例数据
DECLARE @T TABLE ([ID] int, [Name] varchar(50), [RowNumber] int);
INSERT INTO @T([ID], [Name], [RowNumber]) VALUES
(2314, 'YY', 1)
,(213, 'XH', 2)
,(421, 'XD', 3)
,(123, 'AA', 4)
,(213, 'QQQ', 5)
,(12, 'WW', 6)
,(312, 'RR', 7)
,(123, 'GG', 8)
,(12, 'F', 9)
,(12, 'FF', 10)
,(312, 'VV', 11)
,(12, 'BB', 12)
,(32, 'NN', 13)
,(43, 'DD', 14)
,(53, 'DD', 15)
,(658, 'QQQQ', 16)
,(768, 'GGG', 17);
DECLARE @N int = 5;
<强>查询强>
WITH
CTE_Ratio AS
(
SELECT
ID
,Name
,RowNumber
,COUNT(*) OVER() AS TotalRows
,CAST(@N-1 AS float) / CAST(COUNT(*) OVER() AS float) AS Ratio
FROM @T
)
,CTE_Groups AS
(
SELECT
ID
,Name
,RowNumber
,TotalRows
,ROUND(SUM(Ratio) OVER(ORDER BY RowNumber), 0, 1) AS GroupNumber
FROM CTE_Ratio
)
,CTE_Final AS
(
SELECT
ID
,Name
,RowNumber
,TotalRows
,ROW_NUMBER() OVER(PARTITION BY GroupNumber ORDER BY RowNumber) AS rn
FROM CTE_Groups
)
SELECT
ID
,CASE WHEN rn=1 OR RowNumber = TotalRows THEN Name ELSE '' END AS Name
,RowNumber
FROM CTE_Final
ORDER BY RowNumber;
<强>结果强>
+------+------+-----------+
| ID | Name | RowNumber |
+------+------+-----------+
| 2314 | YY | 1 |
| 213 | | 2 |
| 421 | | 3 |
| 123 | | 4 |
| 213 | QQQ | 5 |
| 12 | | 6 |
| 312 | | 7 |
| 123 | | 8 |
| 12 | F | 9 |
| 12 | | 10 |
| 312 | | 11 |
| 12 | | 12 |
| 32 | NN | 13 |
| 43 | | 14 |
| 53 | | 15 |
| 658 | | 16 |
| 768 | GGG | 17 |
+------+------+-----------+
答案 1 :(得分:0)
试试这个:
--Number that user enter
DECLARE @InputNumber INT
DECLARE @WorkingNumber INT
DECLARE @TotalRecords INT
DECLARE @Devider INT
SET @InputNumber = 5
SET @WorkingNumber = @InputNumber -2
--Assume @InputNumber greater than 2 and @TotalRecords greater than 4
SELECT @TotalRecords = COUNT(*)
FROM Table;
SET @Devider = CONVERT(@TotalRecords, DECIMAL(18,2))/CONVERT(@WorkingNumber, DECIMAL(18,2));
WITH Conditioned (RowNumber)
AS
(
SELECT RowNumber
FROM Table
WHERE RowNumber = 1
UNION
SELECT T.RowNumber
FROM (SELECT TOP 1 RowNumber
FROM Conditioned
ORDER BY RowNumber DESC) AS C
INNER JOIN Table AS T ON CONVERT(CEILING(C.RowNumber + @Devider), INT) = T.RowNumber
)
SELECT T.Id, CASE WHEN C.RowNumber IS NULL THEN '' ELSE T.Name END, T.RowNumber
FROM Table T
LEFT OUTER JOIN Conditioned C ON T.RowNumber = C.RowNumber
WHERE
UNION RowNumber != @TotalRecords
SELECT Id, Name, RowNumber
FROM Table
WHERE RowNumber = @TotalRecords