SQL質疑応答スレ 17問目 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。
SQLという言語はISOによって標準化されていますが
この標準を100%実装したDBMSは存在せず、
また、DBMSによっては標準でない独自の構文が
追加されていることもあります。
質問するときはDBMS名を必ず付記してください。
【質問テンプレ】
・DBMS名とバージョン
・テーブルデータ
・欲しい結果
・説明
前スレ:
SQL質疑応答スレ 16問目
http://echo.2ch.net/test/read.cgi/db/1447160858/ バグというより、データベースに事実にない情報を含めるとか違和感が numberでもバグを産む可能性を秘めてるし
どっちのリスクをとるかだけじゃね 年月のみを管理したいっていう場合に
・日付としての正当性は保証されるけど不要な日の情報を持つ
・日付としての正当性は保証されないけど不要な情報を持たない
のどちらがいいか?
って話でしょ
個人的にはデータの正当性の方を重視するかな そして2017/4/1と2017/4/2など
同一年月で複数レコードできてしまうのでした 年月情報をユニーク制約を保持する仕様で日付計算のためにdate使ってたら、皆さんはどう思いますか もうUNIQUE制約のある年月列と日付計算用の列を分けろよ レコードの入力時に日付が何入っていようと、1にしてしまえば良いだけだろう そんなもん制約がなければ全く信用できん
本当に頭が悪いなお前ら >>205
2017/00 とか 2017/13 とか入ってるのとどっちがいい? 1日の0時になっているか確認するcheck制約つければいい そもそもカラムが年と月別なんだからcheck制約でもMonth>=1 and Month<=12でいいから簡単だろ
プログラムも同様
まさか日付を変換して1日かとかやるとか?
いらない情報付与からして、そんなのうちでは許されないわw >>182
後の人間を苦しめるコードをまき散らすのは止めよう 3年分取ってきてと言われて初めて問題に気付くパターンや where fiscal_year(year, month) = 2017
みたいな感じで関数使うかビュー使うほうがロジックが一箇所に集まっていい気がする
パフォーマンス気にするレベルならcalender yearとは別にfiscal yearをデータに持たせるかな あと fiscal_year(date) みたいにオーバーロードしとけば
インターフェースが統一されて使いやすい SQLにオーバーロードあるんですか?どんなRDB? え、、、普通にあるでしょ
むしろできないDBってどれよ そうなんか、OracleとPostgreSQLで出来てるから普通なのかと・・・ てか、そもそもOracleでも単純なオーバーロードってあったっけ? このケースはComputed Columnが使えればそれがいいと思うけど
Postgresでは使えないから関数オーバーロードしとくって話
Computed Columnなら使えるDB多いだろ
SQL標準ならView使えって話かもしれんがViewは管理上のオーバーヘッドが高くなる傾向があるから
使わなくてすむケースならなるべく使わないようにしてる >>228
会計年度を必要とするたびに繰り返し同じことをするのでよければね
年度別に集計したい場合とかしんどいし俺はごめんだわ 普通に関数でいいと思うんだが、あえて(関数?)オーバーロードって言ってるのはなんで? >>230
そういうこと言ってるからいつまでたってもスキルが向上しないんだよ
select case when month < 4 then year - 1 else year end as fiscal_year, sum(hoge)
from foo
group by case when month < 4 then year - 1 else year end つか、いたるところで会計年度を意識するようなシステムなら、会計年度カラムを作っとけばいいよな >>232
where句も入れて何回繰り返すのさ
面倒くさいとは思わないの?
単発の作業ならわからんでもないが会計年度みたいなのは1回じゃすまないだろ
>>231
日付型でデータを持ったテーブルがあったり
日付型に徐々に移行したい場合に同じ名前で扱えるとうれしいから
会計年度って概念をDBに反映させる一つの手段 >>234
> 面倒くさいとは思わないの?
いや、まったく
>>232レベルのクエリなら10秒もかからずタイプできるだろ >>234
> where句も入れて何回繰り返すのさ
ストアドでも似たようなもんだろ。
select fiscal_year(year, month), sum(hoge) from fuga group by fiscal_year(year, month)
しかもストアド使うと、year, monthにインデックスあっても使われないし。 kantomi@qiita_banned < ストアド!ストアド! >>235
面倒くさいと思わないならいいんじゃね
>>236
asで名前つけとけばgroup byでは繰り返す必要ないよ
たとえ繰り返しが必要だったとしても概念をその名前で直接扱える状態と
毎回展開しなきゃいけない状態では全く意味が違うんだけどね
インデックスは必要ならはればいい >>233
算出できる情報を別途カラム作って持たせるのは最終手段 >>180 重み付けの定石
>>182 単年度でしか動かないクソ
>>185 意図が分かりやすい
>>217 ビジネスロジックをDBMSに持たせる派とアプリに持たせる派で戦争勃発 >>234
fiscal_year(year, month)って関数自体はまだなにもオーバーロードしてないだろうが。 >>241のどこが馬鹿なのか論理的に説明できないやついるの? >>240
分解せずに日付型で持っていればよかったって事だな
以降>>188へ戻る 管理上のオーバーヘッドってのがユーザ側の話なのかシステム側の話なのかしらんが
関数オーバーロードができたとして、それがビューより管理が重いとか信じられん
会計年度が必要ならそう言うビュー作れ、で終わりじゃないのか インデックス張るなら、ロシア方式が一番いいよな
トリガーで仕掛けておけば気にしなくて済むし >>239
> インデックスは必要ならはればいい
本末転倒だな
普通にクエリ書けばインデックス使えるのに、ストアドにしようと思うとさらに何かしないといけなくなる
つか、ストアドの結果にインデックス貼れないDBもあるんじゃね? >>239
> asで名前つけとけばgroup byでは繰り返す必要ないよ
その手段が使えるDBでは、>>232も同じことが言える
> 毎回展開しなきゃいけない状態では全く意味が違うんだけどね
例えば四半期ごとの集計がほしいとか、移動平均がほしいとかいうことになったら、
そのたびにストアド作るのか?
増殖しまくりだな ん? >>232 だとインデックス使われないだろ
>>217-218 >>185 のような関数だともっと使われない
>>182 のように or あると、うまく使ってくれるか怪しい >>251
> ん? >>232 だとインデックス使われないだろ
where書いてないからね
>>232は、集計がしんどいという奴へのレス
>>182 のように or あると、うまく使ってくれるか怪しい
大抵のRDBMSだったらうまく使ってくれるんじゃね? それより決算月が変わる可能性について考えたほうがいいと思う >>251
> >>217-218 >>185 のような関数だともっと使われない
こういうバカ避けのためにわざわざ「性能は知らん」って書いてあるのにバカはそれすら理解できないんだな w
インデックス使いたいならdate型にしとけよ >>254
year, monthにインデックス張ればいいだろ
アホか ビューのコストが高いというのがparserの話だとしたら、単純なビューなら最近では全く問題にならない
まぁ、大抵の場合、クエリ1回につき+1ms未満だろう。
(さらには、直近のparse結果をcacheしている場合もある) >>256
> year, monthにインデックス張ればいいだろ
インデックス張っても関数の引数にしちゃったら使われない >>256
バカってこれだから...
複数の列に張るより単一の方が有利だろう
そんなことも理解できないのかよ w そんな理由だったらオレもアンタをバカ呼ばわりしていいかな 不利っつっても、比較が1回か2回かって違いくらいしかないだろ。 ここを2つに分けるかどうかの是非はともかく
キーが2つになるから絡むつにしようとかおかしいだろw
まあこのケース、月なんて12通りしか無いんだし複合キーで >複数の列に張る
こういう言い方しているところを見ると、複合インデックスの仕組みをわかってないんだろう。 yearのインデックスとmonthのインデックスを別々に張りそう >>250
>その手段が使えるDBでは、>>232も同じことが言える
そんなんわざわざ言わんでもわかっとるがな〜ww
>増殖しまくりだな
増殖して何か問題あるの? >>246
システム側の話
組織構造なんかも大きく影響するから環境による
導出列はビューを使うっていう規約があってそれに従ってるようなところならオーバーヘッドも少ないだろうね
ただ関数よりビューのほうが管理の厳格度というか管理レベルが高いのは一般的じゃないのかな?
管理レベルが高ければその分のオーバーヘッドはかかる
それに同じような年・月で持ってるテーブルが10個に増えたら10個ビューを追加することになる
そういうのが嫌だからComputed Column的な機能があるDBが多いと思ってる >>264
お前こそわかってないだろ w
>>180, >>182 みたいに複合インデックスの各々の列を別々に大小比較で使うとインデックス使えないぞ 使われないインデックスと、使えないお前らの脳ミソ達。 >>182は(orは別として)yearとmonthの複合インデックスの教科書的な例だと思うが。
つか、>>180と>>182を同列に並べている時点でお里が知れる。 >>267
管理レベルってのがなんだかわからんが
ビューの方がより厳密に適用される分、問い合わせ時のシステム的なオーバーヘッドは小さいだろ
実行計画もより最適化できる
つか、ユーザー側/システム側って切り分けが、どっちも人員の切り分けだと思ってる?
>それに同じような年・月で持ってるテーブルが10個に増えたら
同じものが分散して存在してたら、その時点でテーブル設計が間違ってるわ >>270
実行計画見てみ
複合インデックスの仕組み知ってたらそんなアホな発想はできないよ おまえこそ見てみろと言いたいが。
念のためだが、ヘボいオプティマイザがorのせいでスキャン範囲の限定に失敗するのは
「複合インデックスの各々の列を別々に大小比較で使うとインデックス使えない」てのとは
関係ないからな。 >>274
> orのせいで
バカを晒すのはほどほどにしろよ 今どきは>>182でも(year,month)のインデックスがあれば
(そしてそれを使ったほうが速いとDBMSが判断すれば)
使うDBMSのほうが多いと思う
パフォーマンスに関しては昔の定石を今はあまり気にしなくても
良くなっていることが多いので必ず実機で試してから語ったほうがいい >>276
それはyearを使わずにmonthだけだった場合だな。こんな初歩的な勘違いしてたのか。 >>278
バカはこれだから...
わざわざ
> インデックスの構造をより深く見ていくと、この理由がはっきりします。
って言うところまで引用してるだからその下読めよ
理解できるかどうかは知らんけど w year, monthにインデックスの件だけど、PostgreSQLなら使われるけどなぁ
ほかのDBだと使われなかったりするのか? create table hoge (year integer, month integer, amount integer);
create index hoge_idx on hoge(year, month);
select year, month, sum(amount)
from hoge where (year = 2017 and month > 3) or (year = 2018 and month < 4)
group by year, month;
実行計画:
https://explain.depesz.com/s/rwx 実行計画見るような人なら当然わかっているだろうけど、統計情報がとられていなかったり
選択されるレコードの割合ががテーブル全体に対して大きい場合はインデックススキャンが
選択されないから注意な。 インデックス使われないマン =
オーバーロードマン =
Computed Columnマン まさか今どき、インデックスがあれば必ず使うとか思ってるんだろうか
ルールベースとコストベースの違いも分かってない? >>285
おいこら
インデックス使われないマンと一緒するなよw お前らが馬鹿なのは使う必要のないインデックスについて延々と話してることだけどな >>282
それ >>287 が書いてる通り Bit Map Index Scanだよ
URL読めばわかると思うけど
> ビットマップスキャンは、一度に全てのタプルへのポインタをインデックスから取り出し、
----
インメモリな「ビットマップ」データ構造を使ってソートし
----
> 物理的なタプル位置の順にテーブルのタプルにアクセスします。
つまりyearとmonthに対して個別にインデックス張っときゃソートなんて要らない
要するに >>264-265 をディスってるだけなんだが w 結論
>year, monthにインデックス張ればいいだろ
>アホか まあ、日付型とか言ってる奴は決算月の考慮どうするんだろうと思うわ ■ このスレッドは過去ログ倉庫に格納されています