2010-11-19 19 views
1

説明するのは少し難しいです。例にスキップする方が簡単かもしれません。列/行による順序付け値

テーブルには、それぞれがnullを許可するIDと4つの列があります。

ID, Col1, Col2, Col3, Col4 

x個の行があります。 (通常は4未満)列全体で最大4つの異なる値が使用されます。

結果セットの各行は、基本的に、値が最初から左から選択されている列の値であり、最初のCol値を保持しているところから4行戻ってきます。他の行の値が列に固有でない場合は、次に使用可能な列に移動します。

例:

私が持っている場合:

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 

感謝を与えます!値の間にユニークな列とスペースがない場合のシナリオを投げ捨てることができます。
これは発生しません。

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 
+0

これらの潜在的なソリューションが返す与えられた最初の例として動作しませんでした B D C – TrevDev

+0

私はそれがどこから来た何行/列の詳細気にして私がコラムで発注するべきではありません。 – TrevDev

+0

あなたはSQL Serverを扱っているように見えます。バージョンも含めてください。 –

答えて

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を使用しています。私たちはコメントしてください。

+0

2番目の例をテストするために挿入するコメント付きのselect文を追加しました。コメントでうまく整形できません。しかし、2番目の例は機能しません。どのselect文がコメントされているかを切り替えてみてください。 – TrevDev

+0

結果はどうなるでしょうか?クエリのチューニングに役立ちます。 –

+0

私はクエリを更新しました。それをチェックし、あなたのためにどのように動作するかを見てください。 –

2

用途:これは役立つかもしれない

a,b,,d 
c,,, 

をUNION

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 

文の間で重複を削除します。 DISTINCTは、文ごとに一意の値リストを返します。 UNION ALLUNIONより高速ですが、重複は削除されません。

+0

更新されたサンプルを確認すると、このクエリは機能しません。 Order By Colは、値のソースではなく値でソートします。私は元の列が既にその列に異なる値を持っていた場合を除いて、ソース列であることをどうにかしたいと思います。その例はそれをより良く示しています。 – TrevDev

+0

@Thx:私は更新を見て、私は値よりもむしろソースに基づいて注文を提案するものは遠く見ない。期待される出力の両方の例は、 "A、B、C、D"のリストです。これは私のクエリが達成するものです。 –

+0

両方の例を更新して、これをより明確にすることを願っています。 – TrevDev

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 
+0

更新されたサンプルを確認すると、このクエリが機能しないことがわかります。 Order By値は、値のソースではなく値でソートされます。私は元の列が既にその列に異なる値を持っていた場合を除いて、ソース列であることをどうにかしたいと思います。その例はそれをより良く示しています。 – TrevDev

0

私はあなたが望んでいた記述のすべてを理解していない可能性が、この1

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 
+0

おかげで、これは近いですが、私は正しい順序である必要が返される結果は、十分に特定されていない可能性があります。例えば B Cこれら4つの結果は、種類のものに対応 D 彼らはどこから来たのだろうか。最高の優先度を持つ最大のIDを持つ。ありがとう! – TrevDev

関連する問題