Сообщение об ошибке синтаксиса MySQL " операнд должен содержать 1 столбец(ы)"

Я попытался выполнить следующее утверждение:

INSERT INTO VOUCHER (VOUCHER_NUMBER, BOOK_ID, DENOMINATION)
SELECT (a.number, b.ID, b.DENOMINATION) 
FROM temp_cheques a, BOOK b
WHERE a.number BETWEEN b.START_NUMBER AND b.START_NUMBER+b.UNITS-1;

который, как я понимаю, должен вставлять в ваучер каждую запись из temp_cheques с полями ID и деноминации, соответствующими записям в таблице BOOK (temp_cheques происходит из резервной копии базы данных, которую я пытаюсь воссоздать в другом формате). Однако, когда я запускаю его, я получаю сообщение об ошибке:

Error: Operand should contain 1 column(s)
SQLState:  21000
ErrorCode: 1241

Я запускаю это в SQuirrel и не имел проблем с любыми другими запросами. Быть там что-то не так с синтаксисом запроса?

EDIT:

структура книги:

ID  int(11)
START_NUMBER    int(11)
UNITS   int(11)
DENOMINATION    double(5,2)

структура temp_cheques:

ID  int(11)
number  varchar(20)

5 ответов


Попробуйте удалить скобки из предложения SELECT. От Microsoft TechNet, правильный синтаксис инструкции INSERT с помощью предложения SELECT следующий.

INSERT INTO MyTable  (PriKey, Description)
       SELECT ForeignKey, Description
       FROM SomeView

ошибка, которую вы получаете: "выбор будет проверять больше строк MAX_JOIN_SIZE; проверьте, где и используйте SET SQL_BIG_SELECTS=1 или SET SQL_MAX_JOIN_SIZE=#, если выбор в порядке.", на самом деле правильно, предполагая, что у вас много строк как в книге, так и в temp_cheques. Вы пытаетесь чтобы запросить все строки из обеих таблиц и сделать перекрестную ссылку, в результате чего запрос размера m*n. SQL Server пытается предупредить вас об этом перед выполнением потенциально длительной операции.

Set SQL_BIG_SELECTS = 1 перед запуском этого оператора и повторите попытку. Он должен работать, но обратите внимание, что эта операция может занять много времени.


содержит ли B столбец единиц?

какова структура таблицы для temp_cheques и Book?

EDIT: как я сказал в комментариях, все столбцы должны быть числовыми при выполнении +/- и при сравнении.
работает ли следующий простой выбор?

SELECT b.START_NUMBER+b.UNITS-1 FROM Books B


у меня нет экземпляра MySQL, но мое первое предположение-предложение WHERE:

WHERE a.number BETWEEN b.START_NUMBER AND b.START_NUMBER+b.UNITS-1;

Я предполагаю, что парсер MySQL может интерпретировать это как:

WHERE number
(BETWEEN start_number AND start_number) + units - 1

попробуйте обернуть все в скобки, т. е.:

WHERE a.number BETWEEN b.START_NUMBER AND (b.START_NUMBER + b.UNITS - 1);

окончательная версия запроса выглядит следующим образом:

Set SQL_BIG_SELECTS = 1;
INSERT INTO VOUCHER (VOUCHER_NUMBER, BOOK_ID, DENOMINATION)
SELECT a.number, b.ID, b.DENOMINATION
FROM temp_cheques a, BOOK b
WHERE a.number BETWEEN b.START_NUMBER AND (b.START_NUMBER+b.UNITS-1);

синтаксический анализ оператора BETWEEN требует скобок, SELECT не сделал, и из-за размера двух таблиц (215000 записей в temp_cheques, 8000 в книге) я нарушал ограничение на размер select, требуя от меня установить SQL_BIG_SELECTS = 1.


я столкнулся с той же ошибкой при использовании репозиториев Spring.

мой репозиторий содержал такой метод, как:

List<SomeEntity> findAllBySomeId(List<String> ids);

это отлично работает при выполнении интеграционных тестов с базой данных в памяти (h2). Однако против автономной базы данных, такой как MySql, произошел сбой с той же ошибкой.

Я решил это, изменив интерфейс метода на:

List<someEntity findBySomeIdIn(List<String> ids);

Примечание: нет никакой разницы между find и findAll. Как описано здесь: весенние данные JPA разница между findBy / findAllBy