質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.03%

  • MariaDB

    262questions

    MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

ユーザ定義変数に配列を代入したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 458

aglkjggg

score 701

前提・実現したいこと

タイトルの通りですが、
ユーザー定義変数に配列(ベクトル)を代入したいのですが上手く出来ませんでした。

そもそも、スカラー値しか代入できないのでしょうか?

発生している問題・エラーメッセージ

なし

該当のソースコード

http://sqlfiddle.com/#!9/18c323/1

 テーブル作成
CREATE TABLE `accounts` (
    `user_id` INT(11) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

/* 1~10 */
INSERT INTO accounts(user_id) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
 実行するクエリ
/* query1 */
select @user_ids := user_id from accounts order by user_id desc limit 3;

/* query2 */
select @user_ids from dual;
 query2 の実行結果
8
 欲しい query2 の実行結果
10
9
8

補足情報(言語/FW/ツール等のバージョンなど)

  • MariaDB 15.1

 追記

一時テーブルを作成する事で欲しい結果を得る方法は分かります。
ユーザ定義変数の公式ドキュメントにも配列(ベクトル)についての記述が無かったので質問しました。
https://mariadb.com/kb/en/library/user-defined-variables/

drop table if exists tmp_user_ids;
create temporary table tmp_user_ids(slelect user_id from accounts order by user_id desc limit 3);

select user_id from tmp_user_ids;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

現在の仕様ではユーザー定義変数に配列や、結果が複数行となるような値を持たせることはできないものと思います。
下記のような形で文字列として結合する等での対応であれば可能かとは思います。

SET @user_ids = '';

SELECT
   @user_ids :=
   CASE
      WHEN @user_ids = ''
      THEN user_id
      ELSE CONCAT(@user_ids, ',', user_id)
   END
FROM accounts
ORDER BY user_id DESC
LIMIT 3;

SELECT @user_ids FROM dual;

+-----------+
| @user_ids |
+-----------+
| 10,9,8    |
+-----------+
SELECT
   @user_ids := GROUP_CONCAT(user_id)
FROM (
   SELECT user_id
   FROM accounts
   ORDER BY user_id DESC
   LIMIT 3
) t;

SELECT @user_ids FROM dual;

+-----------+
| @user_ids |
+-----------+
| 10,9,8    |
+-----------+

追記:

公式ドキュメントに「結果が複数行となるような値は代入できない」と明記されてはいませんが、
出来るとも書かれてない以上不可能なのですね。

MariaDBのドキュメントに記載があるかは見つけられていませんが、MySQLのリファレンスには下記の記載があります。
そのため、ユーザー定義変数では基本的に単一値のみを扱い、その値は基本的に文字列として取り扱われるものと思われます。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 9.4 ユーザー定義変数

ユーザー変数には、限定された一連のデータ型の値 (整数、小数、浮動小数点、バイナリ文字列、非バイナリ文字列、または NULL 値) を割り当てることができます。
10 進値と実数値の割り当てでは、値の精度やスケールは維持されません。
許可されている型以外の型の値は、許可されている型に変換されます。
たとえば、時間を表すデータ型や空間データ型の値は、バイナリ文字列に変換されます。

ユーザー変数に非バイナリ (文字) 文字列値を割り当てた場合、その変数には文字列と同じ文字セットと照合順序が含まれます。
ユーザー変数の強制性は暗黙的です。(これはテーブルカラム値と同等の強制性です。)

ユーザー変数に割り当てられたビット値は、バイナリ文字列として扱われます。
ビット値を数値としてユーザー変数に割り当てるには、CAST() または +0 を使用します。

結果セットでユーザー変数の値が選択された場合、それは文字列としてクライアントに返されます。

初期化されていない変数を参照する場合、その値は NULL で、型は文字列です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/29 01:24

    ご回答がありがとうございます。

    公式ドキュメントに「結果が複数行となるような値は代入できない」と明記されてはいませんが、
    出来るとも書かれてない以上不可能なのですね。

    キャンセル

  • 2017/10/29 07:19

    ご参考まで追記しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    集計関数を利用した場合のORDER BY高速化

    前提・実現したいこと ORDER BYをつけると激遅になります。 これを解決する方法はありませんか? 今のテーブルは500万行ですが、今後も増え続けます。 SELE

  • 解決済

    ストアドプロシージャの書き方

    ストアドプロシージャにてテーブルのバックアップを行いたいのですが、その際にテーブル名に実行日時のマイナス1日を指定したいのですが、どのようにしたら良いのかわかりません。検索して調べ

  • 受付中

    ORDER BY RAND(); が遅い

     質問 タイトルの通りなのですが、 MariaDBにおいてORDER BY RAND()が非常に遅いため改善を試みましたが、 上手くいかなかった為、 「どうすれば結果取得ま

  • 解決済

    INの値が重複した時、複数行取得したい

    accounts テーブルは表1のようになっています。 表1. accountsテーブル id name 1 大塚 2 山田 3 斎藤

  • 解決済

    UPDATEを高速にしたい

    前提・実現したいこと UPDATEが非常に遅いので速くしたいです。 accountsテーブルに約1千万件のデータが入っています。 そのうち約180万件に対してUPDATEをする必要

  • 解決済

    updateとcase whenの相性について

    +------+------+------+----------+ | bang | uria | tuki | bikou    | +------+------+------+

  • 解決済

    SQLにおける日時検索

    毎日毎時間10分単位で時間と風向・風量を測定しDBに記録をしていく様な、添付した画像のテーブルがあります。 そこで質問ですが、このテーブルから 「30分毎のレコード」や「

  • 解決済

    CONCATでCOUNTをすると正しく表示されない

     前提・実現したいこと 表1の出力を得たいです。 表1. 理想の出力 col1 col2 col3 1 1a 1a  発生している問題・エラーメッセージ

同じタグがついた質問を見る

  • MariaDB

    262questions

    MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。