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

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

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

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

SQL

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

Q&A

解決済

6回答

2339閲覧

SQLのみで条件に従った番号を振りたい

kuniatsu

総合スコア141

MySQL

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

SQL

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

1グッド

0クリップ

投稿2017/08/12 00:53

SQL & javaでやっている処理なのですが、もしSQLのみで出来たら素敵だなと思い質問します。

日付,天気,気温
0801,晴れ,25
0802,晴れ,24
0803,雨,20
0804,雨,19
0805,雨,20
0806,雨,20
0807,晴れ,26

このようなテーブルがあった場合に

日付,天気,気温,連続雨記録
0801,晴れ,25,0
0802,晴れ,24,0
0803,雨,20,1
0804,雨,19,2
0805,雨,20,3
0806,雨,20,4
0807,晴れ,26,0
0809,雨,19,1
0810,雨,21,2

のように番号を振ったり

日付,天気,気温,連続雨記録(20度以上)
0801,晴れ,25,0
0802,晴れ,24,0
0803,雨,20,1
0804,雨,19,0
0805,雨,20,1
0806,雨,20,2
0807,晴れ,26,0
0809,雨,19,0
0810,雨,21,1

のように条件をつけて番号を振る事SQLはどのように書けばよいでしょうか?

yodel👍を押しています

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

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

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

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

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

sazi

2017/08/13 00:25

ここで言う連続とは、2日間以上連続するものが該当することでしょうか?そうであるなら、20度以上の方はサンプルが誤りですよね?
kuniatsu

2018/07/09 11:59

サンプルが誤りですね。すみませんでした。
guest

回答6

0

SQLで作成してみました。

sql

1CREATE TABLE `weth` ( `hiduke` date, `tenki` text, `kion` int); 2insert into `weth` values 3('20170801','晴れ',25), 4('20170802','晴れ',24), 5('20170803','雨',20), 6('20170804','雨',19), 7('20170805','雨',20), 8('20170806','雨',20), 9('20170807','晴れ',26), 10('20170809','雨',19), 11('20170810','雨',21); 12 13SELECT DATE_FORMAT(t4.`hiduke`,'%m%d') `日付`, t4.`tenki` `天気`, t4.`kion` `気温`, 14 CASE WHEN `tenki`=`tenki2` AND `tenki`='雨' THEN @n:=@n+1 ELSE 15 CASE WHEN `tenki`='雨' THEN @n:=1 ELSE @n:=0 END END `連続雨記録` 16FROM ( 17 SELECT t1.*, `tenki2`, `kion2` FROM `weth` t1 18 LEFT JOIN 19 (SELECT DATE_ADD(`hiduke`, INTERVAL 1 DAY) `hiduke`, `tenki` `tenki2`, `kion` `kion2` FROM `weth`) t2 20 USING(`hiduke`) ORDER BY t1.`hiduke` 21) t4, (SELECT @n:=0) t5; 22 23 24SELECT DATE_FORMAT(t4.`hiduke`,'%m%d') `日付`, t4.`tenki` `天気`, t4.`kion` `気温`, 25 CASE WHEN `tenki`=`tenki2` AND `tenki`='雨' AND `kion`>=20 AND `kion2`>=20 THEN @n:=@n+1 ELSE 26 CASE WHEN `tenki`='雨' AND `kion`>=20 THEN @n:=1 ELSE @n:=0 END END `連続雨記録(20度以上)` 27FROM ( 28 SELECT t1.*, `tenki2`, `kion2` FROM `weth` t1 29 LEFT JOIN 30 (SELECT DATE_ADD(`hiduke`, INTERVAL 1 DAY) `hiduke`, `tenki` `tenki2`, `kion` `kion2` FROM `weth`) t2 31 USING(`hiduke`) ORDER BY t1.`hiduke` 32) t4, (SELECT @n:=0) t5;

投稿2017/08/12 15:48

編集2017/08/12 15:49
A.Ichi

総合スコア4070

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

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

sazi

2017/08/12 16:12

お、素敵ですね。 私は、日付が日付型ですか?とは怖くて聞けなかったw
A.Ichi

2017/08/12 16:21

はい、実はそこは悩み、計算に適当な年をコンカチしてCASTしようかなとも思いましたが、簡単そうに見せました。(うるう年もありますし)
sazi

2017/08/12 16:31

試してみましたが、上手くいっていない部分がありますね。 7/31に雨、8/11に晴、8/12に雨を追加してみて下さい。 7/31と8/12が連続雨として出力されます。
A.Ichi

2017/08/12 16:45 編集

