🤖

MySQL8.0でEXISTS述語について理解する

2022/01/28に公開約2,500字

MySQL8.0で別テーブルでSELECTした結果をINSERTするの続きでEXISTS述語について確認しました.

述語とは

ミックさんのSQL 第2版 ゼロからはじめるデータベース操作 Kindle版の6-2あたりから引用すると

戻り値が真理値になる関数

です.LIKEIN, 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

ログインするとコメントできます