【问题标题】:Issue with a subquery MySQL 5.5 vs 5.6子查询 MySQL 5.5 vs 5.6 的问题
【发布时间】:2023-03-19 13:11:01
【问题描述】:

我一直在 MySQL 5.5 (percona) 上运行一个网站并使用这个查询,它有效:

SELECT
    bds.FromStationPositionID
FROM
    BusDestinationSegments AS bds
LEFT JOIN BusDestinationSegmentPrices AS bdsp ON bds.SegmentID = bdsp.BusDestinationSegmentID
AND EXISTS (
    SELECT
        BusDestinationScheduleID
    FROM
        BusDestinationSchedule
    WHERE
        BusDestinationScheduleDate + INTERVAL bdssf.DayOfset DAY = '2016-01-26'
),
 BusDestinationStations AS bdssf

我需要升级到 5.6(再次是 Percona),所以我就这样做了(在开发服务器上)。 但是,此查询现在不起作用。它告诉我:

[Err] 1054 - Unknown column 'bdssf.DayOfset' in 'where clause'

我应该补充一点,我已经检查过了,并且该列在那里。

我猜从 5.5 到 5.6 有某种变化,不允许我在子查询中使用列,但我找不到关于该主题的任何内容。

有没有人有这方面的经验,或者任何人都可以提出一种我正在努力完成的工作的方法吗?

【问题讨论】:

  • 您是否尝试过仅使用BusDestinationStations.Dayofset 是否有效?
  • 它在不同的查询中工作,但在这个查询中使用它意味着表的另一个实例,这不是我想要完成的。即便如此,它也不适用于“BusDestinationStations” - 它在“where 子句”中显示未知列“BusDestinationStations.DayOfset”
  • 一旦我将它粘贴到 mysql 上,它会给我一个 sql 语法错误 SELECT bds.FromStationPositionID FROM BusDestinationSegments AS bds LEFT JOIN BusDestinationSegmentPrices AS bdsp ON bds.SegmentID = bdsp.BusDestinationSegmentID AND EXISTS ( SELECT BusDestinationScheduleID FROM BusDestinationSchedule WHERE BusDestinationScheduleDate + INTERVAL bdssf.DayOfset DAY = '2016-01-26' )(BusDestinationStations AS bdssf)
  • 尝试使用这个查询
  • 结果是一样的

标签: mysql percona


【解决方案1】:

您似乎混合使用了新旧 JOIN 语法。并期望 BusDestinationStations(这是 DayOfset 列来自的 bdssf)进行交叉连接。

这曾经有效,但 MySQL 5.6 中的更改之一是连接的优先级:-

http://dev.mysql.com/doc/refman/5.6/en/join.html:-

以前,逗号运算符 (,) 和 JOIN 都具有相同的 优先级,所以连接表达式 t1, t2 JOIN t3 被解释为 ((t1, t2) 加入 t3)。现在 JOIN 具有更高的优先级,所以表达式 被解释为 (t1, (t2 JOIN t3))。此更改会影响语句 使用 ON 子句,因为该子句只能引用列 在连接的操作数中,优先级的变化发生变化 解释这些操作数是什么。

所以我认为发生的事情是 MySQL 试图在隐式连接到 BusDestinationStations 之前执行子查询的处理,因此在执行子查询时它不知道任何关于 bdssf.DayOfset 的信息。

认为以下内容等同于您正在尝试做的事情:-

SELECT bds.FromStationPositionID
FROM BusDestinationSegments AS bds
CROSS JOIN BusDestinationStations AS bdssf
LEFT JOIN BusDestinationSegmentPrices AS bdsp ON bds.SegmentID = bdsp.BusDestinationSegmentID
AND EXISTS 
(
    SELECT BusDestinationScheduleID
    FROM BusDestinationSchedule
    WHERE BusDestinationScheduleDate + INTERVAL bdssf.DayOfset DAY = '2016-01-26'
)

(虽然我对像这样只是为了获取子查询的值而进行交叉连接有点怀疑——看起来效率很低)。

【讨论】:

  • 5.5 版本的文档中也出现了相同的声明 - 但混合新旧样式连接是一种不好的做法,我同意你关于正在发生的事情的理论
  • 谢谢,效果很好。很好的解释!
猜你喜欢
  • 2013-11-21
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多