小编典典

按列/行排序的值

sql

它有点难以解释。跳到示例可能会更容易。

一个表有一个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   ,     ,     ,

A  
B  
D  
C

ID, Col1, Col2, Col3, Col4  
0,  A   , B   , D   ,   
1,  C   ,     ,     ,  
2,  C   ,     ,     ,

A  
B  
D  
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

阅读 212

收藏
2021-04-07

共1个答案

小编典典

我可能不明白您所描述的一切。通过阅读您的问题和其他人的评论,我想这就是您要寻找的:

更新后的版本:

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进行此查询。请发表评论,我们将对其进行完善。

2021-04-07