「注文データが入っているはずなのに、検索すると0件になる」
SQLを使い始めたばかりだと、データがないのか、検索の書き方が違うのか判断しにくいですよね。
DB(データベース)は、注文や顧客などの情報を保存する仕組みです。SQLは、そのデータを検索したり変更したりするための言葉で、検索には主にSELECT文を使います。
この記事では、SELECT文を実行しても目的の行が見つからないときに、どこから確認すればよいかを説明します。
SELECT・FROM・WHEREの基本的な書き方から確認したい方は、先にSQLのSELECT文の使い方を読むと、この記事の確認手順を追いやすくなります。
💡 このページでわかること
- 検索結果が0件でも、データが消えたとは限らない理由
- 接続先や検索条件を確認する順番
- 原因が分からないときに、担当者へ伝える情報
結論:0件は「今の検索では見つからない」という結果
検索結果が0件になるのは、検索する場所が違う、条件に合わない、まだその接続からデータが見えない、といった理由が考えられます。0件だけで「データが消えた」とは判断できません。
まず接続先を確かめ、次に探したい1件を番号などで絞り、条件を1つずつ確認していきましょう。
その前に、SQLが正常に実行されたかも見てください。「検索は完了したが該当する行がない」と、「エラーで検索できなかった」は別の状態です。エラーが出ている場合は、結果表の空欄よりもエラーメッセージを先に確認します。
アプリ画面に「0件」と出る場合も、DBが返した結果とは限りません。画面側の絞り込みなどがあるため、SQLの結果と分けて考えます。
最初に、接続先と探したいデータを確認する
職場では、動作確認用のDBと実際の業務用のDBが分かれていることがあります。同じ名前のテーブルがあっても、中のデータは同じとは限りません。テーブルは、注文一覧のようにデータを行と列で保存する表です。
SQLを書き直す前に、使用中のDBツールの接続情報と、手順書や担当者から指定された接続先を見比べます。
| 確認すること | 見るポイント |
|---|---|
| 接続している場所 | 接続先サーバー名、DB名が作業対象と同じか |
| 検索する表 | テーブル名が正しいか。同名の表が複数ある場合は、表の所属先(スキーマなど)も同じか |
| 探したいデータ | 注文番号など、その1件を特定できる情報は何か |
| 「あるはず」の根拠 | 誰が、いつ、どの環境で登録・確認したデータか |
接続名に「テスト」と書かれているだけでは判断せず、実際の接続情報を確認しましょう。場所が分からなければ、「今どのDBにつながっているか、どの画面で確認できますか?」と聞けば大丈夫です。
以下のSQLは説明用です。実行する場合は、利用を認められた学習・検証用DBのSQL入力画面を使い、例のテーブルとデータが用意されていることを確認してください。コードを貼るだけで表が作られるわけではありません。
また、本番DBでは検索だけでも、大量のデータを読むと負荷がかかります。条件をすべて外すのではなく、対象の番号など必要な範囲を残して確認します。
条件を1つずつ追加して、0件になる箇所を探す
注文一覧から、注文番号1001を探す場面で考えてみましょう。説明用の orders テーブルには次の1行があるものとします。注文番号は重複せず、確認中にデータは変わらない前提です。
| order_id(注文番号) | status(状態) | ordered_at(注文日時) | shipped_at(発送日時) |
|---|---|---|---|
| 1001 | paid | 2026-10-15 14:30:00 | NULL |
日時やNULLの扱いを揃えるため、以下のSQLはPostgreSQLの通常の設定を前提にしています。状態の列は文字列型、日時の列は timestamp without time zone(タイムゾーンの情報を持たない日時型)です。
この例では paid は支払い済み、shipped は発送済みを表します。発送日時の NULL は、値がない・不明な状態を示すもので、この注文ではまだ発送日時を記録していません。
まず、番号だけで検索します。
SELECT order_id, status, ordered_at, shipped_at
FROM orders
WHERE order_id = 1001;
SELECTの後ろは取り出す列、FROMの後ろは検索するテーブルの名前、WHEREの後ろは行を絞る条件です。この前提では、上の1行が結果に残ります。
次に、元の検索にあった「発送済み」の条件を追加します。
SELECT order_id, status, ordered_at, shipped_at
FROM orders
WHERE order_id = 1001
AND status = 'shipped';
結果は0件です。AND は「両方の条件を満たす」という意味ですが、注文1001の状態は paid なので、発送済みの条件に合いません。
| 確認した条件 | 結果 | 分かったこと |
|---|---|---|
| 注文番号1001だけ | 1件 | この接続では注文1001が見える |
| 注文番号1001+発送済み | 0件 | 注文はあるが、発送済みの条件を満たさない |

