空列值,但保持值等于使用SQL查询提供的数字
假设下表空列值,但保持值等于使用SQL查询提供的数字,sql,sql-server,Sql,Sql Server,假设下表 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
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
字段替换为空字符串:
--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
以下内容适用于SQL Server 2012+,因为它使用running/cumulative
SUM
。该查询假定RowNumber
列中的值从1到总行数顺序排列,没有间隙。如果您的数据不是这样,您可以使用ROW\u NUMBER
生成它们
- 计算给定数量的比率
和总行数(N
)CTE\u比率
- 计算此比率的运行总和,截断总和的小数部分(
)CTE\u组
- 运行rum的每个整数值定义一组行,对每个组中的行重新编号(
)CTE_Final
- 仅为每组的第一行保留
Name
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 |
+------+------+-----------+
您正在使用什么RDBMS?您所说的“第一个和最后一个单元格”是什么意思?表本质上是不排序的,所以除非指定了顺序(在sql语句中使用order by),否则“first”和“last”都没有意义。假设它是按行号ROK排序的,那么保留
AA
、GG
和NN
而不是例如QQQ
的原因是什么,FF`andDD
?它可以是任何字符串。您已加入表。。ID不是主键,因为您可以看到问题..ID不是唯一的
+------+------+-----------+
| 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 |
+------+------+-----------+