最佳实践:针对日,月或年搜索表

时间:2009-11-08 11:19:04

标签: sql sql-server

我有一个带有“日期”列的表,其中将查询用户输入(使用存储过程)..并且结果将显示在数据网格上。

现在用户可以输入年份,年/月,年/月/日..(从下拉列表中)

我知道有很多可能的方法来处理不同的查询..但是我想弄清楚哪种方法是最佳做法:

解决方案1:拥有3个不同的存储过程,每个案例一个。

解决方案2:拥有1个存储过程,使用1个额外参数作为searchlvl,然后使用IF ELSE语句来决定应该应用什么样的搜索。

解决方案3:拥有1个存储过程,并将datetime作为3个不同的参数发送,然后检查IF参数是否为null,并使用它来决定搜索lvl

解决方案4:您的建议:)

注意:我知道如何进行部分搜索(使用datepart),我的问题是关于我提供的3个解决方案中的最佳实践或答案中提供的任何其他解决方案。 喜欢哪个更快,更轻的数据库等... 哪个更慢,更重..

4 个答案:

答案 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

我不会在列或条件逻辑上使用任何函数来在选择

之间切换