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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

3回答

4006閲覧

MySQL副問い合わせについて

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2020/06/30 13:15

編集2020/07/01 12:54

副問い合わせについて

SQL

1 2create table asobi_a(name varchar(50),flag int,jotai varchar(2),sex int,age int); 3insert into asobi_a values("a",0,"00","0",21); 4insert into asobi_a values("b",0,"00","1",18); 5insert into asobi_a values("c",0,"00","1",15); 6insert into asobi_a values("d",0,"00","0",21); 7insert into asobi_a values("e",0,"00","1",42); 8insert into asobi_a values("f",0,"00","0",34); 9insert into asobi_a values("g",0,"00","0",76); 10insert into asobi_a values("h",0,"00","0",18); 11insert into asobi_a values("i",0,"00","1",20); 12insert into asobi_a values("j",0,"00","1",35); 13insert into asobi_a values("k",0,"00","1",16); 14insert into asobi_a values("l",0,"00","0",26); 15insert into asobi_a values("m",0,"00","0",53); 16insert into asobi_a values("n",0,"00","0",21); 17insert into asobi_a values("o",0,"00","1",32); 18+------+------+-------+------+------+ 19| name | flag | jotai | sex | age | 20+------+------+-------+------+------+ 21| a | 0 | 00 | 0 | 21 | 22| b | 0 | 00 | 1 | 18 | 23| c | 0 | 00 | 1 | 15 | 24| d | 0 | 00 | 0 | 21 | 25| e | 0 | 00 | 1 | 42 | 26| f | 0 | 00 | 0 | 34 | 27| g | 0 | 00 | 0 | 76 | 28| h | 0 | 00 | 0 | 18 | 29| i | 0 | 00 | 1 | 20 | 30| j | 0 | 00 | 1 | 35 | 31| k | 0 | 00 | 1 | 16 | 32| l | 0 | 00 | 0 | 26 | 33| m | 0 | 00 | 0 | 53 | 34| n | 0 | 00 | 0 | 21 | 35| o | 0 | 00 | 1 | 32 | 36+------+------+-------+------+------+ 37create table asobi_b(bl char(2),name varchar(50)); 38insert into asobi_b values("a","a"); 39insert into asobi_b values("o","b"); 40insert into asobi_b values("ab","c"); 41insert into asobi_b values("a","d"); 42insert into asobi_b values("b","e"); 43insert into asobi_b values("b","f"); 44insert into asobi_b values("b","g"); 45insert into asobi_b values("o","h"); 46insert into asobi_b values("a","i"); 47insert into asobi_b values("a","j"); 48insert into asobi_b values("a","k"); 49insert into asobi_b values("o","l"); 50insert into asobi_b values("a","m"); 51insert into asobi_b values("b","n"); 52insert into asobi_b values("ab","o"); 53+------+------+ 54| bl | name | 55+------+------+ 56| a | a | 57| o | b | 58| ab | c | 59| a | d | 60| b | e | 61| b | f | 62| b | g | 63| o | h | 64| a | i | 65| a | j | 66| a | k | 67| o | l | 68| a | m | 69| b | n | 70| ab | o | 71+------+------+ 72 73select 74 sex,count(*) 75from 76 asobi_a 77where 78 age IN 79( 80select 81 sex,avg(AGE) 82from 83 asobi_a,asobi_b 84where 85 ((asobi_b.bl = "a" and asobi_a.sex = "0") 86 or (asobi_b.bl = "o" and asobi_a.sex = "1")) 87 and asobi_b.bl in("a","o") 88 and (asobi_a.name = asobi_b.name 89 and asobi_a.FLAG = 0 and asobi_a.JOTAI = "00") 90group by 91 sex 92) 93group by 94 sex; 95

副問い合わせの中は大まかに言えば血液型がaかつ、男性か、血液型がoかつ、女性の人の平均年齢を性別ごとに求めています。

