2009-04-21 151 views
2

我有一個數據庫,我需要查詢從一個表中獲取記錄,然後在另一個表上查找該值是否存在。該表可能會返回多個記錄,我想要最近的日期。SQL Server的查詢性能查詢表

所以表1基本上是:

ID (Primary Key) 
Name 
Test_Score 

和表2是

Test_Id (Primary) 
Student_ID (Foreign Key) 
Test_Score 
Test_Date 

,因爲我經歷的記錄,如果在表2中存在的student_id數據的沒有測試,我想要使用表1中的分數,否則我想使用表2中最近日期的分數。我將這一切全部用C#代碼工作,但客戶端需要在存儲過程中進行報告,而且由於表格非常大,所以我看到了一些性能問題。此外,這個基本的例子實際上發生在多個表上。

我敢肯定有一個優雅的方式來做到這一點,快速和高效,但我似乎無法拿出任何東西,但使用遊標。

有人知道直接的解決方案嗎?

+0

請提供完整的示例代碼,所以它更容易爲我們寫一個解決方案(創建表語句和一些虛擬數據) – 2009-04-21 22:30:57

+0

表名至少會很好,我感覺你的數據庫模式是有點開始。但是,如果不知道更多,我們無法分辨出來 – Louis 2009-04-21 22:33:27

回答

3

沒有100%地肯定百分之約語法細節,但是這樣的事情:

select table1.Name, ISNULL(table2.Test_Score, table1.Test_Score) 
from 
    table1 
    left outer join table2 
    on table1.id = table2.Student_ID 
    AND table2.Test_Date = (
     select max(x.Test_Date) 
     from table2 x 
     where table1.id = x.Student_ID 
     group by x.Student_ID) 

如果不允許子查詢的地方是,它移動到WHERE子句。 (對不起,我現在無法嘗試它。)

該查詢只在Test_Date是唯一的時才起作用。如果沒有,你會得到重複的結果。那麼你應該使用一組

select table1.Name, min(ISNULL(table2.Test_Score, table1.Test_Score)) 
from 
    table1 
    left outer join table2 
    on table1.id = table2.Student_ID 
    AND table2.Test_Date = (
     select max(x.Test_Date) 
     from table2 x 
     where table1.id = x.Student_ID 
     group by x.Student_ID) 
group by table1.id, table1.Name 
+0

謝謝,這是看我在找什麼。現在我必須弄清楚如何從那裏的第一列中找到名字。 – 2009-04-21 22:45:29

+1

這很簡單:-) – 2009-04-21 22:46:49

2

斯特凡斯泰內格爾基本上有正確的答案。

通過功能分解使自己更容易:寫一個視圖,爲每個學生提供最近日期的行。

然後將外連接到學生表(表1中的問題),並在表1中使用isnull或coalesce在視圖中沒有行的情況下獲得測試分數。

1

如果您使用的是Sql Server 2005,那麼Common Table Expressions(CTE)提供了一個優雅的解決方案。您爲每個學生創建一個CTE,並帶有最新的考試分數,然後將其加入到學生表中。如果在使用的測試表中存在結果,則使用學生表中的分數。

我假定你的表分別被稱爲學生和TestResult中,也假定爲test_id是一個自動遞增的ID

WITH RecentResults as (
    SELECT student_id, 
    test_score 
    FROM TestResult tr 
    WHERE tr.test_id = (SELECT MAX(test_id) FROM TestResult WHERE student_id = tr.student_id) 
) 
SELECT s.ID as 'Student ID', 
    isnull(rr.test_score, s.test_score) 
FROM Students s LEFT JOIN RecentResults rr ON s.ID = rr.student_id 

我無法測試這臺機器上的代碼 - 如果你提供數據庫模式將更容易細化。

1

在這裏你去,在2005年SQL測試的解決方案,認爲是可以避免的,但我認爲,它提高了清晰度

create table students (id int primary key, name nvarchar(50), score int) 
create table scores (test_id int, student_id int, score int, date datetime) 

insert students values (1, 'bob', 1) 
insert students values (2,'bill', 55) 
insert scores values (22,1,88,getdate()) 
insert scores values (23,1,88,getdate() + 1) 
insert scores values (23,1,89,getdate() + 2) 

go 

create view latest_scores 
as 
select scores.student_id, scores.date, score 
from scores 
join 
(
    select student_id, date = max(date) from scores 
    group by student_id 
) maxDates on maxDates.student_id = scores.student_id and maxDates.date = scores.date 

go 

select Id, isnull(l.score, s.score) from students s 
left join latest_scores l on student_id = id