さて、この問題は少し複雑なので、我慢してください。
データでいっぱいのテーブルがあります。テーブル列の1つはEntryDateです。1日に複数のエントリが存在する可能性があります。ただし、それぞれの日の最新のエントリであるすべての行を選択し、そのテーブルのすべての列を選択したいと思います。
列の1つは一意の識別子列ですが、主キーではありません(なぜそこにあるのかわかりません。これは、かなり古いシステムです)。デモンストレーションの目的で、テーブルが次のようになっていると言います。
create table ExampleTable (
ID int identity(1,1) not null,
PersonID int not null,
StoreID int not null,
Data1 int not null,
Data2 int not null,
EntryDate datetime not null
)
主キーはPersonIDとStoreIDにあり、これらは論理的に一意性を定義します。
さて、私が言ったように、私はその特定の日の最新のエントリであるすべての行を選択したいと思います(Person-Storeの組み合わせごとに)。これは非常に簡単です。
--Figure 1
select PersonID, StoreID, max(EntryDate)
from ExampleTable
group by PersonID, StoreID, dbo.dayof(EntryDate)
ここで、dbo.dayof()は、日時から時間コンポーネントを取り除く単純な関数です。ただし、これを行うと、残りの列が失われます。他の列を単純に含めることはできません。そうすると、group by
それらを含める必要があり、間違った結果が生成されるためです(特に、IDが一意であるため)。
私は自分がやりたいことをする汚いハックを見つけましたが、もっと良い方法があるはずです-これが私の現在の解決策です:
select
cast(null as int) as ID,
PersonID,
StoreID,
cast(null as int) as Data1,
cast(null as int) as Data2,
max(EntryDate) as EntryDate
into #StagingTable
from ExampleTable
group by PersonID, StoreID, dbo.dayof(EntryDate)
update Target set
ID = Source.ID,
Data1 = Source.Data1,
Data2 = Source.Data2,
from #StagingTable as Target
inner join ExampleTable as Source
on Source.PersonID = Target.PersonID
and Source.StoreID = Target.StoreID
and Source.EntryDate = Target.EntryDate
これで正しいデータが得られます#StagingTable
が、よく見てください。null値を使用してテーブルを作成し、更新を実行して値を元に戻します。これを行うためのより良い方法は確かにありますか?初めてすべての値を取得する単一のステートメント?
select
そのオリジナル(図1)に正しく結合すると、自己結合などのトリックが実行されると私は信じています...しかし、このgroup by
句をどのように使用しますか?クエリを実行するための正しい構文が見つかりません。
私はSQLにかなり慣れていないので、明らかな何かが欠けている可能性があります。助言がありますか?
(違いが生じる場合は、T-SQLでの作業)