使用带有select查询的mysql stored-function

时间:2014-09-12 16:44:30

标签: php mysql stored-procedures stored-functions

让我先解释一下我的目的,我有一个车辆预订申请,其中,访客将添加他的旅程的开始日期和结束日期,在数据库中有可用的驱动程序列表(available_from_date和available_to_date),这是一种在它们运行的​​持续时间内,当某些特定日期不工作时,exclude_dates有一个字段。 应用程序需要查找在用户输入的旅程日期期间可用的车辆列表。 例如,用户在2014年9月13日至2014年9月17日期间进入他想要从A到B. 然后数据库需要返回在此期间可用的出租车列表,并且在此期间内不得有任何排除日期。

现在我已经在表格中以逗号分隔格式存储了exclude_dates(我可能已经创建了一个单独的表,但是执行查询会花费更多的时间) 我试图创建一个mysql函数,该函数将在实际的搜索查询中调用,如果有一些在持续时间内存在一些排除日期,则返回true,否则返回false。

这些是我写的查询

SELECT id, exclude_dates  
FROM `taxi_route` 
WHERE  status = 1 
  AND `to_city` = 'Surat' 
  AND `from_city` = 'Ahmedabad' 
  AND `trip_type` = 2 
  AND `available_from_date` <= '2014-09-13' 
  AND available_to_date >= '2014-09-17' 
  AND STR_TO_DATE((SELECT `split`(exclude_dates, ',', 1)),'%d-%m-%Y') 
      NOT BETWEEN STR_TO_DATE('13-09-2014','%d-%m-%Y') 
              AND STR_TO_DATE('17-09-2014','%d-%m-%Y')

Split是我在mysql中创建的一个函数,用于分隔以逗号格式显示的日期

DELIMITER $$

CREATE FUNCTION split( str VARCHAR(500), delchar VARCHAR(2), x INT )
RETURNS VARCHAR(500)
BEGIN
RETURN SUBSTR(SUBSTRING_INDEX(str, delchar, x),
LENGTH(SUBSTRING_INDEX(str, delchar, x-1))+IF(x > 1, 2, 1));
END$$

DELIMITER ;

只要我在分割中传递1(exclude_dates,',',1),这个工作正常,但如果exclude_dates有多个日期,那么这将不起作用 有人可以建议或指导,如何实现这一目标。 数据库快照在http://i.imgur.com/JaI8MSx.png

1 个答案:

答案 0 :(得分:0)

您的查询很可能比为exclusion dates定义单独的表需要更多时间。在列中使用逗号分隔列表进行搜索不是一个好习惯,这违反了规范化规则。

您应该单独定义表格(例如taxi,taxi_route,taxi_route_exclusion,route_exclusion),然后添加必要的索引以提高搜索效率。

示例:

taxi
---------
id
country
***
***
***
taxi_route
-------------------
id
taxi_id
available_from_date
available_to_date
from_city
to_city
route_exclusion
---------------
id
taxi_id
exclusion_date

并在taxi_routeroute_exclusion表之间添加关系表来表示多对多关系。稍后在taxi_route_route_exclusion表上定义外键以指向taxi_routeroute_exclusion表。

taxi_route_route_exclusion
--------------------------
taxi_route_id
route_eclusion_id

定义外键,如:

  • taxi_route.taxi_id - &gt; taxi.id
  • taxi_route_route_exclusion.taxi_route_id - &gt; taxi_route.id
  • taxi_route_route_exclusion.route_exclusion_id - &gt; route_exclusion.id

定义索引,如:

  • taxi:IX1(status,trip_type)
  • taxi_route:IX1(to_city,from_city,available_from_date,available_to_date)

您的最终查询应如下所示:

SELECT tr.id, re.exclusion_date
FROM `taxi_route` tr JOIN `taxi_route_route_exclusion` trre
  ON tr.id = trre.taxi_route_id
JOIN `route_exclusion` re
  ON re.id = trre.route_exclusion_id
JOIN `taxi` t
  ON t.id = tr.id
WHERE
  t.status = 1
  AND t.trip_type = 2 
  AND tr.to_city = 'Surat' 
  AND tr.from_city = 'Ahmedabad' 
  AND tr.available_from_date <= '2014-09-13' 
  AND tr.available_to_date >= '2014-09-17'