У меня очень странное поведение в 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);
Запрос должен возвращать значение «XXA.01» в поле modificada
, но возвращает NULL.
А теперь странные части:
- Если я просто удалю
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
- Если я удаляю вторую запись в
habitaciones
, оставляя только идентификатор "1", это также работает. - Если я делаю это в 5.6 или 8.0, он отлично работает (на самом деле, он работает на 5.6 без проблем)
Но на данный момент я не могу принять ни одно из эти решения. Очевидно, что запрос и данные больше, чем в этом примере, и я бы предпочел не касаться ни одного из них.
Я думаю, что это как-то связано с сопоставлениями или кодировками, а точка в 'XXA.01' , но я не понимаю, как таблицы в запросе или количество строк могут повлиять на это.
Я хотел бы знать, касается ли это конфигурации сервера, таблиц, полей, кодировок или, возможно, ошибки .
Спасибо!