ここは私も迷ったのですが、例題が連続が無くても雨と気温の両方で1としてカウントしているように見えたので、(20度以上)にケースに合わせました。
sazi

2017/08/12 17:14 編集

確かに気温の方は8/3と8/10が連続になってますね。 でも、流石にそれは連続とは言わないと思うので、記述ミスかなぁ。
A.Ichi

2017/08/12 17:04

私も最初、連続が開始しするものを1とする様に作成しましたが、それでは(20度以上)だと違ってしまい変更しました。 SELECT DATE_FORMAT(t4.`hiduke`,'%m%d') `日付`, t4.`tenki` `天気`, t4.`kion` `気温`, CASE WHEN `tenki`=`tenki2` AND `tenki`='雨' THEN @n:=@n+1 ELSE CASE WHEN `tenki`=`tenki3` AND `tenki`='雨' THEN @n:=1 ELSE @n:=0 END END `連続雨記録` FROM ( SELECT t1.*, `tenki2`, `kion2`, `tenki3`, `kion3` FROM `weth` t1 LEFT JOIN (SELECT DATE_ADD(`hiduke`, INTERVAL 1 DAY) `hiduke`, `tenki` `tenki2`, `kion` `kion2` FROM `weth`) t2 ON t1.`hiduke`=t2.`hiduke` LEFT JOIN (SELECT DATE_SUB(`hiduke`, INTERVAL 1 DAY) `hiduke`, `tenki` `tenki3`, `kion` `kion3` FROM `weth`) t3 ON t1.`hiduke`=t3.`hiduke` ORDER BY t1.`hiduke` ) t4, (SELECT @n:=0) t5;
退会済みユーザー

退会済みユーザー

2018/09/16 22:27

幸運にも期待通りの結果を得られるかもしれませんが、それが確約されないSQLで、 論外の品質なので、マイナス投票します。 http://download.nust.na/pub6/mysql/doc/refman/5.1/ja/user-variables.html >基本的なルールは、ステートメントの一部でユーザ変数値を割り当てないこと >および同一ステートメント内の他部分で同じ変数を使用しないことです。 >期待通りの結果を得られるかもしれませんが、これは確約されていません。
sazi

2018/09/17 00:59

>sql_loverさん 引用されているURL内に、 「SET以外のステートメントで、ユーザ変数に値を割り当てることもできます。この場合、代入演算子は:=でなくてはならず、=ではありません。」 とあるようにステートメント内での変数への値設定は非推奨ではありません。 「ステートメントの一部でユーザ変数値を割り当てないことおよび同一ステートメント内の他部分で同じ変数を使用しないことです。」は誤解を生む翻訳になっています。 そこは、「ステートメントの一部でユーザ変数値の割り当てと同一ステートメント内の他部分で同じ変数を参照を同時にしないことです。」 ということで、「単一ステートメント内で、同変数を設定・使用してはいけません。」という別表現されています。 指摘は@変数を使う際の連番作成のSQLで良く言われている事ですけど、鵜呑みにはされない方が良いと思います。
mysql_help

2018/11/17 07:05

退会済ユーザ様 減点するなら下記の2点がより適切です。 https://dev.mysql.com/doc/refman/5.6/ja/user-variables.html >SET ステートメント以外では、同じステートメント内で、 >ユーザー変数に値を割り当ててその値を読み取ることは決してしないでください。 という記載に反して、割り当てた値を、読み取っていることが1点目。 select文の結果が10行なら、同じユーザ変数への10回以上の読取と割当を行ってます。 select文でのユーザ変数への値の代入は5.7で非推奨になり、8.0以降で削除予定の機能であることが2点目。 http://www.mysql.gr.jp/mysqlml/mysql/msg/16488
退会済みユーザー

退会済みユーザー

2019/01/02 02:48

mysql_help様 MySQLの開発者がブログに ”インラインビューでのユーザ変数の初期化は、MySQLが賢くなったらスキップします” と書いてるのを3点目に追加して下さい。 http://www.mysql.gr.jp/mysqlml/mysql/msg/16495
guest

0

row_number(),lag(),lead(),with式が使えないmysqlでは、自己結合による問い合わせをSQLでやっても素敵にはなりません。(できないという意味ではありません)
※素敵という表現は、「シンプル、高速」と解釈しています。

javaで既に作成されているなら、そのままの方がよろしいかと。

また、javaでの処理に課題があるなら、そちらを質問された方が良いかと思います。

投稿2017/08/12 06:38

sazi

総合スコア25138

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

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

0

日付が必ず連続しているという前提であれば、
各日付に対して

  • 連続記録の条件をみたす場合、
    0. その日より前の日付かつ、連続記録の条件を満たさない日付の最大を取り、
    1. その日付との日数の差分を取る
  • 連続記録の条件をみたさない場合、
    0. 0を取る