条件を加えたときに0件になったら、その条件と実際の値を見比べます。 ただし、条件が間違っているとは限りません。「発送済みだけを表示する」という仕様なら、支払い済みの注文が出ないのは正しい結果です。
調査のために条件を外すことと、アプリの検索条件を修正することは別です。検索対象に含めるべき注文なのか、仕様や担当者の説明と照らし合わせましょう。
他の日付などを調べるときは、番号だけで1件になったSQLへ戻り、調べたい条件を1つ追加します。すでに0件になる条件を残したままでは、別の条件の影響を判断できません。実際の調査中にデータが更新された可能性もあるため、実行時刻も記録しましょう。
番号だけの検索でも0件なら、状態の条件が原因とはまだ言えません。接続先、番号の取り違え、登録の状況へ戻って確認します。
検索条件で見落としやすい3つのポイント
文字の違いと、完全一致・部分一致
注文番号では見つかるのに、文字の条件を加えると消える場合は、保存されている値を見てみましょう。
画面では「支払い済み」と表示していても、DBには paid と保存していることがあります。その列に対して status = '支払い済み' と指定しても、同じ値を探していることにはなりません。
また、= は値が等しいかを比べる書き方です。文字列の一部分を含むか調べたい場合は、一般に LIKE と % を使います。たとえば LIKE '%paid%' は、前後に別の文字がある値も対象にします。
ただし、この条件は unpaid(未払い)にも一致します。0件を解消するためだけに部分一致へ変えると、意図しないデータまで出てしまいます。
前後の空白、全角・半角、大文字・小文字も確認候補です。違いを同じとみなすかはDB製品・列の種類・比較設定などで変わるため、「必ず区別される」と決めつけず、実際の値と設定を確認してください。
日付だけでなく、時刻まで入っていないか
注文1001の日時は「2026年10月15日14時30分」です。「10月15日の注文」を探すつもりでも、日時の列を「10月15日0時0分ちょうど」と比較すると一致しません。
1日分を探すときは、当日の0時以上、翌日の0時未満という範囲で考えると、時刻を含むデータも対象にできます。
次はPostgreSQLで、ordered_at がタイムゾーンを持たない日時型の場合の例です。
SELECT order_id, status, ordered_at
FROM orders
WHERE order_id = 1001
AND ordered_at >= TIMESTAMP '2026-10-15 00:00:00'
AND ordered_at < TIMESTAMP '2026-10-16 00:00:00';
>= は「以上」、< は「未満」です。この条件なら14時30分の注文1001が見つかり、翌日0時の注文は含みません。

