1. ホーム
  2. mysql

[解決済み] SQLクエリは、複数のテーブルからデータを返す

2022-03-21 15:08:02

質問

次のことを知りたいのですが。

  • データベースの複数のテーブルからデータを取得するには?
  • このような場合、どのような種類のメソッドがあるのでしょうか?
  • joinとunionとは何ですか、またどのように違うのですか?
  • 他のものと比較して、それぞれをどのような場合に使うべきですか?

私の(例えばPHPの)アプリケーションでこれを使うことを計画していますが、データベースに対して複数のクエリを実行したくありません。1つのクエリで複数のテーブルからデータを取得するためには、どのようなオプションがありますか?

注:PHPのキューで常に遭遇する数多くの質問について、よく書かれたガイドにリンクできるようにしたいので、これを書いています。そうすれば、私が回答を投稿するときに、さらに詳細な情報を得るためにこれにリンクできます。

回答は以下の通りです。

  1. Part 1 - ジョインとユニオン
  2. パート2 - サブクエリ
  3. パート3 - トリックと効率的なコード
  4. パート4 - From句のサブクエリ
  5. パート5 - ジョンのトリックのミックスバッグ

解き方は?

Part 1 - ジョインとユニオン

この回答は、以下の内容をカバーしています。

  1. 第1部
    • 内部結合を使用して2つ以上のテーブルを結合する(参照) ウィキペディアの項目 をご覧ください。)
    • ユニオンクエリの使用方法
    • 左外部結合と右外部結合(これ stackOverflowの回答 は、結合の種類を説明するのに優れています)
    • 交差クエリ(およびデータベースがサポートしていない場合の再現方法) - これはSQL-Serverの機能です( 情報を見る の一部であり を書いた理由 ということです。
  2. パート2
    • サブクエリ - サブクエリとは何か、サブクエリを使用できる場所、サブクエリの注意点
    • Cartesian joins AKA - Oh, the misery!

データベース内の複数のテーブルからデータを取り出すには、いくつかの方法があります。この回答では、ANSI-92結合構文を使用することにします。これは、古いANSI-89構文を使用する他の多くのチュートリアルとは異なるかもしれません(89に慣れている場合、直感的に理解できないかもしれませんが、試してみるしかありません)。 大いに クエリーが複雑になってきたときに理解しやすくなります。なぜ使うのか?パフォーマンスが向上するのでしょうか?その 答え はノーですが、それは です 慣れれば読みやすくなります。他の人がこの構文で書いたクエリも読みやすくなります。

また、ある小さなカーディーラーが、どのような車があるのかを追跡するためのデータベースを持っている、というコンセプトを使おうと思っています。そのオーナーは、あなたをITコンピュータ担当として雇い、彼が要求するデータを即座に提供してくれることを期待しています。

最終的なテーブルで使用するルックアップテーブルをいくつも作りました。これで、合理的なモデルを作ることができます。まず始めに、以下のような構造を持つサンプルデータベースに対してクエリを実行することにします。初心者にありがちな間違いを考えて、何が問題なのかを説明し、もちろんそれを修正する方法も紹介します。

最初のテーブルは単純に色のリストで、車置き場にある色を把握するためのものです。

mysql> create table colors(id int(3) not null auto_increment primary key, 
    -> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| color | varchar(15) | YES  |     | NULL    |                |
| paint | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> insert into colors (color, paint) values ('Red', 'Metallic'), 
    -> ('Green', 'Gloss'), ('Blue', 'Metallic'), 
    -> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from colors;
+----+-------+----------+
| id | color | paint    |
+----+-------+----------+
|  1 | Red   | Metallic |
|  2 | Green | Gloss    |
|  3 | Blue  | Metallic |
|  4 | White | Gloss    |
|  5 | Black | Gloss    |
+----+-------+----------+
5 rows in set (0.00 sec)

ブランド表は、カリアードが販売する可能性のあるさまざまなブランドの車を識別します。

mysql> create table brands (id int(3) not null auto_increment primary key, 
    -> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| brand | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> insert into brands (brand) values ('Ford'), ('Toyota'), 
    -> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from brands;
+----+--------+
| id | brand  |
+----+--------+
|  1 | Ford   |
|  2 | Toyota |
|  3 | Nissan |
|  4 | Smart  |
|  5 | BMW    |
+----+--------+
5 rows in set (0.00 sec)

モデルテーブルでは、さまざまなタイプの車をカバーします。

mysql> create table models (id int(3) not null auto_increment primary key, 
    -> model varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| model | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from models;
+----+--------+
| id | model  |
+----+--------+
|  1 | Sports |
|  2 | Sedan  |
|  3 | 4WD    |
|  4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)

そして最後に、これらすべてのテーブルを結びつけるのが、このテーブルです。IDフィールドは、実際には車を識別するために使用される固有のロット番号です。

mysql> create table cars (id int(3) not null auto_increment primary key, 
    -> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type   | Null | Key | Default | Extra          |
+-------+--------+------+-----+---------+----------------+
| id    | int(3) | NO   | PRI | NULL    | auto_increment |
| color | int(3) | YES  |     | NULL    |                |
| brand | int(3) | YES  |     | NULL    |                |
| model | int(3) | YES  |     | NULL    |                |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1), 
    -> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
|  1 |     1 |     2 |     1 |
|  2 |     3 |     1 |     2 |
|  3 |     5 |     3 |     1 |
|  4 |     4 |     4 |     2 |
|  5 |     2 |     2 |     3 |
|  6 |     3 |     5 |     4 |
|  7 |     4 |     1 |     3 |
|  8 |     2 |     2 |     1 |
|  9 |     5 |     2 |     3 |
| 10 |     4 |     5 |     1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)

これで、以下のさまざまなタイプの結合の例をカバーし、また、十分なデータを得ることができます(と私は思っています)。

で、肝心のボスが知りたいのは 持っているスポーツカーのIDは? .

これは単純な2テーブル結合です。モデルを識別するテーブルと、その中に利用可能な在庫を持つテーブルがあります。ご覧のように、テーブルの中のデータは model のカラムは cars テーブルが関連する models の列があります。 cars テーブルがあります。さて、モデルテーブルのIDは 1 に対して Sports というわけで、結合を書きましょう。

select
    ID,
    model
from
    cars
        join models
            on model=ID

さて、このクエリは良い感じでしょうか?2つのテーブルを識別し、必要な情報を含み、結合するカラムを正しく識別する結合を使用しています。

ERROR 1052 (23000): Column 'ID' in field list is ambiguous

いやーん。最初のクエリでエラーが出た! そうです、プラムです。このクエリには正しいカラムが含まれていますが、そのうちのいくつかは両方のテーブルに存在するため、データベースはどのカラムを指しているのか、またそのカラムがどこにあるのかわからなくなってしまいます。これを解決するには、2つの方法があります。ひとつはシンプルに tableName.columnName というように、データベースに正確に伝えることができます。

select
    cars.ID,
    models.model
from
    cars
        join models
            on cars.model=models.ID

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
|  2 | Sedan  |
|  4 | Sedan  |
|  5 | 4WD    |
|  7 | 4WD    |
|  9 | 4WD    |
|  6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)

もう一つは、おそらくもっとよく使われるもので、テーブルエイリアスと呼ばれるものです。この例のテーブルは、シンプルで素敵な名前ですが、以下のようにタイプアウトします。 KPI_DAILY_SALES_BY_DEPARTMENT というのは、すぐに飽きるでしょうから、簡単な方法として、このようにテーブルにニックネームをつけることができます。

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID

さて、リクエストに戻りましょう。見ての通り、必要な情報はありますが、要求されていない情報もあるので、要求されたスポーツカーだけを取得するために、ステートメントにwhere節を入れる必要があります。私は、テーブル名を何度も使うよりも、テーブル・エイリアスを使う方が好きなので、この時点からこの方法にこだわろうと思います。

明らかに、このクエリにはWhere句を追加する必要があります。スポーツカーを特定するには ID=1 または model='Sports' . IDはインデックス化されており、プライマリキーであるため、クエリでそれを使用することができます。

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

ビンゴ! ボスは喜んでいる。もちろん、上司は上司で、自分が頼んだことに満足することはありませんから、その情報を見てから、こう言います。 色も欲しい .

さて、クエリの大部分はすでに書かれていますが、3つ目のテーブルとして色を使用する必要があります。さて、私たちの主要な情報テーブルである cars には車のカラーIDが格納されており、これがカラーIDカラムにリンクしています。ですから、元と同じような方法で、3番目のテーブルを結合することができます。

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

くそっ、テーブルは正しく結合され、関連するカラムもリンクされていたにもかかわらず、実際の 情報 を、リンクしたばかりの新しいテーブルから取得します。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)

