它有点难以解释。跳到示例可能会更容易。
一个表有一个ID和四列,每列允许为空。
ID, Col1, Col2, Col3, Col4
有x行数。(通常小于4)并且在整个列中最多只能使用4个不同的值。
我希望返回最多4行,其中结果集中的每一行基本上都是一列值,其中该值是从顶部保留Col编号开始从右向左选择的。如果另一行的值不是列唯一,则将其移至下一个可用列。
例子:
如果我有:
ID, Col1, Col2, Col3, Col4 0, A , B , , C 1, , , D ,
我想回来
A B D C
和
ID, Col1, Col2, Col3, Col4 0, A , B , D , 1, C , , ,
给
ID, Col1, Col2, Col3, Col4 0, A , B , D , 1, C , , , 2, C , , ,
谢谢!当存在非唯一列并且值之间存在空格时,可以排除这种情况。 这不会发生:
a,b,,d c,,,
这可能会有所帮助:
CREATE TABLE #original ( id int ,A INT, B INT, C INT, D INT ); INSERT INTO #original --SELECT 0,1,2,null,4 --union --select 1,null,null,3,null -- -- --SELECT 0,1,2,3,null --union --select 1,4,null,null,null -- -- SELECT 0,1,2,4,null union select 1,3,null,null,null union select 2,3,null,null,null select * from #original order by id asc; with cteOriginal as ( select *, RANK() over (partition by [SortOrder] order by id asc) as [NonUniqueSortOrder] from ( select id, A as [value], 1 as [SortOrder] from #original where A is not null union all select id, B as [value], 2 as [SortOrder] from #original where B is not null union all select id, C as [value], 3 as [SortOrder] from #original where C is not null union all select id, D as [value], 4 as [SortOrder] from #original where D is not null ) as temp ) select [value] from ( select top 50 [value], ((([NonUniqueSortOrder] - 1) * 4) + [SortOrder]) sortedOrder from cteOriginal order by sortedOrder ) tmp group by [value] order by min(sortedOrder) DROP TABLE #original
我可能不明白您所描述的一切。通过阅读您的问题和其他人的评论,我想这就是您要寻找的:
更新后的版本:
with cteOriginal as ( select *, RANK() over (partition by [SortOrder] order by id asc) as [NonUniqueSortOrder] from ( select id, A as [value], 1 as [SortOrder] from #original where A is not null union all select id, B as [value], 2 as [SortOrder] from #original where B is not null union all select id, C as [value], 3 as [SortOrder] from #original where C is not null union all select id, D as [value], 4 as [SortOrder] from #original where D is not null ) as temp ) select [value] from cteOriginal where id = (select MIN(tmp.id) from cteOriginal tmp where tmp.value = cteOriginal.value) order by ((([NonUniqueSortOrder] - 1) * 4) + [SortOrder])
我通过选择具有最小id(min(id))的重复值来摆脱重复值。您可以将其更改为使用max(id)。
初始版本:
with cteOriginal as ( select *, RANK() over (partition by [column] order by id asc) as [NonUniqueSortOrder] from ( select id, A as [value], 'A' as [Column], 1 as [SortOrder] from #original where A is not null union all select id, B as [value], 'B' as [Column], 2 as [SortOrder] from #original where B is not null union all select id, C as [value], 'C' as [Column], 3 as [SortOrder] from #original where C is not null union all select id, D as [value], 'D' as [Column], 4 as [SortOrder] from #original where D is not null ) as temp ) select [value] from cteOriginal order by ((([NonUniqueSortOrder] - 1) * 4) + [SortOrder])
顺便说一句,我正在使用mssql 2005进行此查询。请发表评论,我们将对其进行完善。