Mysql 根据当天和明天进行多种排序(公交车行程)
我被困在一个巨大的问题上,我将用下面的问题来回答。这里j5代表星期五,j6代表星期六1到7。。。星期天到星期一 正如你所知道的,公共汽车有不同的时间表取决于一周的时间。在这里,我将在cal j5的25:00:00之后和/或cal 2 j6的01:00:00之后乘坐接下来的5次航班。公交车时刻表如下所示: 如果是凌晨1点,那么当前的公交车时间是25点,凌晨2点是26点。。。你明白了。所以,如果我想在今天凌晨1点后出发,我可能只会得到2-3次,因为巴士日很快就要结束了。为了解决这个问题,我想在这里加上第二天的下一个出发时间是星期六,星期五之后。但第二天,像我们世界上的每一天一样,从00点开始 所以我想做的是:在25:00:00之后获得周五j5的所有后续行程。如果我没有5个,那么从25:00:00=01:00:00开始,在01:00:00之后获得星期六的所有n行程出发 例如: 我周五的出发时间是25:16:00、25:46:00和26:16:00。现在是3点。然后我想第二天再去两次,所以最后我得到5次,就像这样04:50:00和05:15:00。 所以下一次从X站出发的行程是:25:16:00friday,25:46:00friday,26:16:00friday,04:50:00周六,05:15:00周六 我无法对trips.trip\u出发的两个结果进行排序 我知道这可能很复杂,我很难解释,但是。。。无论如何有问题,我在这里。提前多谢 PS:使用MySQL 5.1.49和PHP5.3.8 PS2:我希望避免在PHP中执行多个查询,所以我希望在一个查询中执行这一操作,不管发生什么Mysql 根据当天和明天进行多种排序(公交车行程),mysql,sql,database,Mysql,Sql,Database,我被困在一个巨大的问题上,我将用下面的问题来回答。这里j5代表星期五,j6代表星期六1到7。。。星期天到星期一 正如你所知道的,公共汽车有不同的时间表取决于一周的时间。在这里,我将在cal j5的25:00:00之后和/或cal 2 j6的01:00:00之后乘坐接下来的5次航班。公交车时刻表如下所示: 如果是凌晨1点,那么当前的公交车时间是25点,凌晨2点是26点。。。你明白了。所以,如果我想在今天凌晨1点后出发,我可能只会得到2-3次,因为巴士日很快就要结束了。为了解决这个问题,我想在这里加
SELECT
trips.trip_departure,
trips.trip_arrival,
trips.trip_total_time,
trips.trip_direction
FROM
trips,
trips_assoc,
(
SELECT calendar_regular.cal_regular_id
FROM calendar_regular
WHERE calendar_regular.j5 = 1
) as cal,
(
SELECT calendar_regular.cal_regular_id
FROM calendar_regular
WHERE calendar_regular.j6 = 1
) as cal2
WHERE
trips.trip_id = trips_assoc.trip_id
AND
trips.route_id IN (109)
AND
trips.trip_direction IN (0)
AND
trips.trip_period_start <= "2011-11-25"
AND
trips.trip_period_end >= "2011-11-25"
AND
(
(
cal.cal_regular_id = trips_assoc.calendar_id
AND
trips.trip_departure >= "25:00:00"
)
OR
(
cal2.cal_regular_id = trips_assoc.calendar_id
AND
trips.trip_departure >= "01:00:00"
)
)
ORDER BY
trips.trip_departure ASC
LIMIT
5
数据:
cal_regular_id j1 j2 j3 j4 j5 j6 j7
1 0 0 0 0 1 0 0
2 0 0 0 1 1 0 0
3 1 1 1 1 1 0 0
4 0 0 0 0 0 1 0
5 0 0 0 0 0 0 1
有些公共汽车在x天内可用。这是一个定义一周中的时间的表格。。。分配给行程表
行程表
trips_assoc表
我认为X-Zero建议是最好的解决方案,但我有空闲时间:请看下面,我使用concat作为时间戳进行处理,然后由这两列进行排序。我写的freehand可能是错误的,我使用了exists,在某个地方我读取它的速度比join快,但您可以只使用concat和order部分查询
SELECT
trips.trip_departure,
trips.trip_arrival,
trips.trip_total_time,
trips.trip_direction,
CONCAT(trips.trip_period_start,' ',trips.trip_departure) as start,
CONCAT(trips.trip_period_end,' ',trips.trip_departure) as end,
FROM trips
WHERE EXISTS
(
SELECT
trips_assoc.calendar_id
FROM
trips_assoc
WHERE
trips.trip_id = trips_assoc.trip_id
AND EXISTS
(
SELECT
calendar_regular.cal_regular_id
FROM
calendar_regular
WHERE
cal2.cal_regular_id = trips_assoc.calendar_id
AND
(
calendar_regular.j5 = 1
OR
calendar_regular.j6 = 1
)
)
)
AND
trips.route_id IN (109)
AND
trips.trip_direction IN (0)
AND
trips.trip_period_start <= "2011-11-25"
AND
trips.trip_period_end >= "2011-11-25"
AND
(
trips.trip_departure >= "25:00:00"
OR
trips.trip_departure >= "01:00:00"
)
ORDER BY
TIMESTAMP(start) ASC,TIMESTAMP(end) ASC
LIMIT
5
编辑:复制/粘贴问题已更正首先,切勿让外部实体指定非唯一联接列。它们可能通过授权/身份验证指定唯一的值,如确定的GUID值。否则,它们会在某个地方口述一个自然键,数据库会自动为加入指定行ID。此外,除非您处理大量未索引行上的几十个连接,否则性能将远不如在其他地方处理它所带来的麻烦
所以,从外观上看,你正在存储来自多家公司的公交时刻表,这是谷歌在获取公共交通方向时必须做的事情,是的。
以下是我将如何处理这个问题:
你需要一个新的。这对所有业务场景都很有用,但在这里非常有用注意:不要在其中放置任何与路由相关的信息
修改代理表以控制联接键。代理机构不能指定他们的ID,只能指定他们的名字或类似的标识符。类似于以下内容的内容就足够了:
agency
=============
id - identity, incrementing
name - Externally specified name, unique
修改路由表以控制连接键。代理机构应该只能指定其潜在的非唯一自然密钥,因此我们需要用于联接的代理密钥:
route
==============
id - identity, incrementing
agency_id - fk reference to agency.id
route_identifier - natural key specified by agency, potentially non-unique.
- required unique per agency_id, however (or include variation for unique)
route_variation - some agencies use the same routes for both directions, but they're still different.
route_status_id - fk reference to route_status.id (potential attribute, debatable)
请注意,路线表不应实际列出路线上的站点-它的唯一目的是控制哪个机构有哪些路线
创建位置或地址表。这将使您受益匪浅,因为大多数公交公司倾向于在同一地点铺设多条路线:
location
=============
id - identity, incrementing
address - there are multiple ways to represent addresses in a database.
- if nothing else, seperating the fields should suffice
lat/long - please store these properly, not as a single column.
- two floats/doubles will suffice, although there are some dedicated solutions.
此时,处理路线上的站点有两个选项:
定义停止表,并列出所有停止。大概是这样的:
stop
================
id - identity, incrementing
route_id - fk reference to route.id
location_id - fk reference to location.id
departure - Timestamp (date and time) when the route leaves the stop.
这当然会很快变大,但会使处理假日日程变得容易
定义明细表集和明细表替代表集:
schedule
===================
id - identity, incrementing
route_id - fk reference to route.id
start_date - date schedule goes into effect.
schedule_stop
===================
schedule_id - fk reference to schedule.id
location_id - fk reference to location.id
departure - Time (time only) when the route leaves the stop
dayOfWeek - equivalent to whatever is in calendar.nameOfDay
- This does not have to be an id, so long as they match
schedule_override
===================
id - identity, incrementing
route_id - fk reference to route.id
effective_date - date override is in effect. Should be listed in the calendar file.
reason_id - why there's an override in effect.
schedule_override_stop
===========================
schedule_override_id - fk reference to schedule_override.id
location_id - fk reference to location.id
departure - time (time only) when the route leaves the stop
有了这些信息,我现在可以获得我需要的信息:
SELECT
FROM agency as a
JOIN route as b
ON b.agency_id = a.id
AND b.route_identifier = :(whatever 109 equates to)
AND b.route_variation = :(whatever 0 equates to)
JOIN (SELECT COALESCE(d.route_id, j.route_id) as route_id,
COALESCE(e.location_id, j.location_id) as location_id,
COALESCE(TIMESTAMP(c.date, e.departure),
TIMESTAMP(c.date, j.departure)) as departure_timestamp
FROM calendar as c
LEFT JOIN (schedule_override as d
JOIN schedule_override_stop as e
ON e.schedule_override_id = d.id)
ON d.effective_date = c.date
LEFT JOIN (SELECT f.route_id, f.start_date
g.dayOfWeek, g.departure, g.location_id,
(SELECT MIN(h.start_date)
FROM schedule as h
WHERE h.route_id = f.route_id
AND h.start_date > f.start_date) as end_date
FROM schedule as f
JOIN schedule_stop as g
ON g.schedule_id = f.id) as j
ON j.start_date <= c.date
AND j.end_date > c.date
AND j.dayOfWeek = c.dayOfWeek
WHERE c.date >= :startDate
AND c.date < :endDate) as k
ON k.route_id = b.id
AND k.departure_timestamp >= :leaveAfter
JOIN location as m
ON m.id = k.location_id
AND m.(location inforation) = :(input location information)
ORDER BY k.departure_timestamp ASC
LIMIT 5
这将给出从指定位置出发、在startDate和endDate之间、在leaveAfter时间戳之后、针对给定路线、从startDate和endDate exclusive之间的所有出发的列表。语句等价物在DB2上运行。它接收对日程安排的更改、假期覆盖等。一些表格布局指示在这里会很有帮助。。。尤其是日历?为什么要列出两次?为什么不使用或条件如果该表包含某种日期列,您应该能够将其添加到ORDERBY子句中。哦,在FROM子句中使用隐式连接语法多个表被认为是不好的做法,请改用显式连接。我不知道这是。。。我认为像这样参与进来比较容易。谢谢你的建议!我用还是两天都要?我是
在这里很迷路,真的…:/您是否有权更改数据库,或者您是否被困于此?可能有更好的设计可用,这取决于您尝试如何使用此设计。旅行的开始和结束是怎么回事?如果它们是出发和到达时间的日期,你为什么不使用时间戳呢。一个关于样本数据和旅行用途的想法会很好。你也有一个标准化问题——机构id被提交了两次,这是故意的吗?它们似乎有两种不同的数据类型,这可能是个问题。我拥有corse的所有权限,我可以创建一个新的设计。行程周期开始和结束是指从何时到行程良好的时间段。每个机构每2或3个月更改一次日期。这些日期不是来自trips信息,而是一般情况下。关于代理身份证,是的。即使不应该这样做,也有可能trip\u id中的散列与另一个类似,因为我必须给它们都提供一个代理id。此外,有时我从trips表中请求数据而不进入trips\u assoc,通常是为了避免加入。从10月1日到12月31日,这将不起作用,因为它不是旅行的时间戳,而是所有旅行的时间戳。就像10月1日到12月31日这样的有效期。。。等等,谢谢,很好的尝试
stop
================
id - identity, incrementing
route_id - fk reference to route.id
location_id - fk reference to location.id
departure - Timestamp (date and time) when the route leaves the stop.
schedule
===================
id - identity, incrementing
route_id - fk reference to route.id
start_date - date schedule goes into effect.
schedule_stop
===================
schedule_id - fk reference to schedule.id
location_id - fk reference to location.id
departure - Time (time only) when the route leaves the stop
dayOfWeek - equivalent to whatever is in calendar.nameOfDay
- This does not have to be an id, so long as they match
schedule_override
===================
id - identity, incrementing
route_id - fk reference to route.id
effective_date - date override is in effect. Should be listed in the calendar file.
reason_id - why there's an override in effect.
schedule_override_stop
===========================
schedule_override_id - fk reference to schedule_override.id
location_id - fk reference to location.id
departure - time (time only) when the route leaves the stop
SELECT
FROM agency as a
JOIN route as b
ON b.agency_id = a.id
AND b.route_identifier = :(whatever 109 equates to)
AND b.route_variation = :(whatever 0 equates to)
JOIN (SELECT COALESCE(d.route_id, j.route_id) as route_id,
COALESCE(e.location_id, j.location_id) as location_id,
COALESCE(TIMESTAMP(c.date, e.departure),
TIMESTAMP(c.date, j.departure)) as departure_timestamp
FROM calendar as c
LEFT JOIN (schedule_override as d
JOIN schedule_override_stop as e
ON e.schedule_override_id = d.id)
ON d.effective_date = c.date
LEFT JOIN (SELECT f.route_id, f.start_date
g.dayOfWeek, g.departure, g.location_id,
(SELECT MIN(h.start_date)
FROM schedule as h
WHERE h.route_id = f.route_id
AND h.start_date > f.start_date) as end_date
FROM schedule as f
JOIN schedule_stop as g
ON g.schedule_id = f.id) as j
ON j.start_date <= c.date
AND j.end_date > c.date
AND j.dayOfWeek = c.dayOfWeek
WHERE c.date >= :startDate
AND c.date < :endDate) as k
ON k.route_id = b.id
AND k.departure_timestamp >= :leaveAfter
JOIN location as m
ON m.id = k.location_id
AND m.(location inforation) = :(input location information)
ORDER BY k.departure_timestamp ASC
LIMIT 5