SQL質疑応答スレ 18問目

1NAME IS NULL2018/01/04(木) 22:12:22.14ID:???
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

SQLという言語はISOによって標準化されていますが
この標準を100%実装したDBMSは存在せず、
また、DBMSによっては標準でない独自の構文が
追加されていることもあります。

質問するときはDBMS名を必ず付記してください。

【質問テンプレ】
・DBMS名とバージョン
・テーブルデータ
・欲しい結果
・説明

前スレ:
SQL質疑応答スレ 17問目
https://mevius.5ch.net/test/read.cgi/db/1468157341/

610NAME IS NULL2018/11/03(土) 03:58:33.81ID:Pv5mB3Rz
最近JSONとか末尾カンマ無視するのあるよね
あれ導入されれば後ろでもいいんだけどな
前の方が行カット&ペーストで入れ替えやすい

611NAME IS NULL2018/11/03(土) 09:51:12.69ID:JBJEgXB4
前カンマの方が綺麗だと思うけどなあ
カンマと列名の間にタブなりスペースなり入れてカンマの位置を揃えるの
テキストエディタで矩形選択を使ってごりごり編集するのに便利なのだ

612NAME IS NULL2018/11/03(土) 10:58:19.38ID:???
人の好きずきの問題をここで語られても

613NAME IS NULL2018/11/03(土) 11:34:40.41ID:???
caseの件

614NAME IS NULL2018/11/04(日) 12:09:42.60ID:???
書式整形ソフト使って好きな形で読め。
--のコメントさえなければSQLは改行なし
で書けるんだから読むやつが好きに整形しろ。
ここで個人の好みの書式の話しされると
うざい!!

615NAME IS NULL2018/11/04(日) 12:23:08.21ID:???
ちょっと難しい問題を出してみて
そうしたら、多分静かになるから

616NAME IS NULL2018/11/11(日) 17:44:06.06ID:DVzqXgBV
そもそもカンマがいらなかったんだよな。

英文っぽくしたためにカンマ区切りにしてしまった。

列名の区切りは半角スペースか改行でよかった。

617NAME IS NULL2018/11/23(金) 19:38:48.29ID:NImj8hV3
質問させてください。
使っているのはSQLite(Python)です。

あるテーブルに、たとえば性別、血液型、職業というカラムがあって、
それぞれ、男、A、会社員、などと、データが入っているとします。
これら3つのカラムの中身について、テーブル内にある組み合わせの
パターンをすべて抽出したいのですが、sqlでどのように書けば効率がよいでしょうか?

抽出後、(男、A、会社員)は何名、(女、A、会社員)は何名、、、と
集計することが目的です。テーブルにより起こる組み合わせが様々なので、
都度調べる必要があります。

単純にFor文で1行ずつ調べて、過去にない組み合わせであれば外部のリストに
追加する形だと、非効率な気がしています。
良い方法があればお教えください。

6186172018/11/23(金) 19:43:01.73ID:???
ぐぐっていたら、下記を見つけました。

https://www.dbonline.jp/sqlite/select/index9.html

DISTINCT を使えばできそうです。
ありがとうございました。

619NAME IS NULL2018/11/23(金) 20:05:35.29ID:???
>>617
こうじゃないか

select `性別`,`血液型`,`職業`, count(*) as `人数`
from `テーブル`
group by`性別`,`血液型`,`職業`;

620NAME IS NULL2018/11/24(土) 03:57:01.05ID:???
効率悪いし、何名か?が取れないと思う

621NAME IS NULL2018/11/24(土) 03:58:33.86ID:???
distinctについてね

6226172018/11/24(土) 12:35:17.12ID:???
>>619

ありがとうございます。
助かりました。

623NAME IS NULL2018/11/24(土) 16:31:58.75ID:Pyo9iAE3
再び質問です。
教えてもらった

select `性別`,`血液型`,`職業`, count(*) as `人数`
from `テーブル`
group by`性別`,`血液型`,`職業`;

で得られる'人数’を同じテーブル内の別カラムに保存したいと思い、
カラムは事前に作成しておいて、

update 'テーブル' set '人数のカラム' =
(select `性別`,`血液型`,`職業`, count(*) as `人数`
from `テーブル`
group by`性別`,`血液型`,`職業`)

としてみたのですが、group byの最後のグループのcountの結果が
全部の行に上書きされてしまいます。

各行毎に所属するグループの人数を記録するにはどう書けばよいでしょうか。

(目的は、その人(各行)の所属するグループの人数を個別に保存することです。)

よろしくお願いします

624NAME IS NULL2018/11/24(土) 17:14:07.61ID:???
>>623
> 各行毎に所属するグループの人数を記録するにはどう書けばよいでしょうか。
> (目的は、その人(各行)の所属するグループの人数を個別に保存することです。)
そんな設計やめなよ…
レコードに追加/削除/更新する度にその人数も更新しないとだめだし
毎回求めてもよほどでかい表でない限りは問題にならないだろ

625NAME IS NULL2018/11/24(土) 17:28:12.86ID:???
>>623
使用意図はわからんが、どうしても一時的にテーブルに保存したきゃUPDATEじゃなくて、DELETE→INSERTでよくね?
オイラならテーブル変数使うけど