この型には日本時間などの地域の情報は入りません。保存した日時と、探したい「1日」が同じ地域の時刻を基準にしているかを確認してください。タイムゾーンを扱う別の日時型や他のDB製品へ、この例をそのまま当てはめないようにしましょう。
値がない項目を「= NULL」で探していないか
注文1001の発送日時には、まだ値が記録されておらず、NULLが入っています。NULLの行を探すときは、= NULL ではなく IS NULL を使います。
SELECT order_id, shipped_at
FROM orders
WHERE order_id = 1001
AND shipped_at IS NULL;
この条件なら、発送日時がNULLの注文1001が見つかります。反対に、発送日時が記録されている行を探す場合は IS NOT NULL を使います。
次のように = NULL と書いても、NULLの行は見つかりません。
WHERE shipped_at = NULL
PostgreSQLの通常の設定では、この比較の結果は「等しい」ではなく「不明」になります。WHEREは条件を満たすと判断できた行だけを残すため、注文1001も結果から外れます。
なお、NULLはツールによって「NULL」と表示されたり、空欄で表示されたりします。**表示の違いで検索の書き方が変わるわけではありません。保存されている値がNULLなら、どちらの表示でも IS NULL で探します。**
表をつなぐと0件になる場合は、対応する行を確認する
1つのテーブルだけなら見つかるのに、別のテーブルと組み合わせると0件になることもあります。
ここでは、注文番号が同じ行どうしを組み合わせて、注文情報と発送情報を一緒に確認する場面を考えます。こうして、テーブルの行どうしを条件に従って組み合わせる仕組みをJOINと呼びます。
注文1001について、2つのテーブルが次の状態だとします。この例では、発送した時点で発送テーブルに記録を追加するものとします。
| テーブル | 保存する情報 | 注文1001のデータ |
|---|---|---|
orders(注文テーブル) | 注文番号・注文日時・注文の状態など | ある(支払い済み) |
shipments(発送テーブル) | 注文番号・発送の状態など | まだ発送していないので、ない |
INNER JOIN は、指定した条件で両方のテーブルに対応する行がある組み合わせだけを結果に残します。
注文1001は注文テーブルにはありますが、発送テーブルには組み合わせる相手がいません。そのため、注文番号が同じ行どうしを INNER JOIN で組み合わせて注文1001を探すと、結果は0件になります。注文データそのものがなくなったわけではありません。
この場合は、次の順に確認します。
- 注文の表だけで、注文1001が見つかるか。
- 発送の表に、注文1001に対応する行があるか。
- 行を組み合わせる条件に、正しい列を指定しているか。
「まだ発送していない注文も、検索結果に表示したい」という場合には、LEFT JOIN が候補になります。
注文テーブルを基準にして発送テーブルを組み合わせると、発送情報がない注文1001も検索結果に表示できます。その場合、発送情報の欄はNULLになります。
ここで変わるのは検索結果です。保存されている注文データを削除したり、書き換えたりするわけではありません。
ただし、WHEREに shipments.status = 'shipped'(発送テーブルの状態が発送済み)という条件を付けると、発送情報がNULLの注文1001は条件を満たさず、検索結果に表示されません。LEFT JOINを使っても、この条件では結果が0件になります。 発送テーブルの列に条件を付けると必ず表示されなくなる、という意味ではありません。どのような条件で絞っているかを確認しましょう。
0件だからと機械的にJOINの種類を変えず、「発送情報がない注文も表示する必要があるか」を先に確認してください。詳しい書き方と結果の違いは、SQLのJOINの解説で確認できます。
まだ見つからないときの確認と相談
登録直後か、自分だけ見えないかを整理する
接続先と検索条件が合っていても、登録したばかりのデータが、別の接続からすぐに見えるとは限りません。
登録処理の変更がまだ確定していない場合などが考えられます。変更を確定する操作をCOMMIT(コミット)といいます。ただし、検索する側でCOMMITを実行すれば解決する、という意味ではありません。 登録した側の処理が完了したか、担当者に確認します。
確定後にいつ見えるかも、DBの設定や読み取り先の仕組みによって異なります。原因が分からないまま、再登録やデータ変更を行うと、重複や意図しない変更につながるおそれがあります。
状況を次のように整理すると、相談先で調べやすくなります。
| 状況 | 次に確認すること |
|---|---|
| 番号だけで探しても0件 | 接続先、番号、登録完了の確認方法 |
| 特定の条件を加えると0件 | 保存値と条件、表示対象の仕様 |
| 別の表を組み合わせると0件 | 相手の行の有無、行を組み合わせる条件 |
| SQLでは見つかるがアプリ画面は0件 | アプリの接続先、入力値、追加の絞り込み |
| 他の人には見えるが自分には見えない | 接続先・検索条件・実行時刻の違い、利用者ごとの表示範囲 |
アプリが「削除扱いのデータは除外する」「自分の部署のデータだけ表示する」といった条件を追加している場合もあります。アプリから実際に渡された検索値や条件は、確認方法が分かる担当者に調べてもらいましょう。
分かったことと、分からないことを分けて伝える
「データがありません」だけでは、どこまで調べたのか伝わりません。接続先、対象の番号、実行時刻、試した条件と結果をまとめます。
たとえば、今回の注文1001なら次のように相談できます。以下は架空の報告例です。
テスト用DBの注文1001について確認しています。10月17日10時20分に、注文番号だけで検索すると1件、発送済みの条件を加えると0件でした。DB上の状態はpaidです。この注文は発送済み一覧に表示される想定でしょうか。画面から実際にどの条件が送られているかは、まだ確認できていません。
社内で共有できる範囲で、実行したSQLや結果も添えると比較しやすくなります。顧客名など確認に不要な個人情報は載せず、必要な情報に絞りましょう。
まとめ・関連記事
DBの検索結果が0件でも、データが存在しないとは限りません。最初に接続先と探す番号を確認し、その1件がどの条件で結果から外れるかを調べましょう。
文字の比較、日時の範囲、NULLの探し方、表を組み合わせる条件は、見落としやすいポイントです。条件を変えて結果が出ても、その変更が仕様に合っているかは別に確認します。
まずは元のSQLを残したうえで、許可された範囲の確認用SELECTを使い、「何を条件にすると何件だったか」を1つ記録してみてください。自分で判断できない場合も、その記録が次の相談に役立ちます。
- SQLのSELECT文の使い方|基本構文から条件指定まで初心者向けに解説:SELECT・WHEREの書き方から確認したいときに。
- SQLのJOINとは?表をつなぐ仕組みと使い方を初心者向けに解説:表を組み合わせたときの結果を理解したいときに。
- 【原因と対策】DBを更新したのに反映されないのはなぜ?初心者が確認すべきチェックリスト:直前に更新したデータが見えないときに。
