1

我的数据库中有一个事件表,每个事件最多可以有 5 个不同的日期。表中的 Date1 总是在 date2 之前,date2 在 date3 之前等等。

给定搜索表单中的 2 个日期,我试图找到它们之间的事件。

我的表设计如下:

id | name  | date1     | date2      | date3     | date4     | date5
1  | test1 | 2013-05-24| 2013-05-25 | 0000-00-00| 0000-00-00| 0000-00-00
2  | test2 | 2013-06-01| 2013-06-08 | 2013-06-15| 2013-06-23| 2013-06-30
3  | test3 | 2013-03-15| 0000-00-00 | 0000-00-00| 0000-00-00| 0000-00-00

$datefrom , $dateto 是搜索表单中的两个变量。例如,现在 $datefrom 将始终在表的 date1 中搜索。但是 $dateto 必须在 date5 中搜索,如果它为 null 到 date4 等等。

到目前为止,我想出的最好的查询是:

SELECT * FROM events 
WHERE 
IF(date1 != '0000-00-00', IF(date1>='2012-12-19', 1, 0),0) = 1 
AND CASE 
WHEN date5!='0000-00-00' THEN IF(date5<='2012-12-31', 1, 0)     
WHEN date4!='0000-00-00' THEN IF(date4<='2012-12-31', 1, 0)     
WHEN date3!='0000-00-00' THEN IF(date3<='2012-12-31', 1, 0) 
WHEN date2!='0000-00-00' THEN IF(date2<='2012-12-31', 1, 0) 
END 

但它运行得不是很好,例如这个查询返回最旧日期为 2013 年的行。我不知道 CASE 是否是正确的开始方法。有任何想法吗??谢谢你的时间!

4

2 回答 2

2

你可以这么简单地使用它GREATEST

SELECT name , date1 date_start, GREATEST(date2,date3,date4,date5) date_end
FROM events

并会像这样输出

 NAME   DATE_START  DATE_END
 jack   2013-05-24  2013-05-25
 peter  2013-06-01  2013-06-30

这里是演示 SQLFIDDLE

于 2012-12-22T16:55:12.580 回答
0

试试这个:

SELECT 
  id, 
  name
FROM
(
    SELECT 
      id, 
      name, 
      MIN(EventDate) AS "FromDate",
      MAX(EventDate) AS "ToDate"
    FROM
    (
      SELECT id, name, date1 As "EventDate" FROM events
      UNION ALL
      SELECT id, name, date2                FROM events
      UNION ALL
      SELECT id, name, date3                FROM events
      UNION ALL
      SELECT id, name, date4                FROM events
      UNION ALL
      SELECT id, name, date5                FROM events
    ) t 
    GROUP BY id, name
) t
WHERE FromDate > @fromdate
  AND ToDate   < @todate;

SQL 小提琴演示

但是,如果您想以与事件表中相同的方式获取数据,您可以这样做:

SELECT 
  e.*
FROM
(
    SELECT 
      id, 
      name, 
      MIN(EventDate) AS "FromDate",
      MAX(EventDate) AS "ToDate"
    FROM
    (
      SELECT id, name, date1 As "EventDate" FROM events
      UNION ALL
      SELECT id, name, date2                FROM events
      UNION ALL
      SELECT id, name, date3                FROM events
      UNION ALL
      SELECT id, name, date4                FROM events
      UNION ALL
      SELECT id, name, date5                FROM events
    ) t 
    GROUP BY id, name
) t
INNER JOIN events e ON t.id = e.id
WHERE t.FromDate > @fromdate
  AND t.ToDate   < @todate;

例如,对于@fromdate = '2012-05-01'and @todate = '2012-06-15',这将为您提供:

| ID |  NAME |                      DATE1 |                      DATE2 |  DATE3 |  DATE4 |  DATE5 |
---------------------------------------------------------------------------------------------------
|  1 | test1 | May, 24 2013 00:00:00+0000 | May, 25 2013 00:00:00+0000 | (null) | (null) | (null) |
于 2012-12-22T16:09:29.857 回答