我在Mysql 5.7中遇到了一个非常奇怪的行为。它不会发生在5.6或8.0上,只有5.7。
SELECT
r.identificador, rh.id_reserva_habitacion, h.id_habitacion,
(SELECT identificador FROM reservas WHERE identificador LIKE CONCAT(r.identificador, '.%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh, `habitaciones` h)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador AND h.id_habitacion = rh.id_habitacion
GROUP BY
rh.id_reserva_habitacion
这是测试它的最小转储:
CREATE TABLE IF NOT EXISTS `habitaciones` (
`id_habitacion` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_hotel` int(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id_habitacion`)
) ENGINE=MyISAM AUTO_INCREMENT=4474 DEFAULT CHARSET=utf8;
INSERT INTO `habitaciones` (`id_habitacion`, `id_hotel`) VALUES
(1, 200),
(2, 200);
CREATE TABLE IF NOT EXISTS `reservas` (
`identificador` varchar(13) NOT NULL DEFAULT '',
`timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`identificador`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `reservas` (`identificador`, `timestamp`) VALUES
('XXA', '2020-01-02'),
('XXA.01', '2020-01-01'),
('XXB', '2020-01-01');
CREATE TABLE IF NOT EXISTS `reservas_habitaciones` (
`id_reserva_habitacion` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`identificador` varchar(13) NOT NULL DEFAULT '',
`id_habitacion` int(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id_reserva_habitacion`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO `reservas_habitaciones` (`id_reserva_habitacion`, `identificador`, `id_habitacion`) VALUES
(1, 'XXA', 1),
(2, 'XXB', 1),
(3, 'XXB', 2);
查询应在
modificada
字段,但返回空值。
如果我把
GROUP BY
SELECT
r.identificador, rh.id_reserva_habitacion, h.id_habitacion,
(SELECT identificador FROM reservas WHERE identificador LIKE CONCAT(r.identificador, '.%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh, `habitaciones` h)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador AND h.id_habitacion = rh.id_habitacion
如果我把
habitaciones
从查询表,它工作。
SELECT
r.identificador, rh.id_reserva_habitacion,
(SELECT identificador FROM reservas WHERE identificador LIKE CONCAT(r.identificador, '.%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador
GROUP BY
rh.id_reserva_habitacion
如果“XXA.01”的值改为“XXA_01”(在查询中为“%”),则可以工作`
SELECT
r.identificador, rh.id_reserva_habitacion, h.id_habitacion,
(SELECT identificador FROM reservas WHERE identificador LIKE CONCAT(r.identificador, '_%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh, `habitaciones` h)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador AND h.id_habitacion = rh.id_habitacion
GROUP BY
rh.id_reserva_habitacion
如果不是
CONCAT(r.identificador, '.%')
是的
CONCAT('XXA', '.%')
,它起作用了。
SELECT
r.identificador, rh.id_reserva_habitacion, h.id_habitacion,
(SELECT identificador FROM reservas WHERE identificador LIKE CONCAT('XXA', '.%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh, `habitaciones` h)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador AND h.id_habitacion = rh.id_habitacion
GROUP BY
rh.id_reserva_habitacion
SELECT
r.identificador, rh.id_reserva_habitacion, h.id_habitacion,
(SELECT identificador FROM reservas WHERE identificador COLLATE utf8_general_ci LIKE CONCAT(r.identificador, '.%') LIMIT 1) AS modificada
FROM
(`reservas` r, `reservas_habitaciones` rh, `habitaciones` h)
WHERE
r.identificador = 'XXA' AND r.identificador = rh.identificador AND h.id_habitacion = rh.id_habitacion
GROUP BY
rh.id_reserva_habitacion
如果我删除中的第二个记录
住所
只留下id“1”,它也可以工作。
如果我在5.6或8.0中使用它,它就可以完美地工作(事实上,它一直在5.6上工作,没有问题)
但目前,我不能接受任何这些解决方案。很明显,查询和数据比这个例子要大,我不想碰这些。
我认为这与排序规则或字符集以及'XXA.01'中的点有关,但我不理解查询中的表或行数如何影响它。
我想知道这是关于服务器配置、表、字段、字符集,还是一个bug。
谢谢!