Странное MySQL 5.7 поведение в LIKE CONCAT - PullRequest
0 голосов
/ 15 января 2020

У меня очень странное поведение в 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' , но я не понимаю, как таблицы в запросе или количество строк могут повлиять на это.

Я хотел бы знать, касается ли это конфигурации сервера, таблиц, полей, кодировок или, возможно, ошибки .

Спасибо!

...