ようにすれば、意図通りの結果が得られます。

sql

1SELECT 2 w.*, 3 IF ( 4 w.wether = '雨', 5 ( 6 SELECT DATEDIFF(w.`date`, x.`date`) 7 FROM wethers AS x 8 WHERE x.`date` < w.`date` 9 AND x.wether <> '雨' 10 ORDER BY `date` DESC 11 LIMIT 1 12 ), 13 0 14 ) AS continuous_rain, 15 IF ( 16 w.wether = '雨' AND w.temperature >= 20, 17 ( 18 SELECT DATEDIFF(w.`date`, x.`date`) 19 FROM wethers AS x 20 WHERE x.`date` < w.`date` 21 AND NOT (x.wether = '雨' AND x. temperature >= 20) 22 ORDER BY `date` DESC 23 LIMIT 1 24 ), 25 0 26 ) AS continuous_rain_20 27FROM wethers AS w;

実行結果
http://sqlfiddle.com/#!9/17331ed/1


ただし、質問文にご提示のように日付に歯抜けがある場合、

0807,晴れ,26,0 0809,雨,19,1 <- 0808 が抜けている 0810,雨,21,2

上の方法ではうまく行きません。

実行結果(2017-08-09 と 2017-08-10 のcontinuous_rain列の値がおかしい)
http://sqlfiddle.com/#!9/7ee589/1

---
いずれにせよ、MySQL はこのような「行の順番」を考慮した集計処理を苦手としている上に、
回答に上げた SQL文は「相関サブクエリ」と呼ばれるもので、
レコード数が多くなると耐えられないほど遅くなる可能性が高いです。
http://nippondanji.blogspot.jp/2009/03/mysql_25.html

そのため、集計テーブルを作り、日時のバッチ処理でその集計テーブルにデータを保存しておくか、
他の回答者様の提言どおり Java側で処理したほうが、シンプルに実装できると思います。

投稿2017/08/12 07:58

KiyoshiMotoki

総合スコア4791

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

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

0

こちらのサイトで詳しく解説されているので、参考にしてみてはいかがでしょうか?

最大連勝、連敗を抽出するSQL | 泥庭

投稿2017/08/12 03:23

miyahan

総合スコア3095

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

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

sazi

2017/08/12 05:09 編集

リンク先で使用しているDBはmysqlじゃないですね。mysqlはrow_number()使えないので。
sazi

2017/08/12 06:02

失礼。row_number()部分は別解ですね。
miyahan

2017/08/12 07:20

いえ。札束(ベンダの独自機能)で殴ればシンプルに書けて高速に実行できるけれど、素のSQLだと恐ろしく長いSQL文になるし、相関サブクエリなので速度もアプリ側で処理するより遅くなる可能性があるという教訓が載っている良い記事だったので紹介しました。
guest

0

ベストアンサー

A.Ichi様のテーブルとデータをお借りしました。

2パターンほど記載しておきます。

1パターン目はKiyoshiMotokiさんの歯抜けOK版です。
(同一日付の重複も一応OKにしてますが、重複の際の連続ルールは適当です)

2パターン目は同一日付の重複はない前提で、
A.Ichiさんの抽出を更に1つにした感じです。(同一日時OKにする場合、V1の中身でhidukeで集約)

どうするかは、細かい仕様次第ですが、個人的には2パターン目の方が好みです。

SQL

