2014-03-18 74 views
0

這似乎應該是相對的(沒有雙關語意圖)容易做到,但我無法理解它。我有三張桌子,加入了多對多的關係。一個主要的「問題」表,一個「狀態」表(查找表,指示不同狀態的名稱/描述:'打開','正在進行','已關閉'等)和一箇中間的「IssuesStatuses」主要「問題」記錄隨時間推移的多個狀態。我正在嘗試編寫T-SQL以根據IssuesStatuses表中最新的相關記錄獲取「問題」列表以及最新的StatusName。下面是表的樣子:T-SQL在多對多表格中獲取最近的相關記錄

[問題]表:
- IssueID(PK)
- IssueName
- IssueDescription

[IssuesStatuses表:
- IssuesStatusesID(PK )
- 問題ID(FK)
- 狀態ID(FK)
- 發行狀態日期

[以下狀態表:
- StatusID(PK)
- StatusName

用戶將新增多條記錄(同一IssueID)到IssuesStatuses表,因爲他們更新的主要問題記錄的狀態。因此,此查詢應該從[IssuesStatuses]表中獲取[Issues]記錄,該記錄的最新狀態,以及與該IssuesStatuses記錄關聯的[Statuses]表中關聯的StatusName記錄。我很確定我需要子查詢和/或Max(StatusDate)函數,但是當我在SQL中嘗試這樣做時,我開始編寫過於複雜的嵌套子查詢。

這是否有意義?有人可以幫助我嗎?

回答

2

狀態稱爲緩慢變化的維度。處理這些問題的一種方法是對記錄有一個「有效」和「結束」的日期。隨着EffDateEndDate,所需的查詢是很容易的,無論是:

select * 
from IssueStatus ist 
where EndDate is NULL 

where EndDate = '9999-01-01' -- or whatever your far out future date is 

缺點是插入一個新的狀態需要兩個步驟:

  1. 設置當前狀態的EndDate
  2. 插入新記錄

您通常會將此邏輯封裝在存儲過程或觸發器中。

鑑於你的數據結構,您可以通過使用not exists獲得最新的狀態:

select ist.* 
from IssueStatus ist 
where not exists (select 1 
        from IssueStatus ist2 
        where ist2.issueId = ist.issueId and 
         ist2.IssueStatusDate > ist.IssueStatusDate 
       ) 

的邏輯是:「給我的所有行IssueStatus在給定的問題一直沒有後來狀態的日期。」這相當於說:「讓我與最大日期的行。「但是由於某種原因,當你有一個索引IssueStatus(IssueId, IssueStatusDate)時,數據庫引擎將會很好地優化這個查詢。

+0

謝謝!我一定會考慮將EndDate字段添加到表中;數據庫不在生產中然而,從看你最後一個例子(我現在不在SSMS中),我猜我可以加入** ist **到查找表(狀態)來獲得狀態的漂亮名字? – TheDudeDude

+0

@TheDudeDude ......我應該添加回答「我只使用IssueStatus表顯示部分,但所有查詢都可以通過連接修改到其他表中。」 –

相關問題