🤖
MySQL8.0でEXISTS述語について理解する
MySQL8.0で別テーブルでSELECTした結果をINSERTするの続きでEXISTS述語について確認しました.
述語とは
ミックさんのSQL 第2版 ゼロからはじめるデータベース操作 Kindle版の6-2あたりから引用すると
戻り値が真理値になる関数
です.LIKE
やIN
, BETWEEN
, IS NULL
などもあります.
句と述語の違いを答えよ,と言われると言葉に詰まってしまうのですが,,,
句はSELECT
, INSERT
, FROM
などの関数ではない書き方で,
SUM
などの関数の中の一種が述語である,と理解しています(これは間違っているかもしれません).
MySQLの環境は前記事と同様にこちらを使いました.
準備
create database exists_app;
use exists_app
create table article (
id int not null primary key AUTO_INCREMENT,
user_id int not null,
title varchar(40) not null,
text varchar(200) not null
);
create table user (
id int not null primary key AUTO_INCREMENT,
user_name varchar(40) not null
);
insert into article (user_id, title, text) values
(1, 'abc', 'test_text1'),
(1, 'xyz', 'test_text2'),
(2, 'hogehoge', 'test_text3'),
(3, 'hogehoge', 'test_text4');
insert into user (user_name) values
('ichiro'),
('takeo');
select * from article;
+----+---------+----------+------------+
| id | user_id | title | text |
+----+---------+----------+------------+
| 1 | 1 | abc | test_text1 |
| 2 | 1 | xyz | test_text2 |
| 3 | 2 | hogehoge | test_text3 |
| 4 | 3 | hogehoge | test_text4 |
+----+---------+----------+------------+
select * from user;
+----+-----------+
| id | user_name |
+----+-----------+
| 1 | ichiro |
| 2 | takeo |
+----+-----------+
EXISTS述語を実行してみる
article.user_idがuser.idに存在する場合のarticleテーブルのレコードを取得します.
select *
from article
where exists (
select *
from user
where article.user_id = user.id
);
+----+---------+----------+------------+
| id | user_id | title | text |
+----+---------+----------+------------+
| 1 | 1 | abc | test_text1 |
| 2 | 1 | xyz | test_text2 |
| 3 | 2 | hogehoge | test_text3 |
+----+---------+----------+------------+
ちなみにEXISTS述語のサブクエリのSELECT句で指定するのは適当でよいのですが,SELECT *
と書くのが一般的らしいです.以下はSELECT句で定数1を指定した場合です.結果は変わっていません.
select *
from article
where exists (
select 1
from user
where article.user_id = user.id
);
+----+---------+----------+------------+
| id | user_id | title | text |
+----+---------+----------+------------+
| 1 | 1 | abc | test_text1 |
| 2 | 1 | xyz | test_text2 |
| 3 | 2 | hogehoge | test_text3 |
+----+---------+----------+------------+
Discussion