20211128のMySQLに関する記事は3件です。

sql_mode=only_full_group_by について

エラー SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'カラム名' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: 'only_full_group_by制約を満たさないSQL') ↑こんなやつ 問題と解決法 GROUP BY句を含むSQLが only_full_group_by制約を満たしていないので怒られている。 ので、方法は2つ 1. only_full_group_by制約を満たすように調整する 2. 満たさなくても許される世界に移住する 方法1 結論としては SELECT, WHERE で呼び出す全てのカラムに次のいづれかの処置を行う GROUP BYの集計に加える MAX() などに食わせて一意にする です。 例) users, books (1:N) なテーブルを考えます。userは複数のbooksを持ちます。 あるuserがもつuser.id, books.name(複数) を取りたいとします。 この場合、以下のように適当にGROUP BYをかけるとこんな感じになると思います。 only_full_group_byを満たさないSQL SELECT users.id , GROUP_CONCAT(books.name) FROM users INNER JOIN books ON users.id = books.user_id GROUP BY users.id ORDER BY users.created_at DESC このクエリは、users.id, users.created_at, books.name を複数取得して、その後GROUP BYしてusers.idをまとめています。 books.nameはGROUP_CONCATするので問題ないですが、users.idとusers.created_at は結果の列数に対して複数存在してしまいます。 この点で曖昧なクエリとなっていそうです(実際には同じ値だったとしても、MySQLがよしなに処理してくれないとどれを選んでよいか分からないはず)。 なのでこうすれば良いです。 only_full_group_byを満たすSQL SELECT MAX(users.id) , GROUP_CONCAT(books.name) FROM users INNER JOIN books ON users.id = books.user_id GROUP BY users.id, users.created_at ORDER BY users.created_at DESC 尚、MAX()はVARCHARとかに対して問題なく動作しました。 方法2 データベースの再起動が必要になります。 MySQLのmy.cnf的なファイルのmysqldの項目で sql_modeにonly_full_group_byを含まないように書く つまりこんな感じ [mysqld] sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION クラウドとかだと FLAGS とかで調整できると思います。 あとがき 方法1の正攻法の記事が無かったので書きました。 方法1はさっき点から舞い降りたのでちゃんと正しいか自信がありません。 詳しい人教えてください。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQL5.7をインストールする方法

背景 EC2内にmysqlがインストールされていなかったのでmysql5.7をインストールしたい まず最初に sudo yum update -y をしてパッケージをupdateします。 そして sudo yum remove -y mariadb-libs でデフォルトで入っているmariaDBを消します。 MySQLをyumに追加する sudo yum isntall -y https://dev.mysql.com/get/[Red Hat Enterprise Linux 7をダウンロードしたリンク] Red Hat Enterprise Linux 7をダウンロードしたリンクは↓のリンクのLinux7をインストールしてNo thanks, just start my download.を押すとダウンロードされます。 https://dev.mysql.com/downloads/repo/yum/ MySQLを有効化 yum repolist all | grep -E "mysql[0-9]+-community/x86" でMySQLを確認してみるとデフォルトではMysql8.0が有効化されていると思うので、これを5.7に変えます。 sudo yum-config-manager --disable mysql80-community でMySQL8.0を無効化し、 sudo yum-config-manager --enable mysql57-community で5.7を有効化します。 yum repolist all | grep -E "mysql[0-9]+-community/x86" で5.7が有効化されていることを確認したら、いよいよ5.7のインストールと起動を行なっていきます。 MySQLのインストールと起動! sudo yum install -y mysql-community-server でMySQLをインストール。 sudo systemctl start mysqld でmysqldを起動します。 *ちなみにmysqldとはMySQLのデーモン(MySQLをバックエンドで動かしているものです) systemctl status mysqld.service でMySQLが動いていることを確認します。 sudo systemctl enable mysqld でmysqldを自動で動かせるようにしておきます。 mysql --version でMySQLのversionが5.7になっていれば成功です
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLで変数を便利に使ってみる

この記事はスタンバイ Advent Calendar 2021の1日目の記事です。 MySQLで変数を使用して便利だと感じた機能を書きます。 TL;DR MySQL上で変数を使用できる selectの結果を変数に使用できる MySQL上の変数とは MySQLをコンソールから操作をする際、MySQL変数を使用して、決まった作業、複雑なデータのとり方を簡単に行う事ができるようになります。 特にMySQLはWith句を使用できないので、簡易なものは変数で代替することも可能であります。 MySQL変数で出来ること・出来ないこと 出来ること 変数に任意の文字列、数字を格納することが出来る select文の結果を使って変数を格納することが出来る 出来ないこと DBセッションをまたいだ変数は宣言できない テーブルデータを配列的に持つことは出来ない 変数の使い方 最も簡単な変数宣言方法、呼び出し方です。 ### 変数の設定 mysql> set @user = "scott"; ### 変数の使い方 mysql> select @user; +-------+ | @user | +-------+ | scott | +-------+ 設定した変数は検索キーワードにも使用できます。 mysql> select * from user where name = @user; +-------+----------+ | name | password | +-------+----------+ | scott | tiger | +-------+----------+ select 文で変数を定義する 返り値が1個の場合に限り、select文の返り値を変数に指定することができます。宣言方法は2通りありますが、どちらでも同じ宣言が出来ます。 ### select文で変数の宣言。into @[変数名]で変数定義できます mysql> select password into @password from user where name = @user; (or) mysql> select @password := password from user where name = @user; mysql> select @password; +-----------+ | @password | +-----------+ | tiger | +-----------+ 日時の取り扱い(15分前、1日前、1ヶ月前など)にも便利です。時系列の履歴データを扱うときには必須と言ってもいいかもしれません。 ### 15分前、1日前、1ヶ月前を変数に追加 mysql> select @now := now() , @15min_ago := now() - interval 15 minute, @1day_age := now() - interval 1 day, @1month_ago := now() - interval 1 month; ###参照する mysql> select @15min_ago, @1day_ago, @1month_ago; +---------------------+---------------------+---------------------+ | @15min_ago | @1day_ago | @1month_ago | +---------------------+---------------------+---------------------+ | 2021-11-28 00:43:22 | 2021-11-27 00:58:22 | 2021-10-28 00:58:22 | +---------------------+---------------------+---------------------+ 上記で宣言した変数を使用することで、「現在から1日前までに修正されたレコード一覧。複数のテーブルから取得する」みたいなことが楽にできるようになります。 mysql> select * from user_data where updated_at between @now and @1day_ago; mysql> select * from user_history where updated_at between @now and @1day_ago; mysql> select * from event_history where updated_at between @now and @1day_ago; 感想 変数を使用することで実行するSQLが簡単になるので、ミスの要素が少なくなる 定型的な手順を作成しやすくなる procedureや他の言語に置き換えがやりやすくなる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む