さて、これで一旦はボスの背中を押すことができました。さて、もう少し詳しく説明しましょう。ご覧のとおり from 節は、メインテーブル(私はよく、ルックアップやディメンションテーブルではなく、情報を含むテーブルを使用します)をリンクしています。このクエリは、テーブルを入れ替えても同じように動作しますが、数カ月後にこのクエリを読み返すと、あまり意味がありません。したがって、直感的にレイアウトし、インデントをうまく使って、すべてができるだけ明確になるように、わかりやすいクエリを書くようにするとよいでしょう。特に、トラブルシューティングを行う場合は、このような特徴をクエリに植え付けるようにしましょう。

このように、どんどんテーブルをリンクさせていくことは十分に可能です。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

複数のカラムを結合したいようなテーブルを入れ忘れたのに対して join 文がありますが、ここではその例を示します。もし models テーブルにはブランド固有のモデルがあり、そのために brand にリンクしています。 brands テーブルの ID というフィールドがあれば、このようにすることができます。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
            and b.brand=d.ID
where
    b.ID=1

上のクエリは、結合されたテーブルをメインの cars テーブルの結合を指定するだけでなく、既に結合されているテーブル間の結合も指定します。これが行われていない場合、結果はカーテシアン結合と呼ばれます。カルテジアン結合とは、情報が結果を制限する方法をデータベースに伝えていないため、行が返される結合のことです。 すべて のように、条件に合致する行を表示します。