そして、副問い合わせが
(asobi_b.bl = "a" and asobi_a.sex = "0")の場合asobi_a.sex = "0"の平均年齢と一致する人を、(asobi_b.bl = "o" and asobi_a.sex = "1")の場合asobi_a.sex = "0"の平均年齢と一致する人を
出力したいのですが、今のSQL文だと、where句の中に、age in や sex = "0" などとりあえず入れてみたものの
ERROR 1241 (21000): Operand should contain 1 column(s)
と出てしまいます。

エラーが出る原因も何をすればエラーが出ないのかも分かりません。ぜひわかれば教えて頂きたいです。

バージョンは8.0です。

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

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

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

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

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

hope_mucci

2020/06/30 15:39

MySQLのバージョンを書きましょう。編集で本文を修正してください。 特に8.0以降かどうかで回答が大幅に変わる可能性があります。
hope_mucci

2020/07/01 02:39

Orlofskyさんがおっしゃるようにテーブル定義、サンプルデータがないと回答のしようがありません。回答者側でテストができないし、以下のようなことが判然としないので。 ・asobi_aテーブルとasobi_bテーブルの役割がどういうものかが質問文からわかりません。 ・両テーブルの結合条件がコードから正しいのかも分かりません。 ・sexとageはどちらのテーブルに所属しているのかもわかりません。
退会済みユーザー

退会済みユーザー

2020/07/01 12:56

返信が大変遅くなり申し訳ございませんでした。 ただいま編集させていただきました。 また足りていないところがございましたら教えていただけると嬉しいです。
hope_mucci

2020/07/01 13:45

まだ真に実施したいことが見えてきません。 男性側だけに問題を絞ると、以下のどちらかを集計したいと見えますがどちらでしょうか。 ・A型の男性の集団に対し、「その集団の平均年齢」と一致する人物の人数を計算する ・A型の男性の集団に対し、「男性全体の平均年齢」と一致する人物の人数を計算する
退会済みユーザー

退会済みユーザー

2020/07/02 03:48

2番目の男性全体の方です! 説明が下手くそで申し訳ないです。
guest

回答3

0

ベストアンサー

質問のクエリがエラーになる原因

sql

1where age IN ( サブクエリ )

のサブクエリの中身が2列以上の結果を返すからです。
IN句の中身をサブクエリで表現するには、何行あっても良いですが1列で返さないといけません。

問題解決

上記のクエリは一度ご破算にして、一からどうすればいいか考えます。

手順としては、

  • 男女別の平均年齢を求める
  • 特定の血液型の人間に対し、同性の平均年齢と一致するかどうかを調べる

となるでしょう。これを順番に解決していきます。

※MySQL8.0から導入された共通テーブル式(with句)の知識が必須です。

まず、男女別の平均年齢を求めます。これは簡単にできると思います。sexでgroup byしてavgを取るだけです。

sql

1select 2 ta.sex 3 ,avg(ta.age) as avg_age 4from 5 asobi_a ta, asobi_b tb 6where 7 ta.name = tb.name 8 and ta.flag = 0 9 and ta.jotai = "00" 10group by 11 ta.sex
sexavg_age
033.7500
125.4286

次に、A型男性に対し、上記平均年齢と一致する人数が何人いるか数えます。
whereでA型男性であるかと年齢が男性平均年齢と一致するかを指定します。
血液型と年齢は別テーブルなのでnameで結合します。

sql

1select 2 'sex=0,bl=A' as caption 3 ,count(*) 4from asobi_a as ta, asobi_b as tb 5where 6 ta.name = tb.name 7 and ta.sex = 0 and tb.bl = 'a' -- 男性かつA型 8 and ta.age = ( /* 男性平均年齢 */ )

コメントの男性平均年齢の部分をどうするかというと、with句を用いて先に平均年齢のクエリを作成し、後続のSQLでコメントの部分にサブクエリとして投入します。

sql

