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

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

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

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

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

Q&A

3回答

777閲覧

サブクエリを用いたデータの取得

退会済みユーザー

退会済みユーザー

総合スコア0

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

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

0グッド

1クリップ

投稿2020/05/02 21:59

編集2020/05/02 22:56

SELECT文で取得するカラム名を指定する箇所でサブクエリを使って、countriesテーブル内のすべての国について,対応するcountries.idをusers.country_idに持つユーザー数を取得したいです。

usersテーブル

idnamecountry_id
1brian2
2emma2
3aubrey2
4mitsuru1
5brandon2
6shunji1

countriesテーブル

idname
1Japan
2USA
3China
4India

以下のSQLを作成して実行したのですが、「Japan,2 USA,4 China 0」という結果になり、Indiaのデータが取得できません。

SQL

1select name, 2( 3 select count(*) 4 from users 5 where country_id = c.id 6) as user_count 7from countries as c;

「Japan,2 USA,4 China 0 India 0」という結果を得るためには、上記のSQLをどのように修正すればよろしいでしょうか?
よろしくお願いいたします。

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

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

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

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

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

Orlofsky

2020/05/02 22:19

質問のテーブル定義はCREATE TABLEに、テーブル中のデータはINSERTに https://teratail.com/help/question-tips#questionTips3-7 の [コード] で見易さを考えて修正できた方が適切なコメントが付き易いです。 SELECTも上記のMarkdownに含めてね。
Orlofsky

2020/05/02 23:21 編集

SQLでSELECTを実行する為にはCREATE TABLEが実行されてテーブルが存在していなければなりません。SELECTを実行した時にテーブル内に存在するデータを取得される為には、既にデータがINSERTされていなければなりません。(これを理解できなかったら職業を変えた方が人生失敗が少ないです) CREATE TABLEやINSERTとは Markdown の表で提示しろ、って意味ではありません。 https://www.dbonline.jp/sqlite/table/index1.html https://www.dbonline.jp/sqlite/insert/index1.html
guest

回答3

0

ヒントで(動作確認していません)

SQL

1select 2 c.name 3 , u.count(*) as counts -- u.count(*) → count(*) で良いかも? 4from countries as c 5left outer join users as u 6on c.id = u.coutry_id -- キャプチャが coutry_id 7group by c.name 8;

投稿2020/05/02 22:28

Orlofsky

総合スコア16417

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

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

退会済みユーザー

退会済みユーザー

2020/05/02 23:08

ご回答ありがとうございます。 いただいたヒントを元に以下のSQLを実行したところ、 「Japan,2 USA,4 China 1 India 1」という結果が返ってきました。 select c.name, count(*) as counts from countries as c left outer join users as u on c.id = u.country_id group by c.name; countryテーブル内のidにusersテーブルのChinaとIndiaのcountry_idは存在しないので 0が出力されると思ったのですが、SQLにさらに変更を加える必要がありますでしょうか?
Yasumichi

2020/05/02 23:56 編集

count(u.name) に変えたらどうなりますか?
m.ts10806

2020/05/03 00:00

「ヒント」なのでそのまま使えると思わない方が良いのではと・・・。 考え方を活かしてやってみてはどうでしょうか。
Orlofsky

2020/05/03 00:10

はい、ヒントはあくまでもヒントです。 汗水流さないと身につかないこともありますから、 最近、皆さん甘やかし過ぎかと思うことも?
kaikubo_ko

2021/04/27 03:55

上司でもないのに質問サイトで何言ってるんだか・・・ ここは技術指導する場所ではないですよ????
Orlofsky

2021/04/27 04:34

最近は目先のコストを最優先する会社が多く、若い技術者に大切な情報を伝承する機会が極端になくなりました。 たまにOracle Database のパフォーマンス・チューニング案件が来ると処理時間が半分以下に改善できるようなものばかりです。最初から呼んでもらえたら何億円も浮いただろうに。
guest

0

SELECT文で取得するカラム名を指定する箇所でサブクエリを使って

という条件なら、CASE文でデータが取得できない場合(NULLの場合)は0とすれば良いのでは。
すでについてる他の回答はJOINを使ってるのでこの条件を満たしてないように思えますが。

投稿2020/05/03 02:17

gentaro

総合スコア8947

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

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

退会済みユーザー

退会済みユーザー

2020/05/03 02:21

確かにそうですね。
guest

0

ご提示していただいたサブクエリですとusersテーブルにIDがないためIndiaのデータを
カウントすることはできません。

理解を深めるために下記を参考にされるといいかと思います・・・。

Qiita SQL素人でも分かるテーブル結合(inner joinとouter join)

内部結合、外部結合について、インターネットで調べると色々出てきます。

投稿2020/05/02 22:10

編集2020/05/02 22:12
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/05/02 23:04 編集

すみません。DB名とかテーブル名とか検証用にいじったので少しちがうかもしれないことをご了承ください。MariaDB (mysql)の例です。 MariaDB [kuni]> select c.name,count(u.contry_id) as '件数' from contry as c left outer join users as u on c.id = u.contry_id group by c.name; +-------+------+ | name | 件数 | +-------+------+ | CHINA | 0 | | India | 0 | | japan | 2 | | USA | 4 | +-------+------+ 4 rows in set (0.00 sec) create database kuni; use kuni create table users( id int, name varchar(20), contry_id int ); create table contry( id int, name varchar(20) ); insert into users(id,name,contry_id) values('1','brian','2'); insert into users(id,name,contry_id) values('2','emma','2'); insert into users(id,name,contry_id) values('3','aubery','2'); insert into users(id,name,contry_id) values('4','mitsuru','1'); insert into users(id,name,contry_id) values('5','brandon','2'); insert into users(id,name,contry_id) values('6','shunji','1'); insert into contry(id,name) values('1','japan'); insert into contry(id,name) values('2','USA'); insert into contry(id,name) values('3','CHINA'); insert into contry(id,name) values('4','India');
退会済みユーザー

退会済みユーザー

2020/05/02 22:58

ご回答ありがとうございます。 テーブル結合について理解が不足していたので、 添付いただいたリンク等を参考に理解を深めていきます。
m.ts10806

2020/05/02 23:56

ymakotoさん テーブル名、カラム名はあわせてあげてください。 contry はそもそも英語として存在しないような。
退会済みユーザー

退会済みユーザー

2020/05/03 02:20

そうですね。ありがとうございます。
退会済みユーザー

退会済みユーザー

2020/05/03 08:35

ymakotoさん ご教授いただいた例で実行したところ、countriesテーブル内のすべての国について、対応するcountries.idをusers.country_idに持つユーザー数を取得することができました。 しかし、「Chine,0 India,0 Japan,2 USA,4」の順に取得されますが、今回は「Japan,2 USA,4 China,0 India,0」の順に取得する必要があります。 order by句を用いて並び替えを試みましたが、group by句と併用する際にはselect句の列を指定しなければならないとのことで行き詰まってしまいました。 もし可能であれば、並び替えについて手を貸していただけますと幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問