Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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 2005 查找1-N关系中第一个(按日期)关联记录的有效SQL查询_Sql Server 2005_Tsql - Fatal编程技术网

Sql server 2005 查找1-N关系中第一个(按日期)关联记录的有效SQL查询

Sql server 2005 查找1-N关系中第一个(按日期)关联记录的有效SQL查询,sql-server-2005,tsql,Sql Server 2005,Tsql,这是一个场景:有一个软件表PK=SoftwareID和一个相关的发布表PK=[SoftwareID,Version] 发布可以是主要的,也可以是次要的,发布类型由release.ReleaseType'MAJ',MIN'标识 发布还以日期为特征:release.ReleaseDate 软件被划分为类别,由Software.CategoryID标识 问题:需要有效的T-SQL查询来列出特定类别的所有软件,并且第一个主要发布日期在给定的时间间隔内,由@DateFrom、@DateTo分隔。最终结果集

这是一个场景:有一个软件表PK=SoftwareID和一个相关的发布表PK=[SoftwareID,Version]

发布可以是主要的,也可以是次要的,发布类型由release.ReleaseType'MAJ',MIN'标识

发布还以日期为特征:release.ReleaseDate

软件被划分为类别,由Software.CategoryID标识

问题:需要有效的T-SQL查询来列出特定类别的所有软件,并且第一个主要发布日期在给定的时间间隔内,由@DateFrom、@DateTo分隔。最终结果集中只需要SoftwareID和ReleaseDate列

这不是真实的情况,但我用这种方式来表述,以便更容易理解。在实际情况下,表发行版将有大约1000万条记录,表软件大约有100万条。我已经提出了一个解决方案,但速度很慢,我觉得这里的专家可能会找到更好的解决方案

以下是我的缓慢解决方案:

select  s.SoftwareID, min(r.ReleaseDate)
from
    Software s inner join Release r on (s.SoftwareID = r.SoftwareID)
where s.CategoryID = @Category
      and r.ReleaseType = 'MAJ'
group by
    s.SoftwareID
having
    min(r.ReleaseDate) >= @DateFrom
    and min(r.ReleaseDate) < @DateTo
谢谢。

您的查询很好

您可能需要确保您的查询具有适当的索引:

在MSSQL管理工作室中:查询->在数据库引擎优化顾问中分析查询,然后按照白兔优先顺序操作 在MSSQL Management Studio中:查询->包含实际执行计划。然后运行查询,查看执行计划是否建议使用新索引。
你可能有索引问题。您是否尝试过在ReleaseDate列上创建索引,或在包含按ReleaseDate排序的ReleaseDate的表上创建聚集索引?

尝试以下方法:

select  
  s.SoftwareID, 
  min(r.ReleaseDate)
from
  Software s 
  inner join Release r on s.SoftwareID = r.SoftwareID
where 
  s.CategoryID = @Category
  and r.ReleaseType = 'MAJ'
  and s.ReleaseDate >= @DateFrom
  and s.ReleaseDate < @DateTo
group by
  s.SoftwareID
其基本思想是:为什么在分组后过滤日期,而在分组前可以防止不需要的记录进入结果


您正在s.SoftwareID上分组。对我来说,似乎没有办法让MINs.ReleaseDate>=。。。将影响不同于s.ReleaseDate>=..

的记录,谢谢大家的建议。这个问题似乎已经基本解决了,我想没有太多的事情要做了

查询顾问建议了两个有用的索引,其中一个类似于:

CREATE NONCLUSTERED INDEX [IX_Release_1234] ON [dbo].[Release] 
(
    [ReleaseType] ASC,
    [SoftwareID] ASC
)
INCLUDE ( [ReleaseDate]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
索引调整将执行时间缩短到50%以下。然而,在之前减半的时间中,另一个略微改进25-30%是重新组织查询,首先从发布表中获取发布日期,然后将此子查询与软件连接:

select s.SoftwareID, r.ReleaseDate
from Software s inner join (
    select   SoftwareID, min(ReleaseDate) as ReleaseDate
    from     Release
    where    ReleaseType = 'MAJ'
    group by SoftwareID
    having
        min(ReleaseDate) >= @DateFrom
        and min(ReleaseDate) < @DateTo
) r on (
    s.SoftwareID = r.SoftwareID
)
where
    s.CategoryID = @Category
现在我想应该重新调整索引:


总之,请尽可能使用engine tuning advisor,再次感谢大家。

+1建议使用最可能的cullprit,但我认为在ReleaseDate上使用聚集索引没有意义。where子句中的按ReleaseDate筛选会将误报带入结果集。最明显的例子是:间隔设置为一个月,软件在前一个月发布了第一个主要版本。。。?我不知道为什么在软件表中有一个发布日期。查询中有一个错误,只是修复了它。Tomalak,我不是在寻找给定时间间隔的第一个主要版本,而是寻找最早的主要版本落入该时间间隔的软件。比利在下面的评论中详细说明了这一点。我认为having子句必须保留,除非我完全遗漏了一些重要的东西…@Sorin:看看Tomalak的解决方案:他在筛选/分组顺序方面有一个很好的观点。假设你有日期D1和D2,并且:软件S1-主要发布:R1,R2在[D1,D2,R3在[D1,D2,R4,等]S2-主要发布:R1在[D1,D2,R2在][D1、D2、R3、R4等,您希望得到什么样的结果?-S1-R2和S2-R1早期主要版本间隔-或仅S2-R1首次主要版本间隔只是检查格式化功能,很快就会回来…我想我必须编辑上述响应以获得更好的格式化:看起来html格式化在注释中不起作用,是吗上面的我真是一团糟:-