我必须平均划分行, 所以在这里,例如,有15行。我想平均分配,这是三组,但我希望名称只出现在每组的第一个条目之前,如图所示:
DECLARE @NAMES TABLE
(
[ID] INT IDENTITY,
[NAME] VARCHAR(20)
)
INSERT INTO @NAMES
SELECT 'NAME1' UNION ALL
SELECT 'NAME2' UNION ALL
SELECT 'NAME3' UNION ALL
SELECT 'NAME4' UNION ALL
SELECT 'NAME5' UNION ALL
SELECT 'NAME6' UNION ALL
SELECT 'NAME7' UNION ALL
SELECT 'NAME8' UNION ALL
SELECT 'NAME9' UNION ALL
SELECT 'NAME10' UNION ALL
SELECT 'NAME11' UNION ALL
SELECT 'NAME12' UNION ALL
SELECT 'NAME13' UNION ALL
SELECT 'NAME14' UNION ALL
SELECT 'NAME15'
期望的输出:
ID NAME
----------- --------------------
1 NAME1
2
3
4
5
6 NAME6
7
8
9
10
11 NAME11
12
13
14
15
答案 0 :(得分:7)
如果您使用的是SQL 2005或更高版本,则以下任何行都应执行以下任务:
declare @numBuckets;
select @numBuckets = 3;
;with nameBase as
(
select ntile(@numBuckets) over(order by ID) as bucket,
NAME, ID
from @NAMES
),
nameRows as
(
select row_number() over(partition by bucket order by ID) as rn,
NAME, ID
from nameBase
)
select n.ID, case when rn = 1 then n.NAME else null end as NAME
from nameRows n
order by ID;
如果您需要SQL 2000或ANSI的解决方案,请尝试以下方法:
declare @numRecs int, @numBuckets int, @recsPerBucket int;
select @numRecs = count(*) from @NAMES;
select @numBuckets = 3;
select @recsPerBucket = @numRecs / @numBuckets;
select n.ID, case when d1.minIdInBucket is null then null else n.NAME end as NAME
from @NAMES n
left join (
select min(n2.ID) as minIdInBucket
from (
select n1.ID, n1.NAME,
(
select count(*) / @recsPerBucket
from @NAMES n2
where n2.ID < n1.ID
) as bucket
from @NAMES n1
) n2
group by n2.bucket
) d1
on n.ID = d1.minIdInBucket
order by n.ID;
答案 1 :(得分:0)
SELECT ID, CASE WHEN (ID = 1 OR ID = 6 OR ID = 11) THEN Name Else NULL END
FROM @Names
我知道这是一种愚蠢的做法 但是,以这种方式为有限的行集编写它更好(根据您的示例)。
如果您有更多行数(超过15个),请发布。
我会试着看看我是否能得出一个公式,以便按照你的期望打印出结果。
答案 2 :(得分:0)
您可以计算子查询中的行号和总行数。然后外部选择可以根据这些列进行选择:
select
id,
case
when id = 1 then name
when id = total/3+1 then name
when id = total*2/3+1 then name
else ''
end
from (
select row_number() over (order by id) as nr,
(select count(*) from @names) as total,
*
from @names
) sub