では、カルテジアン結合の例として、次のクエリを実行してみましょう。

select
    a.ID,
    b.model
from
    cars a
        join models b

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  1 | Sedan  |
|  1 | 4WD    |
|  1 | Luxury |
|  2 | Sports |
|  2 | Sedan  |
|  2 | 4WD    |
|  2 | Luxury |
|  3 | Sports |
|  3 | Sedan  |
|  3 | 4WD    |
|  3 | Luxury |
|  4 | Sports |
|  4 | Sedan  |
|  4 | 4WD    |
|  4 | Luxury |
|  5 | Sports |
|  5 | Sedan  |
|  5 | 4WD    |
|  5 | Luxury |
|  6 | Sports |
|  6 | Sedan  |
|  6 | 4WD    |
|  6 | Luxury |
|  7 | Sports |
|  7 | Sedan  |
|  7 | 4WD    |
|  7 | Luxury |
|  8 | Sports |
|  8 | Sedan  |
|  8 | 4WD    |
|  8 | Luxury |
|  9 | Sports |
|  9 | Sedan  |
|  9 | 4WD    |
|  9 | Luxury |
| 10 | Sports |
| 10 | Sedan  |
| 10 | 4WD    |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)

やれやれ、醜いことだ。しかし、データベースに関する限りは まさに は、要求されたものです。クエリの中で、私たちは ID から carsmodel から models . しかし なんと を結合するために、データベースがマッチングした あらゆる の行は、最初のテーブルから すべての の行は、2番目のテーブルの行です。

さて、ボスが戻ってきて、また情報を欲しがっていますね。 同じリストが欲しいが、4WDも入れて欲しい .

しかし、このことは、これを達成するための2つの異なる方法を見るための素晴らしい口実を与えてくれます。where節に次のような別の条件を追加することができます。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
    or b.ID=3

上記は全く問題なく動作しますが、別の方法で見てみましょう。 union クエリが動作します。

次のようにすると、すべてのスポーツカーが返されることが分かっています。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

そして、次のようにすると、すべての4WDが返されます。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

そのため union all 節を挟むと、2 番目のクエリの結果が最初のクエリの結果に追加されます。

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
union all
select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
|  5 | 4WD    | Green |
|  7 | 4WD    | White |
|  9 | 4WD    | Black |
+----+--------+-------+
7 rows in set (0.00 sec)

ご覧のように、最初のクエリの結果が最初に返され、その後に2番目のクエリの結果が返されます。

この例では、もちろん最初のクエリを単純に使用した方がずっと簡単でしたが union クエリーは特定のケースで威力を発揮します。簡単に結合できないテーブルから特定の結果を返すには最適な方法です。 全く 無関係のテーブルです。ただし、守るべきルールがいくつかあります。

  • 最初のクエリの列型は、以下の他のすべてのクエリの列型と一致しなければなりません。
  • 最初のクエリのカラムの名前は、結果のセット全体を識別するために使用されます。
  • 各クエリのカラム数は同じでなければなりません。

さて、あなたは は何なのか気になるところです。 を使用した場合との違いは何ですか? unionunion all . A union クエリは重複を削除します。 union all はありません。このため union を超えて union all でも、その価値はあるかもしれませんね。でも、ここではそういうことは推測しません。

その上で、ここにいくつかの補足事項を記しておくとよいかもしれません。

  • 結果を順番に並べたい場合は order by が、エイリアスは使えなくなります。上のクエリでは order by a.ID はエラーになります。結果に関する限り、このカラムは ID ではなく a.ID - 両方のクエリで同じエイリアスが使用されているにもかかわらず、です。
  • を1つだけ持つことができます。 order by 文があり、それは最後の文でなければなりません。

