Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 根据当天和明天进行多种排序(公交车行程)_Mysql_Sql_Database - Fatal编程技术网

Mysql 根据当天和明天进行多种排序(公交车行程)

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次,因为巴士日很快就要结束了。为了解决这个问题,我想在这里加

我被困在一个巨大的问题上,我将用下面的问题来回答。这里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中执行多个查询,所以我希望在一个查询中执行这一操作,不管发生什么

        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