626NAME IS NULL2018/11/24(土) 17:32:36.45ID:???
>>624

コメントありがとうございます。
実はモデルをすり替えて質問していまして、
データを書き換えての繰り返し計算に使いたいのです。

その後、order by でなく、select以下のテーブルをtable as Tなどとしてwhere句で’テーブル’とTの要素が等しい時に限定したら一応できました

何故かブロックされたのでスマホから

627NAME IS NULL2018/11/24(土) 17:49:44.47ID:Pyo9iAE3
>>625
使用意図は、エクセルの表計算のように、
左のカラムにデータがあって、それを元に
右の方のカラムに途中計算を書いていって、
最後に得られた結果の誤差が減るように
また最初の方から計算を繰り返すような感じです。

1巡の計算が大きすぎて記録を残したいのですが、ご指摘の通り、記録が不要なところはテーブル変数がよさそうです
勉強してみます

628NAME IS NULL2018/11/24(土) 17:50:56.49ID:???
オレ多分頭悪いんだろう
>>626 で何を言っているのかよく分からない

愚直に>>623の要求通りのものを書くとすれば
`テーブル`に`人数`カラムを追加したとして
update `テーブル` t1 set
`人数` = (
select `人数` from (
select `性別`,`血液型`,`職業`, count(*) as `人数` from `テーブル`
group by`性別`,`血液型`,`職業`
) t2
where
t1.`性別` = t2.`性別` and
t1.`血液型`= t2.`血液型` and
t1.`職業` = t2.`職業`
);

でも、こんなこと実際にはしないし、
もっと良い方法が必ずあるはずだし
見直した方がいい

629NAME IS NULL2018/11/24(土) 18:02:53.98ID:Pyo9iAE3
>>628

626が意味不明で申し訳ないです。
書かれておられるように自分もwhereで
比較しました。

計算は各行に対してするのですが、
それが所属するグループの平均等の計算値も
途中計算で何度もつかうのです
それで、各行にそれを入れておきたいのです

なんだか変な事をやってるみたいで恐れ入ります

630NAME IS NULL2018/11/24(土) 18:07:07.78ID:???
結局何をしたいのかさっぱり理解できないけどわざわざ違うモデルで答えさせるとか失礼な事するやつだからスルーしとくわ

631NAME IS NULL2018/11/24(土) 18:18:02.74ID:???
質問をシンプルにしたくてモデルを
変えましたが、失礼と思われたようで
済みません

632NAME IS NULL2018/11/24(土) 18:26:04.19ID:???
わざわざスルーするって宣言してる奴なんだからスルーでいいよ

633NAME IS NULL2018/11/24(土) 21:20:38.92ID:???
合計値も平均値も割と簡単に計算出来ますし
それをテーブルに入れた方が良いのか
それともDBを見ているミドルの方で計算させた方が良いのか
全体の仕組みと性能で総合的に考えた方が良いかもしれません

634NAME IS NULL2018/11/25(日) 01:43:22.84ID:+jUq2Ssi

635NAME IS NULL2018/11/26(月) 21:45:52.63ID:???
mysql,mariadbでmyisamが非推奨になったのはなぜですか?
innodbではbeginやcommitが使えるそうですが、メモ的なデータをinsertするぐらいなのですが、
それでもinnodbを使った方がいいのでしょうか?

636NAME IS NULL2018/11/26(月) 22:42:16.59ID:???
そういうのは各RDBのスレがあるんだから、そこで聞けよ

637NAME IS NULL2018/11/26(月) 23:01:09.03ID:???
>>635
こちらで聞いてみたら

MySQL SQL質問応答スレ
https://mevius.5ch.net/test/read.cgi/db/1478776715/

638NAME IS NULL2018/11/27(火) 03:05:52.60ID:???
専用スレがあったのですね、誘導ありがとうございます。

639NAME IS NULL2018/11/28(水) 16:28:54.70ID:ZtGMc1/U
【勝谷誠彦(57)死去】 人口が毎年20万人も減るほど被曝して応援させ、さらに70歳まで働いて応援
http://rosie.5ch.net/test/read.cgi/liveplus/1543371270/l50

640NAME IS NULL2018/11/29(木) 10:10:36.91ID:???
以下のようなデータがあった場合、
name date rate
AAA 11/1 2000
BBB 11/1 900
CCC 11/1 500
DDD 11/1 700
AAA 11/2 2000
BBB 11/2 1200
CCC 11/2 500
DDD 11/2 700
AAA 11/3 2000
BBB 11/3 500
CCC 11/3 1500
DDD 11/3 700

最新のrateが1000未満だけを抽出するにはどうすればよいでしょうか?
DDD 11/3 700
BBB 11/3 500

641NAME IS NULL2018/11/29(木) 11:07:44.82ID:???
>>640 こうかな?
select name, MIN(date), rate
from hoge
where rate < 1000
group by name, date, rate

6426412018/11/29(木) 11:26:02.69ID:???
違った、こうか?
select a.name, a.date, a.rate
from hoge as a,
(select name, MAX(date) from hoge where rate < 1000 group by name, date) as b
where a.name = b.name and a.date=b.date;