1with q1 as ( -- q1という別名で性別平均年齢の表を作成 2 select 3 ta.sex 4 ,avg(ta.age) as avg_age 5 from 6 asobi_a as ta 7 where 8 ta.flag = 0 9 and ta.jotai = "00" 10 group by 11 ta.sex 12) 13select 14 'sex=0,bl=A' as caption 15 ,count(*) 16from asobi_a as ta, asobi_b as tb 17where 18 ta.name = tb.name 19 and ta.sex = 0 and tb.bl = 'a' -- 男性かつA型 20 and ta.age = 21 (select tq1.avg_age from q1 as tq1 where tq1.sex=0) -- ageが男性の平均年齢と一致すれば抽出

この場合のサブクエリが返す結果は、スカラ値(1行1列)でないとエラーになります。
残念ながらテストデータでは1件も抽出されませんが、このように複雑でないクエリの組み合わせで解を得ることができます。

もう一つの「女性O型」を抽出する場合、同じようにselect文を作り、union allするのが良いかと思います。この方法なら他の複雑な条件も含めて抽出する必要がある場合でも容易に対応できるかと思います。

sql

1(withの部分は同じなので略) 2select 3 'sex=0,bl=A' as caption 4 ,count(*) 5from asobi_a as ta, asobi_b as tb 6where 7 ta.name = tb.name 8 and ta.sex = 0 and tb.bl = 'a' -- 男性かつA型 9 and ta.age = 10 (select tq1.avg_age from q1 as tq1 where tq1.sex=0) -- ageが男性の平均年齢と一致すれば抽出 11union all 12select 13 'sex=1,bl=O' as caption 14 ,count(*) 15from asobi_a as ta, asobi_b as tb 16where 17 ta.name = tb.name 18 and ta.sex = 1 and tb.bl = 'o' -- 女性かつO型 19 and ta.age = 20 (select tq1.avg_age from q1 as tq1 where tq1.sex=1) -- ageが女性の平均年齢と一致すれば抽出

投稿2020/07/02 06:02

hope_mucci

総合スコア4447

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

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

退会済みユーザー

退会済みユーザー

2020/07/03 15:52

わざわざご丁寧にありがとうございます!! こちらを参考に作成したら完成しました!!本当にありがとうございます!!
guest

0

項目名はすべて小文字なのですね。
また、男性は男性の平均年齢なのでasobi_a.sex = '1'ですね。
質問にあるデータだと一致するレコードはないですが、以下のようになると思います。
(女性の血液型をB型にすれば1件ヒットします。)

SQL

1select 2 sex,count(*) 3from 4 asobi_a,asobi_b 5where 6 (asobi_b.bl = 'a' and asobi_a.sex = '0' 7 and asobi_a.age = (select round(avg(age)) from asobi_a where asobi_a.sex = '0') 8 or 9 asobi_b.bl = 'o' and asobi_a.sex = '1' 10 and asobi_a.age = (select round(avg(age)) from asobi_a where asobi_a.sex = '1')) 11 and asobi_a.name = asobi_b.name 12 and asobi_a.flag = 0 and asobi_a.jotai = '00' 13group by 14 sex;

投稿2020/07/01 04:00

編集2020/07/01 13:34
etsuhisa

総合スコア416

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

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

退会済みユーザー

退会済みユーザー

2020/07/01 13:00

ご回答ありがとうございます。 教えていただいた通りやってみたのですがやはりエラーが出てしまいました。 ただいま編集しましたのでまた何かわかることがありましたら教えていただけると嬉しいです。 また、男性は男性の、女性は女性の平均年齢と一致する人数を知りたいです。 説明がへたくそで申し訳ないです。
etsuhisa

2020/07/01 13:40

SQLを質問のテーブルに合わせて書き換えました。
退会済みユーザー

退会済みユーザー

2020/07/03 15:53

何度もありがとうございます!! とても参考になりました!!
guest

0

具体的な情報がないのでなんとも言えませんがSQL文をみるかぎり
where句が条件文になっていないので、文法的におかしいと思います

投稿2020/07/01 03:41

yambejp

総合スコア116724

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

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

退会済みユーザー

退会済みユーザー

2020/07/01 13:01

ご回答ありがとうございます。 where句には何を入れてもエラーになってしまったので何も入れていないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問