web-dev-qa-db-ja.com

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;

これは、私が理解しているように、BOOKテーブルのエントリに対応するIDおよびDENOMINATIONフィールドを持つtemp_chequesの各レコードをVOUCHERに挿入する必要があります(temp_chequesは、データベースバックアップから取得され、別の形式で再作成しようとしています)。ただし、実行するとエラーが発生します。

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

私はこれをSQuirrelで実行しており、他のクエリで問題が発生していません。クエリの構文に何か問題がありますか?

編集:

BOOKの構造は次のとおりです。

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

Temp_chequesの構造は次のとおりです。

ID  int(11)
number  varchar(20)
23
Elie

SELECT句から括弧を削除してください。 Microsoft TechNet から、SELECT句を使用したINSERTステートメントの正しい構文は次のとおりです。

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

「SELECTはMAX_JOIN_SIZEを超える行を検査します。SELECTに問題がない場合、WHEREを確認し、SET SQL_BIG_SELECTS = 1またはSET SQL_MAX_JOIN_SIZE =#を使用してください。」というエラーは、両方に多くの行があると想定して実際に正しいです。 BOOKとtemp_cheques。両方のテーブルのすべての行をクエリして相互参照を作成しようとすると、m * nサイズのクエリになります。 SQL Serverは、潜在的に長い操作を実行する前に、これを警告しようとしています。

セットする SQL_BIG_SELECTS = 1このステートメントを実行する前に、もう一度やり直してください。動作するはずですが、この操作には時間がかかる場合があることに注意してください。

52
lc.

BにはUNITS列が含まれていますか?

Temp_chequesとBookのテーブル構造は何ですか?

編集:私がコメントで言ったように、+ /-を行うとき、および比較するとき、すべての列は数値でなければなりません。
次の簡単なSELECTは機能しますか?

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

3
shahkalpesh

クエリの最終バージョンは次のとおりです。

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には必要ありませんでした。2つのテーブルのサイズ(temp_chequesで215000レコード、BOOKで8000)が原因で、選択サイズの制限を超えていたため、SQL_BIG_SELECTS = 1を設定する必要がありました。 。

2
Elie

便利な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);
2
RJHunter

Springリポジトリを使用すると、同じエラーが発生しました。

私のリポジトリには次のようなメソッドが含まれていました:

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

これは、インメモリデータベース(h2)に対して統合テストを実行するときにうまく機能します。ただし、MySqlのようなスタンドアロンのデータベースに対しては、同じエラーで失敗していました。

メソッドインターフェイスを次のように変更して解決しました。

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

注:findfindAllの間に違いはありません。ここで説明するように、 findBy/findAllBy間のSpring Data JPAの違い

1
Pim Hazebroek