643NAME IS NULL2018/11/29(木) 13:04:58.18ID:???
SELECT * FROM a WHERE (name,date) IN (SELECT name,MAX(date) FROM a GROUP BY name) AND rate<1000

644NAME IS NULL2018/11/29(木) 13:09:17.80ID:???
>>642
レスありがとうございます。
試したのですが、fromのselectでMAX(date)以外のも全て列挙されてしまいます。
DDD 2018/11/01 00:00:00
BBB 2018/11/01 00:00:00
CCC 2018/11/01 00:00:00
DDD 2018/11/02 00:00:00
CCC 2018/11/02 00:00:00
DDD 2018/11/03 00:00:00
BBB 2018/11/03 00:00:00
ちなみに使用DBはpostgresqlです。

645NAME IS NULL2018/11/29(木) 13:14:19.05ID:???
>>643
おお!できました!!
ありがとうございます!
整理して理解します。

646NAME IS NULL2018/11/29(木) 16:31:32.41ID:???
こういうときに色々意地悪な条件をついつい考えてしまう
最新日って言う場合、1件だけになるのか、
それとも同一日は全部該当にするのか
結果表示に時刻まで出てきていると悩んでしまう
その後の処理で何を使いたいかにもよるんだろうけど

647NAME IS NULL2018/11/29(木) 23:50:24.51ID:0rvo1ya5
>>646
ここで質問してくるやつはいつも仕様などあまり考えていない。

648NAME IS NULL2018/12/03(月) 19:05:02.42ID:???
2つの文字列カラムがあり、一方がもう片方の文字列から始まるものだけを抽出したい場合どうすればいいですか?
str1 str2
ABC ABCDEF
DEF aiu
GHI GHIxxx
JKL akasa
の場合、
ABC ABCDEF
GHI GHIxxx

649NAME IS NULL2018/12/03(月) 20:36:59.12ID:???
>>648
str1の長さがstr2より短いことがわかってるなら
where left(str2, len(str1)) = str1
でいいかと

650NAME IS NULL2018/12/03(月) 22:05:33.10ID:???
ためしてないけど、
where (str1 like str2+'%') or (str2 like str1 + '%')とかでどうだろう

651NAME IS NULL2018/12/03(月) 22:51:42.17ID:???
>>648
んじゃ他ので
WHERE PATINDEX(str1 + '%', str2) = 1

652NAME IS NULL2018/12/04(火) 10:41:43.68ID:???
>>649>>650>>651
お三方、ありがとうございました。
ばたばたしてて遅くなりましたが、確認できました。

653NAME IS NULL2018/12/04(火) 11:20:56.24ID:???
>>650-651
str1とかstr2に'%'含んでても大丈夫だっけ?

654NAME IS NULL2018/12/04(火) 11:59:27.62ID:KJK6oDpE
大丈夫。ただ+が使えるのはMS系だな。
後は使えるやり方に読み換えて

655NAME IS NULL2018/12/09(日) 16:50:28.29ID:???
SQL SERVERのSQL文について質問です

【条件】
1.全てのテーブル内容を取得
2.@ABのM_CODEとS_CODE、CのM_CODEとS_CODEが一致したNAMEを取得

一つのSQL文で完結できると助かります
以上の内容でご教示お願いします


@Table1
ID | M_CODE | S_CODE | 内容
--+----------+-----
01 | 1 | 1 | a
02 | 1 | 2 | aa
03 | 1 | 3 | aaa
04 | 1 | 2 | aaaa

ATable2
ID | M_CODE | S_CODE | 内容
--+----------+-----
01 | 2 | 1 | ab
02 | 2 | 2 | abb
03 | 2 | 3 | abbb
04 | 2 | 2 | abbbb

BTable1
ID | M_CODE | S_CODE | 内容
--+----------+-----
01 | 3 | 1 | ac
02 | 3 | 2 | acc
03 | 3 | 3 | accc
04 | 3 | 2 | acccc

CCode
M_CODE | S_CODE | NAME
--+----------+-----
1 | 1 | サッカー
1 | 2 | 野球
1 | 3 | バスケット
2 | 1 | バナナ
2 | 2 | リンゴ
2 | 3 | オレンジ
3 | 1 | サバ
3 | 2 | カツオ
3 | 3 | マグロ

656NAME IS NULL2018/12/09(日) 18:37:50.56ID:???
1,2,3をuionして4とjoinすればいいんだろうけど,何んでこんな設計?

657NAME IS NULL2018/12/09(日) 18:58:36.79ID:???
欲しい結果がよくわからん

4に1〜3をJOINするだけじゃダメなのか?

658NAME IS NULL2018/12/11(火) 21:37:14.11ID:???
この板誰も人いないけど、他にデータベースの話題扱う場所あるの?

659NAME IS NULL2018/12/12(水) 07:07:27.08ID:???
ここはSQLの板だから
DBは別にあるだろ

660NAME IS NULL2018/12/14(金) 13:53:33.51ID:???
スレはSQLだが、ここはデータベース板

新着レスの表示
レスを投稿する