#mysql #coalesce
#MySQL #coalesce
Вопрос:
У меня есть запрос MySQL, который использует COALESCE для возврата к нулевым значениям и присваивает этим нулевым значениям первое ненулевое значение, которое он находит.
Запуск этого запроса из PHP-скрипта с использованием устаревшей функции mysql_query, а также с использованием mysqli и вызова самой хранимой процедуры, строки не затрагиваются; однако, если я запускаю запрос вручную или вызываю хранимую процедуру для него вручную, строки обновляются должным образом, создавая желаемый набор результатов.
DDL:
CREATE TABLE IF NOT EXISTS `file_index` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`file_id` int(10) unsigned NOT NULL,
`page` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`made` datetime DEFAULT NULL,
`current` tinyint(3) unsigned DEFAULT '1',
`code` char(5) NOT NULL,
`idnumber` int(10) unsigned DEFAULT NULL,
`deconstructed` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `file_id` (`file_id`,`page`),
KEY `user_id` (`user_id`),
KEY `idnumber` (`idnumber`)
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED;
INSERT INTO `file_index` (`id`, `file_id`, `page`, `user_id`, `made`, `current`, `code`, `idnumber`, `deconstructed`) VALUES
(2, 637847, 2, 473, '2014-06-23 00:00:00', 1, 'INIT', 1737929, 0),
(3, 637847, 3, 473, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
(4, 637847, 4, 473, '2014-06-23 00:00:00', 1, 'INIT', 85956, 0),
(5, 637847, 5, 473, '2014-06-23 00:00:00', 1, 'INIT', 163262, 0),
(6, 637847, 6, 473, '2014-06-23 00:00:00', 1, 'INIT', 1171457, 0),
(7, 637847, 7, 473, '2014-06-23 00:00:00', 1, 'INIT', 1173838, 0),
(8, 637847, 8, 473, '2014-06-23 00:00:00', 1, 'INIT', 2264105, 0),
(9, 637847, 9, 473, '2014-06-23 00:00:00', 1, 'INIT', 2084006, 0),
(10, 637847, 10, 473, '2014-06-23 00:00:00', 1, 'INIT', 1298597, 0),
(11, 637847, 11, 473, '2014-06-23 00:00:00', 1, 'INIT', 2263042, 0),
(12, 637847, 12, 473, '2014-06-23 00:00:00', 1, 'INIT', 1288872, 0),
(13, 637847, 13, 473, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
(15, 637845, 2, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264143, 0),
(16, 637845, 3, 79, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
(17, 637845, 4, 79, '2014-06-23 00:00:00', 1, 'INIT', 2019138, 0),
(18, 637845, 5, 79, '2014-06-23 00:00:00', 1, 'INIT', 157726, 0),
(19, 637845, 6, 79, '2014-06-23 00:00:00', 1, 'INIT', 2087837, 0),
(22, 637845, 9, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264118, 0),
(23, 637845, 10, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264124, 0),
(24, 637845, 11, 79, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0);
Ссылка на SQLFiddle: http://sqlfiddle.com /#!2/6e79d
Запрос:
UPDATE file_index
SET idnumber = (@n := COALESCE(idnumber, @n))
ORDER BY file_id, page ASC
Текущий набор результатов:
---------- ------ ----------
| file_id | page | idnumber |
---------- ------ ----------
| 637847 | 2 | 1737929 |
| 637847 | 3 | NULL |
| 637847 | 4 | 85956 |
| 637847 | 5 | 163262 |
| 637847 | 6 | 1171457 |
| 637847 | 7 | 1173838 |
| 637847 | 8 | 2264105 |
| 637847 | 9 | 2084006 |
| 637847 | 10 | 1298597 |
| 637847 | 11 | 2263042 |
| 637847 | 12 | 1288872 |
| 637847 | 13 | NULL |
| 637845 | 2 | 2264143 |
| 637845 | 3 | NULL |
| 637845 | 4 | 2019138 |
| 637845 | 5 | 157726 |
| 637845 | 6 | 2087837 |
| 637845 | 9 | 2264118 |
| 637845 | 10 | 2264124 |
| 637845 | 11 | NULL |
---------- ------ ----------
Желаемый набор результатов:
---------- ------ ----------
| file_id | page | idnumber |
---------- ------ ----------
| 637847 | 2 | 1737929 |
| 637847 | 3 | 1737929 |
| 637847 | 4 | 85956 |
| 637847 | 5 | 163262 |
| 637847 | 6 | 1171457 |
| 637847 | 7 | 1173838 |
| 637847 | 8 | 2264105 |
| 637847 | 9 | 2084006 |
| 637847 | 10 | 1298597 |
| 637847 | 11 | 2263042 |
| 637847 | 12 | 1288872 |
| 637847 | 13 | 1288872 |
| 637845 | 2 | 2264143 |
| 637845 | 3 | 2264143 |
| 637845 | 4 | 2019138 |
| 637845 | 5 | 157726 |
| 637845 | 6 | 2087837 |
| 637845 | 9 | 2264118 |
| 637845 | 10 | 2264124 |
| 637845 | 11 | 2264124 |
---------- ------ ----------
Комментарии:
1. Обновлено на основе предложений.
2. Я не уверен в формальном определении, но здесь я думаю, что «DDL» означает инструкции CREATE И INSERT .
3. Обновлено с помощью инструкции INSERT.
4. Извините, но, учитывая, что ваша проблема касается только столбцов
idnumber
,file_id
, иpage
у меня возникнет соблазн свести эту скрипку только к соответствующей информации.
Ответ №1:
По какой-то причине я должен выполнить запрос дважды, чтобы он вступил в силу и обновил строки. Странно, да, но он работает, если я запускаю его дважды.
Комментарии:
1. Я поиграл с вашей sql-скрипкой. Действительно, похоже, что это работает, если вы выполняете запрос дважды. Однако, похоже, это связано с тем, что во 2-й раз переменная @n была инициализирована (первым запросом). Если
SET @n:=0;
это сделано до обновления, оно также работает.