これは、実行中のクエリの簡略化されたバージョンで、子行が一致するメインの親テーブル内のすべての行を検索する必要があります。子テーブルの1つが空の場合、以下のクエリは結果を返しません。このクエリは、空ではない子テーブルの結果のみを返すのはなぜですか?
メインテーブルには2つのテーブルを持っています
CREATE TABLE main (id INT PRIMARY KEY, name VARCHAR(8));
CREATE TABLE child1(id INT PRIMARY KEY, main_id int, name VARCHAR(8));
ALTER TABLE child1 add constraint fk_child1_main foreign key (main_id) references main (id);
CREATE TABLE child2(id INT PRIMARY KEY, main_id int, name VARCHAR(8));
ALTER TABLE child2 add constraint fk_child2_main foreign key (main_id) references main (id);
INSERT INTO main (id, name) VALUES (1, 'main');
INSERT INTO child1 (id, main_id, name) VALUES (2, 1, 'child1');
ありchild2の中に行がありませんし、それが空である場合は、次のクエリは行が戻されない:行が追加され
SELECT
main.*
FROM
main
INNER JOIN
child1
ON
main.id = child1.main_id
INNER JOIN
child2
ON
main.id = child2.main_id
WHERE
child1.name = 'child1' OR
child2.name = 'DOES NOT EXIST';
場合child2は、WHERE句と一致しない場合でも、SELECTはメインテーブルの行を返します。
INSERT INTO child2 (id, main_id, name) VALUES (4, 1, 'child2');
私はこれをDerbyとSQLiteでテストしました。これはデータベースで一般的なものです。
これはなぜこのように動作しますか?
私はそれを修正するために何ができますか?
私は、UNION、別のSELECTに変えることができるが、それははるかに冗長だし、プラス、我々は動的SQLを生成していると私はむしろ私たちのコードを変更する必要はありませんと思います。
別の修正は、単にデータベースにダムの行を追加することですが、それは厄介です。
PSは、メインテーブルには、クライアントが見上げる資産を記録した資産管理システムにおけるセッションテーブルです。ルックアップにはさまざまなタイプがあり、それぞれのタイプには別々の子テーブルがあります。また、検索可能なセッションのキー/値ペアの属性子テーブルがあります。
次に、一致しない行をchild2に追加するとクエリの結果が変更されるのはなぜですか?このステートメントによれば、一致しない行をchild2に追加した後でも、クエリはまだ行を返さないはずです。 –
これは、child2.nameが一致しなくても、クエリが結果を返さないようにするmain.id = child2.main_idだと分かります。私はこの質問の部分を無視していました。 –