按列/行排序的值

时间:2010-11-19 02:25:25

标签: sql

有点难以解释。跳过示例可能更容易。

一个表有一个id和四列,每列都允许null。

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

4 个答案:

答案 0 :(得分:2)

使用:

SELECT DISTINCT COL1 AS col
  FROM YOUR_TABLE
 WHERE col1 IS NOT NULL
UNION
SELECT DISTINCT COL2 AS col
  FROM YOUR_TABLE
 WHERE col2 IS NOT NULL
UNION 
SELECT DISTINCT COL3 AS col
  FROM YOUR_TABLE
 WHERE col3 IS NOT NULL
UNION
SELECT DISTINCT COL4 AS col
  FROM YOUR_TABLE
 WHERE col4 IS NOT NULL
ORDER BY col

UNION将删除声明之间的重复; DISTINCT将返回每个语句的唯一值列表。 <{1}}会比UNION ALL快,但不会删除重复项。

答案 1 :(得分: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)来摆脱重复的值。您可以将其更改为使用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进行此查询。请评论,我们会对其进行改进。

答案 2 :(得分:0)

select value from (    
    select col1 as value from table_name where col1 is not null
     union
    select col2 as value from table_name where col2 is not null
     union
    select col3 as value from table_name where col3 is not null
     union
    select col4 as value from table_name where col4 is not null     
) order by value

答案 3 :(得分:0)

试试这个

With MyTables as
(
SELECT  [Col1] as [ColX] FROM [Test].[dbo].[MyTable] 
Union 
SELECT  [Col2] as [ColX]   FROM [Test].[dbo].[MyTable]
Union
SELECT  [Col3] as [ColX]   FROM [Test].[dbo].[MyTable]
Union
SELECT  [Col4] as [ColX]   FROM [Test].[dbo].[MyTable]
)
select ColX from MyTables where ColX is not null