Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server-表查找的查询性能_Sql Server_Performance - Fatal编程技术网

Sql server SQL Server-表查找的查询性能

Sql server SQL Server-表查找的查询性能,sql-server,performance,Sql Server,Performance,我有一个数据库,需要在其中查询以从一个表中获取记录,然后在另一个表中查找以查看该值是否存在。该表可能会返回多条记录,我想要一条具有最新日期的记录 所以表1基本上是: ID (Primary Key) Name Test_Score 表2是 Test_Id (Primary) Student_ID (Foreign Key) Test_Score Test_Date 当我查看记录时,如果表2中没有关于学生id的测试,我想使用表1中的分数,否则我想使用表2中最近日期的分数。我用C#代码实现了这些

我有一个数据库,需要在其中查询以从一个表中获取记录,然后在另一个表中查找以查看该值是否存在。该表可能会返回多条记录,我想要一条具有最新日期的记录

所以表1基本上是:

ID (Primary Key)
Name
Test_Score
表2是

Test_Id (Primary)
Student_ID (Foreign Key)
Test_Score
Test_Date
当我查看记录时,如果表2中没有关于学生id的测试,我想使用表1中的分数,否则我想使用表2中最近日期的分数。我用C#代码实现了这些功能,但是客户端希望将其保存在一个存储过程中用于报告目的,而且我发现了一些性能问题,因为表非常大。此外,这个基本示例实际上针对多个表多次出现

我相信有一种优雅的方法可以快速高效地完成这项工作,但我似乎只能使用光标


有人知道直截了当的解决方案吗?

不是百分之百确定语法细节,但类似这样:

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子句。(对不起,我现在不能在这里试一试。)

仅当测试日期唯一时,查询才起作用。如果没有,你会得到重复的结果。那么你应该使用一个小组

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

Stefan Steinegger基本上有正确的答案

通过函数分解让自己变得更容易:写一个视图,为每个学生提供包含最近日期的行


然后,将其连接到student表(问题中的表1),并使用isnull或coalesce获取表1中没有行的测试分数。

如果您使用的是Sql Server 2005,则公共表表达式(CTE)提供了一个优雅的解决方案。您使用每个学生的最新考试分数创建一个CTE,然后左键连接到学生表。如果使用的测试表中存在结果,则使用学生表中的分数

我假设您的表分别称为Student和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

我无法在此计算机上测试代码-如果您提供DB模式,将更容易优化。

现在,SQL 2005上的测试解决方案,可以避免该视图,但我同意它提高了清晰度

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 

请提供完整的示例代码,这样我们就可以更容易地编写解决方案(创建表语句和一些虚拟数据)表名了,至少这样会更好,我感觉您的db模式一开始就有点不对劲。如果不知道更多的话,我真的说不出来。谢谢,这是我一直在寻找的东西。现在,我必须弄清楚如何从其中的第一列中获取名称。。。这可能是也可能不是案例约定的-我假设test_id是auto inc id,并且之前没有导入,因此最新的id将是最高的id。这假设日期将有时间元素,或者学生在一天内不会参加超过1次的测试,这可能不是事实;)