好吧,這個問題有點複雜,請耐心等待。半複雜集合選擇語句混淆
我有一張充滿數據的表格。其中一個表列是EntryDate。每天可以有多個條目。但是,我想要選擇所有日期中最新條目的所有行,並且要選擇所有表中的所有列。
其中一列是一個唯一標識符列,但它不是主鍵(我不知道它爲什麼存在;這是一個非常舊的系統)。爲了演示的目的,假設表格如下所示:
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
但是,好了,看它!用空值創建一個表,然後進行更新以獲取值 - 當然有更好的方法來做到這一點?一個單一的聲明,將首次給我所有的價值?
我相信,原始select
(圖1)上的正確連接可以實現訣竅,就像自連接或其他東西一樣......但您如何使用group by
子句做到這一點?我無法找到正確的語法來執行查詢。
我很新的SQL,所以很可能我錯過了一些明顯的東西。有什麼建議麼?
(以T-SQL的工作,如果它使任何區別)
感謝您對錶現的關注。我嘗試了兩種方法,而且你是對的 - 臨時表方法的速度提高了1秒(總共83和84秒)!但是我會在任何一天(幾乎)任何一天對你的解決方案進行簡潔的說明...... – 2010-03-08 18:43:31