1SELECT DATE_FORMAT(T1.`hiduke`,'%m%d') as `日付` 2 , T1.tenki as `天気` 3 , T1.kion as `気温` 4 , ifnull( 5 ( 6 SELECT COUNT(distinct T2.hiduke) 7 FROM weth T2 8 WHERE T2.hiduke > ( 9 SELECT MAX( T3.hiduke ) as hiduke 10 FROM weth T3 11 WhERE T1.tenki = '雨' 12 AND T3.tenki <> '雨' 13 AND T3.hiduke < T1.hiduke 14 ) 15 AND T2.hiduke <= T1.hiduke 16 AND T2.tenki = '雨' 17 ) 18 , 0 19 ) as `連続雨記録` 20 , ifnull( 21 ( 22 SELECT COUNT(distinct T4.hiduke) 23 FROM weth T4 24 WHERE T4.hiduke > ( 25 SELECT MAX( T5.hiduke ) as hiduke 26 FROM weth T5 27 WHERE T1.tenki = '雨' 28 AND T1.kion >= 20 29 AND ( 30 T5.tenki <> '雨' 31 OR T5.kion < 20 32 ) 33 AND T5.hiduke < T1.hiduke 34 ) 35 AND T4.hiduke <= T1.hiduke 36 AND T4.tenki = '雨' 37 AND T4.kion >= 20 38 ) 39 , 0 40 ) as `連続雨記録(20度以上)` 41FROM weth T1 42ORDER BY T1.hiduke 43; 44 45 46SELECT DATE_FORMAT(V1.`hiduke`,'%m%d') as `日付` 47 , V1.tenki as `天気` 48 , V1.kion as `気温` 49 , ( 50 CASE 51 WHEN V1.tenki = '雨' 52 AND V1.mae_tenki = '雨' THEN @n:=@n+1 53 WHEN V1.tenki = '雨' THEN @n:=1 54 ELSE @n:=0 55 END 56 ) as ame 57 , ( 58 CASE 59 WHEN V1.tenki = '雨' 60 AND V1.kion >= 20 61 AND V1.mae_tenki = '雨' 62 AND V1.mae_kion >= 20 THEN @m:=@m+1 63 WHEN V1.tenki = '雨' 64 AND V1.kion >= 20 THEN @m:=1 65 ELSE @m:=0 66 END 67 ) as ame20 68FROM ( 69 SELECT T1.hiduke 70 , T1.tenki 71 , T1.kion 72 , T2.tenki as mae_tenki 73 , T2.kion as mae_kion 74 FROM weth T1 75 LEFT JOIN weth T2 ON( 76 T2.hiduke = ( T1.hiduke - INTERVAL 1 DAY ) 77 ) 78 ORDER BY T1.hiduke 79 ) V1 80 , ( SELECT @n:=0 ) T3 81 , ( SELECT @m:=0 ) T4 82;

あと、記載しませんでしたが、「2日以上連続していない場合、1ではなく0にする」については、
そんなに難しくないので、記載してません。
(考え方としては、当日がOKで前日と翌日がNGの場合、0とするという表現を付け加えるだけです。)

投稿2017/08/13 17:35

tomari_perform

総合スコア760

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

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

退会済みユーザー

退会済みユーザー

2018/09/16 22:28

幸運にも期待通りの結果を得られるかもしれませんが、それが確約されないSQLで、 論外の品質なので、マイナス投票します。 http://download.nust.na/pub6/mysql/doc/refman/5.1/ja/user-variables.html >基本的なルールは、ステートメントの一部でユーザ変数値を割り当てないこと >および同一ステートメント内の他部分で同じ変数を使用しないことです。 >期待通りの結果を得られるかもしれませんが、これは確約されていません。
sazi

2018/09/17 01:14

別回答でコメントしたように、こちらも、 「(参照順序が保証されないので)単一ステートメント内で、同変数を設定・使用してはいけません。」という状況にはなっていません。
tomari_perform

2018/09/17 17:49 編集

sazi様、補足ありがとうございます。 sql_loverさんが勘違いされてるだけとは思いますが、私からも補足しますね。 「幸運」という表現を使うということは、sql_loverさん的には、 今回の条件で、期待通りの結果が出ないケースがあるってことだと思うので、 そのようなケースがあるなら、以下のケースを除いたもので教えて頂きたいです。 (思いつく例外ケース) 今回提示したSQL部分以外で、 set @m='hogehoge'; set @n='hogehoge2'; 等の設定が既に存在し、@mや@nを利用したSQLがあり、かつ、 上記設定と@mや@nを利用したSQLの間に今回提示したSQLが存在している場合 なお、 , ( SELECT @n:=0 ) T3 , ( SELECT @m:=0 ) T4 の部分を、SQL上に記載せず、 set @m=0; set @n=0; とすべき、ということであれば、そこは記載を端折っただけではありますが、 SQLの処理順的には、SELECTよりFROMが先に処理されるので、 そこまでおかしくはない部分です。 また、 CASE文の中に@n:=が多すぎる? という事があるのでしたら、 1行内で複数実行されるケースはありませんので、 特別に問題がある内容ではありません。 ○最後に、各指摘内容について >基本的なルールは、ステートメントの一部でユーザ変数値を割り当てないこと ⇒あくまで、基本。複数行存在するテーブルをFROM句である場合、  SELECT @n:=0をしたところで、普通は意味がないと解釈してます。  今回は基本的な使い方をしていませんよ。 >および同一ステートメント内の他部分で同じ変数を使用しないことです。 ⇒「同一ステートメント内」の解釈を勘違いされてると思います。  SELECT @n:=0,@n:=@n+1 等はしてはいけません。  という解釈になりますが、そのような使い方はしておりません。  おそらく「SELECT文内で、同じ変数を使用しない」等と勘違いされてませんか? >期待通りの結果を得られるかもしれませんが、これは確約されていません。 ⇒期待通りの結果を得られる「かも」ではありません。  同一ステートメント内の他部分で同じ変数を使用していませんので、  「期待通りの結果しか得られません」
mysql_help

