質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

828閲覧

SQLでのデータ取得について

siroyuri

総合スコア10

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2022/01/11 04:44

編集2022/01/11 07:21

## 疑問点
SQLでデータの取得をしているのですが、上手くデータが取得できなかった部分がありました。
解決はしたのですが、なぜ取得できなかったのかが考えても調べてもわからなかったので質問しました。

テーブル情報

必要なカラムだけ抜粋してます。

itemsテーブル

idname
10A
11B
12C

item_informationsテーブル

iditem_id
110
210
311
412

やりたいこと

item_informaitonsテーブルのitem_idが重複しているレコード、新規のレコードを別々に取得したい。
重複しているレコード(id: 1,2)のうち、最初のレコード(id: 1)は新規として扱いたい。

以下の様な感じです。

新規 = item_informationsの(id: 1,3,4)のレコード
重複 = item_informationsの(id: 2)のレコード

問題点

新規のレコードの取得は以下のクエリで実現しました。

sql

1SELECT * 2FROM item_informations 3GROUP BY item_id 4ORDER BY id asc

以下のレコードが取得できています。

iditem_id
110
311
412

重複のレコードをクエリを使用して取得しようとして問題が発生しました。

## 問題があったクエリ

sql

1SELECT * 2FROM item_informations 3WHERE id NOT IN ( 4 SELECT id 5 FROM item_informations 6 GROUP BY item_id 7 ORDER BY id asc 8);

サブクエリでは、以下が取得できています。

id
1
3
4

これをサブクエリとして、NOT INで省けば取得できると考えました。
結果として何も取得されず、空の値が返ってきました。

疑問点まとめ

知りたいことは、問題があったクエリでは、なぜデータの取得ができなかったのかです。

憶測ですが、
GROUP BYは重複をまとめるもの。
省いているわけではないので、見えなくても(id: 2)のレコードも含まれている?
だからそのままNOT INで省こうとしたら全てのレコードが省かれたのではないか?
と考えています。

ちなみに、重複のデータ取得に関しては、SQLを使用しない形で解決しております。

解決はしているのですが、理由がわからないままだと今後も同じことをしてしまうと思ったので理由を調べています。
いろいろ調べたのですがこれと言った答えが見つかりませんでした。
初心者の憶測で終わらせてしまうのは心許ないので、理由が分かるかたがいれば回答していただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takasima20

2022/01/11 04:59

「問題があったクエリ」のサブクエリのみを実行しましたか?
siroyuri

2022/01/11 05:11

実行しています。 item_informationsテーブルの(id: 1, 3, 4)のidカラムのみ取得しています。 新規のレコード取得に使用したクエリのselectを*からidのみに限定したクエリだったので結果の表記を省いてしまっていました。
takasima20

2022/01/11 11:47

SELECT id で実行したらなんかへんなの出ませんか?
YT0014

2022/01/12 09:04

このSQLは、DBやバージョンにより、動作が異なります。 標準SQLを想定した場合も、標準SQL92以前では、エラーとなります。 対象のDBとバージョンをご提示ください。 また、質問用に省略されたカラムの挙動に依存する可能性もあります。 実際に、質問の通りのテーブルを作成しての挙動確認もお願いいたします。
guest

回答3

0

自己解決

考えていた通り、GROUP BYは重複を1行にまとめているだけであって、除外しているわけではない。
見えていないだけで実際には重複したレコードの情報も含まれていた。
だから、NOT INで除外しようとした時に全てのレコードが除外の対象になってしまった。
という理由が正解だった様です。

投稿2022/01/18 03:11

siroyuri

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

重複というのは、同じデータが複数存在している場合の事を言います。
Group byは同じものを纏める事ですから、複数なのかどうかの判断が必要です。
単純なものではhavingを用います

SQL

1SELECT * 2FROM item_informations 3WHERE item_id IN ( 4 SELECT item_id 5 FROM item_informations 6 GROUP BY item_id 7 having count(*) > 1 8 ) 9ORDER BY id asc

新規のレコードの取得は以下のクエリで実現しました。

重複したものを除くなら上記の反転ですね。

SQL

1SELECT * 2FROM item_informations 3WHERE item_id not IN ( 4 SELECT item_id 5 FROM item_informations 6 GROUP BY item_id 7 having count(*) > 1 8 ) 9ORDER BY id asc

投稿2022/01/11 05:17

sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

GROUP BY item_id
で取得しているのは、新規、というより、item_idのユニークな(重複のない)リストです。

重複しているレコードを取得したいのであれば、
1.COUNTとGROUP BYで同一のitem_idを持つレコードを数える
2.COUNTしたレコード数が2以上のものをHAVINGで絞り込む
といったことをするのが良いかと思います。

さっと検索しただけですが、以下の記事などが参考になるのではないでしょうか。
https://johobase.com/extracts-duplicate-records-sql/

また、新規か重複かを一度に判断できるようにしたいのであれば、以下のようにrow_number()関数を使う等でもよいかもしれません。

sql

1select 2 id, 3 item_id, 4 row_number() over (partition by item_id order by id) as choufuku_count 5from 6 hoge

投稿2022/01/11 05:13

JPYJPY

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siroyuri

2022/01/11 09:25

回答ありがとうございます。 「ユニークな(重複のない)リスト」というのは、見えていないだけで重複している全てのレコードの情報も同時に取得されているのでしょうか? だからNOT INでサブクエリに使用しようとすると全てのレコードが除外されてしまう、という考えでいいのでしょうか?
JPYJPY

2022/01/11 14:08

なるほど、気になっているのは先のクエリで何も返ってこない理由の方ですね。 サンプルのテーブルの通りだとしたら返ってこない理由がちょっと思いつかないですが、実際のテーブルにnullが含まれている場合は返ってこない場合があります。 https://www.ilovex.co.jp/blog/system/cat820/sqlnot-in.html サンプルが実データだとしたらすみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問