次の例では、テーブルにいくつかの行を追加しています。

を追加しました。 Holden をブランドテーブルに追加しました。 また、行を cars を持つ color の値です。 12 - のように、カラーテーブルの中で参照されていないものがあります。

さて、ボスがまた戻ってきて、要求を吠えています - *取り扱いブランドの数と車の台数が欲しい!` - 典型的な、話し合いで面白いセクションになったところで、ボスがもっと仕事を欲しがっているのです。

右代さん、ではまず、可能性のあるブランドを完全にリストアップする必要がありますね。

select
    a.brand
from
    brands a

+--------+
| brand  |
+--------+
| Ford   |
| Toyota |
| Nissan |
| Smart  |
| BMW    |
| Holden |
+--------+
6 rows in set (0.00 sec)

さて、これをcarsテーブルと結合すると、次のような結果が得られます。

select
    a.brand
from
    brands a
        join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Nissan |
| Smart  |
| Toyota |
+--------+
5 rows in set (0.00 sec)

もちろん、これは問題です。 Holden というブランドを追加しました。

これは、結合が ともに テーブルを使用します。車には、データ型が Holden は返されません。そこで outer を結合します。これは すべて の結果は、一方のテーブルの結果が他方のテーブルで一致するかどうかにかかわらず

select
    a.brand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Holden |
| Nissan |
| Smart  |
| Toyota |
+--------+
6 rows in set (0.00 sec)

これで、素敵な集計関数を追加して、カウントを取得することができ、ちょっとだけボスを追い払うことができます。

select
    a.brand,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+--------------+
| brand  | countOfBrand |
+--------+--------------+
| BMW    |            2 |
| Ford   |            2 |
| Holden |            0 |
| Nissan |            1 |
| Smart  |            1 |
| Toyota |            5 |
+--------+--------------+
6 rows in set (0.00 sec)

そう言って、ボスはコソコソと去っていく。

さて、もう少し詳しく説明しますと、外部結合は left または right の型があります。左または右は、どちらのテーブルが 完全に が含まれます。A left outer join は左側のテーブルのすべての行を含めますが、(ご想像のとおり) right outer join は、右側のテーブルの結果をすべて結果に取り込みます。

一部のデータベースでは full outer join からの結果(マッチするかどうかに関わらず)を返します。 ともに テーブルがありますが、これはすべてのデータベースでサポートされているわけではありません。

さて、この時点でおそらく皆さんは、クエリで結合型をマージできるかどうか疑問に思っていることでしょう。

select
    b.brand,
    c.color,
    count(a.id) as countOfBrand
from
    cars a
        right outer join brands b
            on b.ID=a.brand
        join colors c
            on a.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)

では、なぜ期待された結果と違うのでしょうか?それは、carsからbrandへの外部結合は選択しましたが、colorsへの結合では指定しなかったため、この結合では両方のテーブルで一致する結果のみが返されるからです。

以下は、期待通りの結果を得るためのクエリです。

select
    a.brand,
    c.color,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
        left outer join colors c
            on b.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Holden | NULL  |            0 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| Toyota | NULL  |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)

見ての通り、クエリに2つの外部結合があり、期待通りの結果が得られています。

では、他のタイプの結合はどうでしょうか?交差点はどうでしょうか?

すべてのデータベースが intersection しかし、ほとんどすべてのデータベースで、Join(または少なくとも構造化されたWhereステートメント)を通じて交差点を作成することができます。

インターセクションは、以下のような結合の一種です。 union しかし、その違いは のみ は、ユニオンで結合された個々のクエリ間で同一(同一という意味です)のデータ行を返します。あらゆる点で同一の行だけが返されます。

簡単な例を挙げると、このようになります。

select
    *
from
    colors
where
    ID>2
intersect
select
    *
from
    colors
where
    id<4

通常の union クエリはテーブルのすべての行を返します (最初のクエリは ID>2 を持つもの、2番目は ID<4 にマッチする行のみが返されます。 id=3 という2つの条件を満たしています。

さて、もしあなたのデータベースが intersect というクエリで簡単に対応できます。

select
    a.ID,
    a.color,
    a.paint
from
    colors a
        join colors b
            on a.ID=b.ID
where
    a.ID>2
    and b.ID<4

+----+-------+----------+
| ID | color | paint    |
+----+-------+----------+
|  3 | Blue  | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)

交差点クエリを本質的にサポートしていないデータベースを使用して、2つの異なるテーブルで交差点を実行したい場合、以下のようにジョインを作成する必要があります。 各カラム のテーブルの