2017-05-26 13 views
2

とSUMの一種このSQL - varchar型

ID Version Value1 Value2 Value3 
1  1   Shaft  
1  2     steel  xy 
2  1     Knife  somethins 
2  3   Super 

のように見える(変な)テーブルがコンテンツを持っている、最高のバージョンからの値を使用することによって、この結果を持っている必要があり、マージしたいています

ID Value1 Value2 Value3 
1  Shaft  steel  xy 
2  Super  Knife  somethin 

私が知っている限り、Max(Version)を使っているグループは、最も高いバージョンの行のNULL値を持っています。

SUMのようなもの?

+0

あなたの現在のクエリの試行を見せてください! – jarlh

+0

どのdbmsを使用しますか?それはDB scpecificすることができますか?適切なタグを追加してください – StanislavL

+0

MS SQL、MS SQL Studioのクエリ – Volker

答えて

1

第二には、してみてください...あり、おそらく短く、よりよい解決策はありますが、それは動作するはずです:値は、これらのバージョンでは、元の表とnot nullnot blank、その後joinedあるSELECT max(version)CASE WHENを使用し

with 
v1 as 
(
select w1.id, w1.value1 from weird w1 
where w1.value1 is not null 
and w1.version=(select max(w11.version) from weird w11 where w11.id=w1.id and w11.value1 is not null) 
), 
v2 as 
(
select w2.id, w2.value2 from weird w2 
where w2.value2 is not null 
and w2.version=(select max(w22.version) from weird w22 where w22.id=w2.id and w22.value2 is not null) 
), 
v3 as 
(
select w3.id, w3.value3 from weird w3 
where w3.value3 is not null 
and w3.version=(select max(w33.version) from weird w33 where w33.id=w3.id and w33.value3 is not null) 
) 
select v1.id, v1.value1, v2.value2, v3.value3 
from v1, v2, v3 
where v1.id=v2.id and v1.id=v3.id; 
+0

「id by group」はありませんが)私は論理が好きです – StanislavL

+0

ありがとうございました! :-) ID/VERSIONが主キーの場合には、id *ごとに1つの行のみを含める必要があるため、 'group by id'をスキップしました。 – Galcoholic

+0

それは間違っています。あなたが複数のIDを持っていて、それぞれのIDが自分の必要なバージョンであるとします。あなたの場合、IDは使用されていません。それはあなたが – StanislavL

-1

。クエリの下に表示されるリンクの実際の動作を確認できます

このクエリを使用します。

Select distinct a.*, b.value1, c.value2, d.value3 
from 
(
Select id, max(case when (value1 is not null and value1 <> ' ') then version else 0 end) as ver1, 
max(case when (value2 is not null and value2 <> ' ') then version else 0 end) as ver2, 
max(case when (value3 is not null and value3 <> ' ') then version else 0 end) as ver3 
from 
your_table 
group by id 
) a 
inner join 
your_table b, 
your_table c, 
your_table d 
where (a.ver1=b.version and a.id=b.id) 
and (a.ver2=c.version and a.id=c.id) 
and (a.ver3=d.version and a.id=d.id) 

はあなたがrow_numberで値をランク付けすることができ、このlink

+0

は最大ではなくバージョン – StanislavL

+0

で最大でなければなりません。それで、私は 'max(バージョン)の代わりに'を書いています.OPはmax(value)を使うことができます。もしOPがこれを書いて理解しやすいと感じたら –

+0

このSELECTは上記の例では行を返しません。テーブルのどの行が 'value1がnullでなく、value2がnullでなくvalue3がnullでもない'を満たす行はどれですか? – Galcoholic

0

で、ここでのアクションでそれを参照してください。次のクエリは、まずそのようなランクを作成します。 rn1は、バージョンの降順にidvalue1 is null/not nullで作成されています。 IDごとに、最後のヌル値と最後に満たされた値のために#1が得られます。後で我々はrn1 = 1を使用して、2つのうちの最大値を取得します。これは最後に満たされた値です。 rn2/value2およびrn3/value3と同じです。

select 
    id, 
    min(case when rn1 = 1 then value1 end) as value1, 
    min(case when rn2 = 1 then value2 end) as value2, 
    min(case when rn3 = 1 then value3 end) as value3 
from 
(
    select 
    id, value1, value2, value3, 
    row_number() over (partition by id, case when value1 is null then 0 else 1 end order by version desc) as rn1, 
    row_number() over (partition by id, case when value2 is null then 0 else 1 end order by version desc) as rn2, 
    row_number() over (partition by id, case when value3 is null then 0 else 1 end order by version desc) as rn3 
    from mytable 
) ranked 
group by id 
order by id; 
1

私たちは、あなたが望むデータを構築するために創造UNPIVOT and PIVOTを使用することができます。

declare @t table (ID int not null, Version int not null, Value1 varchar(20) null, 
        Value2 varchar(20) null, Value3 varchar(20) null) 
insert into @t(ID,Version,Value1,Value2,Value3) values 
(1,1,'Shaft',null,null), 
(1,2,null,'steel','xy'), 
(2,1,null,'Knife','somethins'), 
(2,3,'Super',null,null) 

;With Numberable as (
    select *,ROW_NUMBER() OVER (PARTITION BY ID,Val ORDER BY Version desc) rn 
    from @t t 
    unpivot (tdata for Val in (Value1,Value2,Value3)) u 
), Selected as (
    select ID,tdata,Val 
    from Numberable where rn = 1 
) 
select 
    * 
from Selected s 
pivot (MAX(tdata) for Val in (Value1,Value2,Value3)) u 

UNPIVOTが自動的NULL秒を削除します。 ROW_NUMBER()は、保持したい値を識別します。 。我々は唯一たので(私はピボットでMAXを使用していますが、それはただオプティマイザを満たすためだ

ID   Value1    Value2    Value3 
----------- -------------------- -------------------- -------------------- 
1   Shaft    steel    xy 
2   Super    Knife    somethins 

PIVOTは、私たちが望む最終的な結果を作成するようSelected CTEは、我々が不要になった列を非表示にします各IDVal組み合わせごとに1行を選択し、我々は多くても1つの値がピボットにより形成された格子の最後の位置)


に表示されるように選択されることを知っている上記Value1という仮定を作るし、 Value2およびValue3は、すべて同じ、または少なくとも互換性のあるデータ型を持ちます。