【问题标题】:How to write search query in sql server如何在sql server中编写搜索查询
【发布时间】:2014-07-31 10:19:47
【问题描述】:

我的事件表包含 starteventdate 和 endevent 日期。

         Id  EventName starteventdate endevent
        ---------------------------------------
         1    a        7/6/2014       8/6/2014
         2    b        9/6/2014       10/6/2014
         3    c        10/6/2014      15/6/2014
    
    

我的搜索屏幕有 fromdate 和 todate。所以我想搜索这些事件处于活动状态的两个日期之间的事件。

我正在搜索 2014 年 7 月 6 日至 2014 年 10 月 6 日之间的事件结果 -->1,2,3。

如果我正在搜索 10/6/2014-12/6/2014 结果之间的事件 -->2,3.

如果我正在搜索 2013 年 8 月 6 日至 2014 年 20 月 6 日之间的事件结果-->1,2,3

我试过这个查询。但我只能搜索一个日期,比如

SELECT e.EventsID,e.EventDesc AS 'Event Description' 
FROM dEvents e  
WHERE convert(datetime,convert(varchar(10),StartEvent,101),101) 
   BETWEEN 
       convert(datetime,convert(varchar(10),@FromDate,101),101) 
   AND
       convert(datetime,convert(varchar(10),@ToDate,101),101).

所以我只想要黑白搜索日期的活动事件。请整理一下。

【问题讨论】:

  • starteventdate/end event/@FromDate/@ToDatedate 是类型吗?如果没有,为什么不呢,你能先解决这个问题吗?

标签: sql sql-server


【解决方案1】:

假设您有 DATETIME 类型可以使用,而不是字符串,我会做这样的事情。不过,如果有必要,您应该可以将 CONVERTs 放回原处。

SELECT e.EventsID, e.EventDesc AS 'Event Description' 
  FROM dEvents e 
 WHERE EndEvent >= @FromDate
   AND StartEvent <= @ToDate

【讨论】:

    【解决方案2】:

    请试试这个。观察,你正在存储 dd/mm/yyyy 所以使用 103 进行转换

    样本数据:

    IF OBJECT_ID(N'dEvents')>0
    BEGIN
        DROP TABLE dEvents
    END
    
    CREATE TABLE dEvents (Id INT,EventName VARCHAR(10),StartEvent VARCHAR(20),endevent VARCHAR(20))
    
    INSERT INTO dEvents VALUES
    ('1','a','7/6/2014','8/6/2014'),
    ('2','b','9/6/2014','10/6/2014'),
    ('3','c','10/6/2014','15/6/2014')
    

    查询:

    DECLARE @FromDate VARCHAR(20) = '7/6/2014'
    DECLARE @ToDate VARCHAR(20) = '10/6/2014'
    
    SELECT e.ID,e.EventName AS 'Event Description' 
    FROM dEvents e  
    WHERE CONVERT(DATE,StartEvent,103) BETWEEN CONVERT(DATE,@FromDate,103) AND CONVERT(DATE,@ToDate,103)
    OR CONVERT(DATE,endevent,103) BETWEEN CONVERT(DATE,@FromDate,103) AND CONVERT(DATE,@ToDate,103)
    

    清理:

    IF OBJECT_ID(N'dEvents')>0
    BEGIN
        DROP TABLE dEvents
    END
    

    【讨论】:

    • 请注意,此查询将错过在参数之前开始并在参数之后结束的事件。关于日期比较,我建议使用 Mark 的方法。
    • @Kahn 你为什么认为查询会错过事件。请您详细说明,以便我纠正任何逻辑缺陷。
    • 啊,抱歉。我试着在那里说。 :) 我的意思是,当一个事件在 FromDate 之前开始并在 ToDate 之后结束时,那么在 FromDate 和 ToDate 之间都不会找到任何值。马克在他的回答中正确地回答了这一点,当他进行比较时:StartEvent = FromDate.
    • 举个例子,在这里看这个小提琴:sqlfiddle.com/#!3/19307/1/0我使用了你的回复,并在 dEvents 表中添加了一个新的注释行。这不会出现,即使它应该出现。 :)
    • 好的,我想我理解你的担心了,Between 也包括值。所以 a 和 b 之间的值与 Value >= a 和
    【解决方案3】:

    不确定我是否理解问题。

    所以你有两个参数:@FromDate 和@ToDate。并且您想返回 dEvents 表中的所有行,其中事件在这两个参数日期之间的时间内处于活动状态?

    您似乎在那里进行了很多转换,您不是在处理日期或日期时间数据类型吗?

    然后试试这个:

    SELECT DISTINCT e.EventsID,e.EventDesc AS 'Event Description' 
    from dEvents e  
    WHERE @FromDate BETWEEN starteventdate AND endevent 
    OR @ToDate BETWEEN starteventdate AND endevent
    OR (@FromDate < starteventdate AND @ToDate > endevent)
    

    【讨论】:

    • OR 的效率将低于使用 AND 的查询。
    • 只有一点点,因为它不用于复杂的计算或 JOIN 逻辑。但你是对的,马克的逻辑在这里要好得多。我的大脑似乎从来没有得到这些范围比较公式。 :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    相关资源
    最近更新 更多