![]() |
1
2
|
![]() |
2
5
我知道你正在寻找一种方法来选择11月相交的所有范围, 在任何一年 . 逻辑如下:
翻译成伪代码,条件是:
|
![]() |
3
1
试试这个: select * from Mytable where month(StartDate) = @MonthCode or month(EndDate) = @MonthCode // Nov/15/2009 - Nov/15/2009 or dateadd(month,@MonthCode-1,convert(datetime,convert(varchar,year(StartDate)))) between StartDate and EndDate // Oct/01/2010 - Dec/31/2010 or dateadd(month,@MonthCode-1,convert(datetime,convert(varchar,year(EndDate)))) between StartDate and EndDate // Dec/01/2009 - Dec/31/2010 - tricky one 主IDEEA将检查01.11.StartYear和01.11.EndYear日期所在的位置。 希望它有帮助。 |
![]() |
4
0
筛选在月底之前开始,在月初之后结束的行。2009年10月:
或者,只输入月份:
|
![]() |
5
0
您可以使用各种功能来实现这一点,例如 DATEPART 和 DATETIFF . 然而,真正的问题不是如何表达给定月份的开始日期或结束日期的条件,而是如何以一种使查询高效的方式来实现这一点。换句话说,如何用一种可裁剪的方式来表达这一点。 如果你搜索一个小的变化表,任何低于10万页,那么它不会有太大的区别,一个完整的扫描可能是完全可以接受的。真正的问题是,表的大小是否很大,完全扫描是不可接受的。 如果在StartDate或EndDate列上没有索引,则没有区别,条件不可搜索,查询将扫描整个表。但是,如果在startdate和enddate上有索引,则表示条件的方式会产生所有差异。日期时间索引的关键部分是必须将搜索表示为精确的日期范围。将条件表示为依赖于日期时间字段的函数将使条件不可搜索,从而导致完整的表扫描。因此,这些知识使自己能够正确地搜索日期范围:
这也可以表示为:
哪个查询工作得更好取决于许多因素,如表大小和表中实际数据的统计信息。 不过,你想要十一月从 任何 年份,此查询不提供。解决这个问题的方法违背了程序员的直觉:硬编码相关年份。不管怎样,大多数情况下,表格都有一小部分年份,在过去4-5年的数据范围内,并且计划在3-4年内,直到系统检修:
一年有12个月,写12个单独的程序。这听起来很疯狂吗?当然可以,但从SQL查询编译器和优化器的角度来看,这是最理想的。如何维护这样的代码?12个单独的过程,其中有一个查询本身重复10次(如果使用StartDate和EndDate之间的联合来删除或,则重复20次),120次代码重复, 必须 胡说八道。实际上,不是这样的。使用代码生成来创建过程,比如XML/XSLT,这样您就可以轻松地更改和维护它。客户是否必须了解12个程序并呼叫相应的程序?当然不是,它调用一个包装过程来区分@month参数以调用正确的包装过程。 我再次确认,任何在事实发生后关注系统的人都可能相信这个查询是由一群喝醉的猴子编写的。然而,在参数嗅探、索引可sargability和SQL日期时间怪癖之间的某个地方,其结果是,当它涉及到搜索日历间隔时,这是当今最先进的技术。 哦,如果查询命中 Index Tipping Point 不管怎样,这会使整个争论变得沉默…… 更新
顺便说一句,如果您愿意牺牲一些存储空间,还有一种廉价的方法:在
|
![]() |
6
-1
SQL Server 200/2005,还可以执行以下操作:
更新:
远离的
|
![]() |
John D · 需要为NULL或NOT NULL的WHERE子句 4 月前 |
![]() |
Marc Guillot · 记录值时忽略冲突 5 月前 |
![]() |
Fachry Dzaky · 正确使用ROW_NUMBER 5 月前 |
![]() |
TriumphTruth · 从满足特定条件的数据集中选择1行 5 月前 |