2018/11/17 07:05

退会済ユーザ様 減点するなら下記の2点がより適切です。 https://dev.mysql.com/doc/refman/5.6/ja/user-variables.html >SET ステートメント以外では、同じステートメント内で、 >ユーザー変数に値を割り当ててその値を読み取ることは決してしないでください。 という記載に反して、割り当てた値を、読み取っていることが1点目。 select文の結果が10行なら、同じユーザ変数への10回以上の読取と割当を行ってます。 select文でのユーザ変数への値の代入は5.7で非推奨になり、8.0以降で削除予定の機能であることが2点目。 http://www.mysql.gr.jp/mysqlml/mysql/msg/16488
退会済みユーザー

退会済みユーザー

2019/01/02 02:47

mysql_help様 MySQLの開発者がブログに ”インラインビューでのユーザ変数の初期化は、MySQLが賢くなったらスキップします” と書いてるのを3点目に追加して下さい。 http://www.mysql.gr.jp/mysqlml/mysql/msg/16495
aiou

2019/04/06 14:07

mysql_help様 MySQLの開発者がブログに https://mysqlserverteam.com/row-numbering-ranking-how-to-use-less-user-variables-in-mysql-queries/ It works. But it relies on the fact that MySQL sets @rownum before setting @prev_sex, i.e. evaluates selected expressions from left to right. Which is true for this query, but not for all queries と書いてあるのも追加するべきですし tomari_perform様に、 同一ステートメントかの判定にはnow関数が使える点も指摘したほうがいいと思います。 https://qiita.com/AketiJyuuzou/items/cced9b70cc714b382d98 >マニュアルのステートメントという表現は、 >Select文、Update文、Insert文、Delete文において、その文全体を指して、1つのステートメントという意味です。 >(Now関数の結果が一致するため)
tomari_perform

2019/04/06 22:29 編集

お久しぶりです。 この質問を期に、teratailを利用しなくなった者です。 (フォロワーの方々、すいません) 結局のところ、指摘者は、以下の部分で、NGである、と言いたかったんですかね。 ```SQL , ( CASE WHEN V1.tenki = '雨' AND V1.mae_tenki = '雨' THEN @n:=@n+1 WHEN V1.tenki = '雨' THEN @n:=1 ELSE @n:=0 END ) as ame ``` つまり、ソートした後のデータでも、処理順は確約されてないから、 3行目、2行目、1行目の順で処理した後に、1行目から抽出する可能性があるから、 このSQLはNG!というのが、指摘者のご意見でしょう。 MySQLの中身を知らなければ、ブラックボックスである以上、その可能性もあるため、 指摘は正しいんでしょうね。 私は、このブラックボックスに対して、 私がMySQLを作ったら、わざわざソート後のINDEXもないデータがある状況で、 3行目2行目1行目を処理した後に1行目から抽出するようなプログラムなんて 並列処理でもしない限り、作るわけがない。という考えです。 また、当時のマニュアル上には、 はっきりと「SELECT @a, @a := @a+1」がNGと書いてあり、 ここの解釈において、 「1行の中の各項目の処理順は確約されていない。」と捉えるか、 「1つのSELECT文の中の処理順は確約されていない。」と捉えるか、の違いでしょう。 私は前者で捉え、実際に動かし、ブラックボックスを考えた結果、 「期待通りの結果しか得られません」と記載しており、 指摘者は後者で捉えたり、ブラックボックスにおいて、 上記の処理順の可能性があるからNGと言っているんですよね。 ここまで来ると、 どちらが正しいか?ステートメントの定義は何の単位なのか? ブラックボックスの中身は何なのか?については、 話自体が古いお話ですので、どちらでも良いですけどね。 このSQLをNGと言う指摘者は、使わなければ良い事だと思います。 (補足・参考) 今回、返信しようと思ったきっかけは「NOW()ではなく、SYSDATE()では?」 と記載しようとしたのですが、結局のところ、上記の話になるので、関係なかったですね。。 ```SQL SELECT NOW(),SYSDATE() FROM (100万行の) ORDER BY 1,2; ```
guest

0

Java が使えるなら、MySQLはデータストア専用と割り切って、今まで通りJavaで行うことをお勧めします。

投稿2017/08/12 05:17

hihijiji

総合スコア4150

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問