我有一个带有“日期”列的表,其中将查询用户输入(使用存储过程)..并且结果将显示在数据网格上。
现在用户可以输入年份,年/月,年/月/日..(从下拉列表中)
我知道有很多可能的方法来处理不同的查询..但是我想弄清楚哪种方法是最佳做法:
解决方案1:拥有3个不同的存储过程,每个案例一个。
解决方案2:拥有1个存储过程,使用1个额外参数作为searchlvl,然后使用IF ELSE语句来决定应该应用什么样的搜索。
解决方案3:拥有1个存储过程,并将datetime作为3个不同的参数发送,然后检查IF参数是否为null,并使用它来决定搜索lvl
解决方案4:您的建议:)
注意:我知道如何进行部分搜索(使用datepart),我的问题是关于我提供的3个解决方案中的最佳实践或答案中提供的任何其他解决方案。 喜欢哪个更快,更轻的数据库等... 哪个更慢,更重..
答案 0 :(得分:5)
没有关卡。
当用户选择2009年时,您搜索日期> ='2009.01.01 00:00'和< '2010.01.01 00:00'。
当他选择2009年的01月时,你搜索日期> ='2009.01.01 00:00'和< '2009.02.01 00:00'。
当然,您不将日期作为字符串传递,您应该使用CONVERT()或将日期作为DATETIME类型传递。这是通用的解决方案,速度很快,因为它会使用索引。您可以创建包含两个日期的存储过程,它将允许按每个日期范围进行搜索,而不仅仅是年/月/日。
答案 1 :(得分:2)
我不会做以上任何事情。
您应该设计存储过程以采用三种不同的整数,一种用于一天,一种用于月份,一种用于一年。保留参数可为空,但建立约定,以便仅使用有意义的参数组合。然后从参数构造一个MINDATE和MAXDATE。
根据日/年/月搜索日期时间列需要以下查询:
SELECT * FROM table WHERE date > MINDATE AND date < MAXDATE
这是非常低效但不是明确的问题。
另一种方法(如果表格很大)将创建一个带有年/月/日整数列的索引视图,并在那里搜索完全匹配。要创建这样的视图,请使用DATEPART()。
答案 2 :(得分:1)
您可以使用datepart获取要过滤的日期部分
declare @table table(
DateVal DATETIME
)
INSERT INTO @table SELECT GETDATE()
DECLARE @Year INT,
@Month INT,
@Day INT
SELECT @Year = 2009
SELECT DATEPART(YY, DateVal) DateYear,
DATEPART(MM, DateVal) DateMonth,
DATEPART(DD, DateVal) DateDay,
*
FROM @table
WHERE (DATEPART(YY, DateVal) = @Year OR @Year IS NULL)
AND (DATEPART(MM, DateVal) = @Month OR @Month IS NULL)
AND (DATEPART(DD, DateVal) = @Day OR @Day IS NULL)
答案 3 :(得分:1)
我将年/月/日作为单独的参数传递到一个存储过程中,比如默认为NULL。
然后,我将使用DATEADD来构建from / to datetimes并使用
...
SELECT
@ToYear = ISNULL(@ToYear, DATEPART(year, GETDATE()), --or some base value, such as "1900"
@ToMonth = ...
...
SELECT
@DateTo = DATEADD(year, @ToYear, DATEADD(month, @ToMonth, DATEADD(day, @ToDay, 0), 0), 0)
....
SELECT * FROM myTable WHERE DateColumn >= @DateFrom AND DateColumn <= @DateTo
我不会在列或条件逻辑上使用任何函数来在选择
之间切换