SQL質疑応答スレ 8問目

このエントリーをはてなブックマークに追加
1NAME IS NULL
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

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

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

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

前スレ:
SQL質疑応答スレ 7問目
http://pc11.2ch.net/test/read.cgi/db/1223525474/
2NAME IS NULL:2009/03/05(木) 20:46:43 ID:???
3NAME IS NULL:2009/03/05(木) 20:50:44 ID:???
過去スレ
SQL質疑応答スレ 6問目
http://pc11.2ch.net/test/read.cgi/db/1210940477/
SQL質疑応答スレ 5問目
http://pc11.2ch.net/test/read.cgi/db/1193486961/
【帰ってきた】SQL質疑応答スレ 4問目
http://pc11.2ch.net/test/read.cgi/db/1176553195/
【帰ってきた】SQL質疑応答スレ 3問目
http://pc11.2ch.net/test/read.cgi/db/1160458216/
【帰ってきた】SQL質疑応答スレ 2問目
http://pc8.2ch.net/test/read.cgi/db/1141622643/
【帰ってきた】SQL質疑応答スレ
http://pc8.2ch.net/test/read.cgi/db/1124178925/
SQL質疑応答スレ Part 2
http://pc8.2ch.net/test/read.cgi/db/1103113155/
SQL質疑応答スレ
http://pc8.2ch.net/test/read.cgi/db/1056973582/
4NAME IS NULL:2009/03/05(木) 20:52:25 ID:???
よくある質問1

(問)
ID | DATE     | DATA
--+----------+-----
1 | 2007-11-11 | aaa
2 | 2007-11-11 | bbb
1 | 2007-11-10 | ccc
3 | 2007-11-12 | ddd
3 | 2007-11-11 | eee
4 | 2007-11-10 | fff
1 | 2007-11-12 | ggg

このようなテーブルから、下記のように

1 | 2007-11-12 | ggg
3 | 2007-11-12 | ddd
2 | 2007-11-11 | bbb
4 | 2007-11-10 | fff

各idに対して最新の1件だけ抽出するSQLの書き方を教えてください。

(答)
select A.ID,
    A.DATE,
    A.DATA
from TableName A
   inner join
   (select ID, max(DATE) as MAX_DATE
    from TableName
    group by ID
   ) B
   on A.ID = B.ID
   and A.DATE = B.MAX_DATE
;
5NAME IS NULL:2009/03/05(木) 20:53:22 ID:???
よくある質問2

(問)
key   data
----------------
1     a
1     a
1     b
1     b
1     a
2     b
2     a
2     a

というテーブルから

key   a   b
--------------------
1    3   2
2    2   1

というExcelのピボットの様なデータを取得したいのですが、どういうSQLになりますか?
a,bというのは固定なので、仮にcというデータがあっても無視して構いません。

(答)
SELECT key,
    SUM(CASE data WHEN 'a' THEN 1 END) AS a,
    SUM(CASE data WHEN 'b' THEN 1 END) AS b
FROM table
GROUP BY key
ORDER BY key
;
6NAME IS NULL:2009/03/05(木) 21:11:51 ID:???
7NAME IS NULL:2009/03/07(土) 00:30:17 ID:lFENR4eI
ちょっとSQLとは離れてしまうのですが、テーブルのなかにテーブルを作れる DBMS ってあるのでしょうか?

id | table | data
--+----------+-----
1 | sub_tb1 | aaa
2 | sub_tb2 | bbb

こんなかたちで、普通のデータとテーブルを混合して扱えるといいのですが、
8NAME IS NULL:2009/03/07(土) 00:48:02 ID:???
>>7
少なくともOracleではできるけど激しくお勧めしない
今すぐデータ構造を見直したほうがいい
9NAME IS NULL:2009/03/07(土) 00:51:03 ID:???
>>7
何故それをやらなければならないのか、それが問題だ。
10NAME IS NULL:2009/03/07(土) 02:33:50 ID:lFENR4eI
>>8 >>9

一つのプロジェクト情報を1レコードで管理しようと考えていまして、こんな感じのデータ入れようと思っています。
主キーはプロジェクトコードになります。

A工程作業 10人の氏名や単価などなど5カラムくらい。
B工程20人...
C工程30人...

となると、1レコードあたり300カラム以上になってしまい、また委託先がバラバラなので外注マスタみたいなものを
作るのが困難なため、こんな方法にしようかと、、、なにかいい方法はないでしょうか
11NAME IS NULL:2009/03/07(土) 03:40:34 ID:???
>>10
一つ確認なのですが、300カラム以上と言うのは、

(10人 x 5カラムぐらい) + (20人 + 5カラムぐらい) + (30人 + 5カラムぐらい)

という計算で良いのでしょうか?
12NAME IS NULL:2009/03/07(土) 07:19:26 ID:???
>>10
RDBMS を勉強し直せ
13NAME IS NULL:2009/03/07(土) 10:40:24 ID:lFENR4eI
>>11
はいそうなんです。こんな形で考えてみましたのですが、ありなのでしょうか?
|A名前1|A単価1|A期間1|A社名1|A備考1|・・・|A名前10|A単価10|A期間10|A社名10|A備考10|B名前1|・・・|B備考20|C名前1|・・・|C備考30|

>>12
なにか根本的に間違っているのでしょうか、、
14NAME IS NULL:2009/03/07(土) 11:15:19 ID:???
>>13
根本的に間違ってるからまずリレーショナルデータモデルを勉強したほうがいい
15NAME IS NULL:2009/03/07(土) 11:40:31 ID:lFENR4eI
>>14
なんか根本的に間違ってる気がしてきた、、項目が多い部分は、外部のテーブルにしろってことですかね。

□主テーブル
|プロジェクトコード|プロジェクト名|予算|工期|・・・・

□外部のテーブル
|プロジェクトコード|工程種別|No|名前|期間|備考|

こんな形にしてプロジェクトコードで結合。この場合、正規化する必要の無いテーブルを分割しているのですが、それはありですか?
16NAME IS NULL:2009/03/07(土) 12:21:23 ID:???
主キーとか正規化とか知ってる割には... 釣りとしか思えん。

釣りじゃないと言うなら、>>12, >>14 が言ってるように本屋に
行ってデータベース関連の本買ってきて勉強した方がいい。
17NAME IS NULL:2009/03/07(土) 12:52:13 ID:???
釣りじゃないですよ。もう少しちゃんと勉強しないとまずそうですね。
スレ汚しみたいになってしまってすみませんでした。本買ってきます。
18NAME IS NULL:2009/03/07(土) 13:00:27 ID:???
なんて偉そうなw
19NAME IS NULL:2009/03/07(土) 14:15:18 ID:???
純粋にデータベース理論に基づく議論として、>>13のスキーマがダメで
>>15のようなスキーマの方がよい理由って何でしょうか。
20NAME IS NULL:2009/03/07(土) 14:24:28 ID:???
ここは SQL なスレであって、テーブル設計のスレではないことに
そろそろ気づこうな。
21NAME IS NULL:2009/03/07(土) 23:08:49 ID:lFENR4eI
本から調べてみましたが、正規化するする必要がないテーブルを分割するのは設計上ありえない、もしくは仕方の無い場合のみ
しかしカラム数が膨大になる場合でも分割するのは、EDI規約では分割しては "ダメ" とのこと、、、

まあ結局 Oracle あたりで調べてみるしかなさそうですね

どうでも良いけど、「リレーションをつかえば..」「そういう設計はない」「もう少し調べてろ」とか うちのアホ上司と
答えが同じで面白かったです。で、困ると「俺に(ここ)で聞くな」的なw 知らなければ知らないでいいですよ。無理しないでね。
22NAME IS NULL:2009/03/07(土) 23:13:25 ID:???
何をもって「正規化する必要がない」なのか、俺には全然理解できん。
普通に正規化する必要ありそうに見えるけどな。
23NAME IS NULL:2009/03/07(土) 23:16:39 ID:???
>>21
正規化について考えたのであれば>>10のデータに関して
関数従属性(FD)を見当したはずですが、どのようなFDを
列挙したか書いてもらえますか?
24NAME IS NULL:2009/03/07(土) 23:22:06 ID:???
ACCESSだけど、>>13と同じ構造でテーブル設計されてるDBを見たことがある。
もうなんていうか、え…っ?何を見たんだろう…?って感じ。
でもさすがに300カラムはなかった。255カラムだったw

>>19
人の入れ代わりが繰り返されたら、そのテーブル構造だとどうなるかをまず考えてみよう。
そうして、正規化について基礎から勉強しなおそう。
25NAME IS NULL:2009/03/07(土) 23:24:54 ID:???
スレ違いなのに、逆ギレを装いつつ煽ることで答えを引き出そうとするテクニックですね。
いい加減、スレ違いなお馬鹿さんにつきあうのはやめにしましょう。
26NAME IS NULL:2009/03/07(土) 23:29:09 ID:???
>>24
いや、なので純粋に「関係データベースモデル的に」ですよ。ネタです。
とりあえず部分従属も推移的従属も多値従属もないですよ?
27NAME IS NULL:2009/03/07(土) 23:37:48 ID:lFENR4eI
>>23
なんかスレ違いを続けてすみません。

プロジェクトA の 作業A の スタッフ1 は プロジェクトコードAにのみ従属するので断念しました。スキル不足かもしれません。
また、正規化の基礎が分かっている方なら、それが出来ないくらい分かりそうなものだと思いますが、、

データベース関連の本買ってきて勉強した方がいい。ですよw
28NAME IS NULL:2009/03/07(土) 23:43:51 ID:???
カタカナ言葉で逃げないで、ちゃんと読めって言われた本やマニュアル読みなよ。
自己満足で変な物作るなよ。
29NAME IS NULL:2009/03/07(土) 23:45:37 ID:???
>>27
失礼しました。関数従属性も見当しないで「正規化すると・・・」なんて
文句言う人も少なくないので一応ちゃんと見当したか確認したかった
のです。見当したという事で、了解しました。

もう一つ確認なのですが、各プロジェクトのスタッフの数は10人・20人・
30人で固定でしょうか。
欠員や人数割れは発生しませんか?あるいはこれらの人数は単に
上限を示すものでしょうか。
30NAME IS NULL:2009/03/08(日) 00:01:01 ID:???
データーベースってさ、
「作る前に」
いっしょうけんめい、考えないといけないよね。
31NAME IS NULL:2009/03/08(日) 00:03:27 ID:???
>>24
> ACCESSだけど、>>13と同じ構造でテーブル設計されてるDBを見たことがある。
> でもさすがに300カラムはなかった。255カラムだったw

Excel の概念から脱却できなかったんだろうな。
まあ、Excel 2003 まででよかったよ、Excel 2007 使いだと、カラム数 1,000
とか平気で作りそうだし。(w
32NAME IS NULL:2009/03/08(日) 00:06:45 ID:???
>>26
ヒント:第一正規形
33NAME IS NULL:2009/03/08(日) 00:16:05 ID:OlHguXyr
>>32
>>13のリレーションは第一正規形のようですが。
347:2009/03/08(日) 00:19:08 ID:vyix2FVv
>>29
こちらそ失礼をすみません。スタッフの数は極端な話 0人(全てお任せで社名のみ)〜100人近くになる可能性もあります。

直接プロジェクト管理する場合は、全てのスタッフ情報を登録する必要があり、外注先が子会社、別会社、個人とバラバラなので
マスタを作るとなるとショットで頼んだ個人まで登録しなくてはならないので、>>13 みたいな形を考えました。

ただ想定している上限100名×5 = 500カラムはちょっと無理そうなので、テーブルのなかにテーブルがつくれるのがいいのかな?と考えました。
35NAME IS NULL:2009/03/08(日) 00:29:25 ID:OlHguXyr
>>34
了解しました。実は以下の回答はあらかじめ書いてあったものです。
無駄にならなくて良かったw

まず私の意見としては「正規化すれ」云々のコメントは全く見当違いです。
例としてあげられた>>13のスキーマは第五正規形まで見事に満たしています。
これ以上正規化しようがありません。更新時異常も起こりようがありません。

失敗はリレーションの正規化以前の、データ設計にあります。
例としてプロジェクトの「作業Aのスタッフ1の名前」を挙げます。
>>13のスキーマではこれは次の関数従属性で表現されています。

プロジェクトID -> 作業Aのスタッフ1の名前

これに対して、ベターな表現は次のようなものです。

プロジェクトID, 作業A, スタッフ1 -> 名前

何故これがベターかは左辺の作業名とスタッフ番号を具体値から属性名
に置きかえると判ります。

プロジェクトID, 作業名, スタッフ番号 -> 名前

幸いこれは多値ではない関数従属です。ですので綺麗に第一正規形の
リレーションで表現出来ます。試しに元の表現でもやってみます。

プロジェクトID -> 作業名, スタッフ番号, 名前

これは多値関数です。ですのでナイーブに実装しようとすると思わず入れ子
リレーションを発想してしまうかも知れません。>>7のような質問が出てきた
理由を無理矢理理屈立てて推測すると、多分こんなところです。

いずれにしても>>15のスキーマは>>13のスキーマの正規化を崩している
のではなく、元より異なるデータ構造を実装したものなのです。
なので安心して>>15のアプローチでデータベースを作ると良いと思います。
36NAME IS NULL:2009/03/08(日) 00:29:41 ID:???
>>31
Oracleならありそうで怖いw
Accessは幸いなことに…いや全然幸いでも何でもないけど、1テーブル255カラムが最大。

>>26
>>13のテーブル構造で、それぞれのプロジェクトにかかるコストを算出することを考えてみて。
工程ごとの小計もそれに加えたりなんかすれば…、死ねるw
DB構築する意味ないじゃん。
37NAME IS NULL:2009/03/08(日) 00:40:45 ID:???
なんだ〜、さっぱり理解できない…
最後の1文だけ同意するw
38NAME IS NULL:2009/03/08(日) 01:02:50 ID:???
正規化できない暴威は結局,答えが欲しいんでしょ?
素直になれば良いのに。
「教えてください」って言えない子は,自分勝手に設計して
後で理解できれば本人のためにも良いと思う。
スレチってことも自覚してるようだし。
Access弄ってる気の利いた素人でもそんな設計しないよw
397:2009/03/08(日) 01:24:03 ID:vyix2FVv
>>35
>失敗はリレーションの正規化以前の、データ設計にあります。
>元より異なるデータ構造

このあたりを考えていなかったため、おはずかしい考えをさらしてしまいました、、、
別テーブルを、異なるデータ構造を扱うためのものとしてとらえてみます。

ベテランの方だと思うのですが、失礼すみませんでした。
40NAME IS NULL:2009/03/08(日) 01:34:46 ID:???
>>37
要約すると、次のような感じ。

(1) >>13のスキーマは正規形
(2) >>15のスキーマは>>13のとは異なるデータ構造を実装したもの
(3) なので>>15のスキーマは正規化崩しではない。安心してOK。
(4) 正規化正規化言っている人は、ちゃんと理解して言っていますか?

(4)が屁理屈っぽく書いた理由です。
ただ正規化正規化言っているのも、ちょっと無責任だなと思ったので。


余興ついでにもちっと数学的に屁理屈をつけると>>13のスキーマに
含まれる関数従属は>>15のスキーマで表現されている関数従属

プロジェクトID, 作業名, スタッフ番号 -> 名前

の左辺にある作業名・スタッフ番号という属性に対してカリー化という
操作を適用し、出来た関数にこの2属性の具体値を適用する事で、
この一つの関数従属を複数の関数従属へと分割したものです。
数学的も何ら問題ない操作ですし、データモデリングの際には逆カリー
化と共に広く行われている操作です。

問題はこの操作によって出てくる関数従属の数や種類は適用された
2属性(作業名・スタッフ番号)の具体値(またはドメイン)に依存します。
例えばスタッフ番号の数が変わると、異なる数の関数従属が出ます。

他方でデータベーススキーマの一つの目的はデータ中の関数従属を
十分に表現する事ですから、関数従属の数や種類が変わるとそれに
応じてスキーマも変更しなければなりません。

スキーマ=時間不変な構造、が、スタッフ番号の数などでコロコロ
変化されては困ります。屁理屈を言えば>>29の質問の意図はこの点
を確認するものでした。

ところが実際はスタッフの数はどうも曖昧っぽかったので、理屈的にも
ベターなのはこのカリー化を適用していない>>15のスキーマです。
41NAME IS NULL:2009/03/08(日) 02:10:38 ID:???
>>40
詳しい説明をどうもです。
でもカリー化とやらをググってたら脳ミソ逃避し始めた…w
42NAME IS NULL:2009/03/08(日) 02:33:51 ID:???
>>41
ごめんなさい。ググるほどの概念でも、難しい操作でもありません。
手順を書くと次のような操作です。

(元の関数従属)
プロジェクトID, 作業名, スタッフ番号 -> 名前

(カリー化)
作業名, スタッフ番号 -> (プロジェクトID -> 名前)

これだけです。右辺も関数になっているのがミソです。

(左辺に具体値を適用)
作業A, スタッフ1 -> (プロジェクトID -> 名前)
作業A, スタッフ2 -> (プロジェクトID -> 名前)
...
作業B, スタッフ1 -> (プロジェクトID -> 名前)
作業B, スタッフ2 -> (プロジェクトID -> 名前)
...

あとはそれぞれの左辺の具体値を新たな属性名として利用して、
右辺の関数従属を

「プロジェクトID -> 作業Aスタッフ1の名前」

のようにスキーマ内で実装すれば>>13のスキーマが出来ます。

ただこれらは「屁理屈」ですからね。理解としては楽しいですが
あまり世間的に役に立つとは思いません。
43NAME IS NULL:2009/03/08(日) 10:08:10 ID:???
俺の意見としては >>13 は「正規化できてない」だな。

単純に「作業名(?)」が重複してるから。
そんなん、「作業」が増えたときにすぐ死ねる。

「スタッフ」もとくに固定ではない、ってことだし。

マスタ化しづらいなら、マスタから値を引っ張るケース、その行に単一スタッフを
書き込むケース、なんて形に分けると思う。
44NAME IS NULL:2009/03/08(日) 10:38:07 ID:???
俺もそう思う。
難しい言葉はともかく、第一正規形は
「テーブル内テーブル」を排除したものでしょ?
45NAME IS NULL:2009/03/08(日) 14:46:17 ID:???
>>42
待った。
>>13を見ただけではそのような関数従属が存在するとは判断できないと
いう意味で、>>13が非正規形であると言い切れないというのは良い。
ただ、>>42のような関数従属の存在を前提とした場合、コッドの関係モデルが
一階述語論理に基づくものである以上、そのようなカリー化された関係を
スキーマに表現することはできない。
カリー化の操作そのものには問題はないのだが、「左辺の具体値を新たな
属性名として利用して」という部分で、元の関数従属を表現できなくなっている
ことに注意。
46NAME IS NULL:2009/03/08(日) 16:40:11 ID:???
>>45
その通りです。一連の操作で展開された関係従属の集合と元の関数従属は
同じものとして扱う事は出来ません。
なので>>13>>15のスキーマは「異なるデータ構造」、つまり異なる属性集合
と異なる関係従属性の集合を表現したものなります。

元々の質問が>>15>>13の正規化崩しでは無いか、というものであったので、
そうではないです、なぜなら元より異なるデータ構造を表現しているのだから、
というのが一連の趣旨です。

>>43-44
データ設計(モデリング)とスキーマの正規化ははっきり区別すべきです。
データベースで表現したい対象から属性とその間の関係を抽出するデータ
設計とスキーマの正規化はどの本でも異なる章に書かれているはずです。

元のデータ中に存在する関係従属性を出来るだけ保ったままリレーションを
無損失に分解していくのが正規化の一連のステップですが、>>13から>>15
のように肝心の関係従属性の集合をざっくり別のものに入れ替えるようでは
流石に正規化の範囲を超えています。
これはデータ設計の問題として議論すべき事柄です。

実際>>13のスキーマはちゃんと正規形なのです。なぜなら>>27にあるように
「作業Aスタッフ1の名前はプロジェクトコードにのみ関数従属する」他の属性
についても以下同文、というようにデータを設計したらです。
そのようなデータを表現する限りに置いて、このスキーマは正規形です。
ですのでツッコミの入れどころは正規化ではなく、データ設計のそのものと
なります。
47NAME IS NULL:2009/03/08(日) 16:43:09 ID:???
ありゃ、関数従属が全部関係従属になっている・・・Typoです orz
君らが賢いのわかったから、どっかよそでやってくれないかな。
49NAME IS NULL:2009/03/08(日) 18:30:35 ID:???
やっぱりXMLデーターベースだよねー
あとから変更できるしー
50NAME IS NULL:2009/03/08(日) 19:10:34 ID:???
>>46
こっちにレスしました。

DB設計を語るスレ 2
http://pc11.2ch.net/test/read.cgi/db/1223458453/321

>>48
こういう話題振ると、叩き上げの上司がそういう反応したりしますねぇ。
51NAME IS NULL:2009/03/08(日) 19:12:48 ID:???
いい加減、煽るのやめろよハゲ
52NAME IS NULL:2009/03/08(日) 19:46:02 ID:???
注意されて逆切れするタイプなんだろ。
スルー推奨。
53NAME IS NULL:2009/03/08(日) 20:11:07 ID:???
>>49
XQueryとXPathが全社共通になったらね。
54NAME IS NULL:2009/03/08(日) 20:12:56 ID:???
>>53
そんなの待ってられないから、
とりあえず、現時点でシェアトップのものを
使いたいんだけど?
55NAME IS NULL:2009/03/08(日) 20:27:50 ID:???
よし ならば DB2 v9.1 pureXMLだ

夏前にはv9.5が出るよん
56NAME IS NULL:2009/03/08(日) 21:54:31 ID:???
>>53
それを言うなら問題はXQuery Update Facilityだと思うけど・・・
XQueryやXPathは世に言うXMLDBなら大概は使えると思う。
57NAME IS NULL:2009/03/09(月) 16:25:54 ID:???
PHP+MySQLで、ある設定をひとつのユーザにつき10個までに制限したい
この場合の設定テーブルは
ID、ユーザーID、設定1、設定2、設定3・・・設定10
なのか
ID=ユーザーID*10+0、ユーザーID、設定
ID=ユーザーID*10+1、ユーザーID、設定
ID=ユーザーID*10+2、ユーザーID、設定
なのか・・・

どういう構造がいいんでしょうか?
58NAME IS NULL:2009/03/09(月) 16:45:11 ID:???
典型的には後者だけど、次のような点が検討項目になるかな

・「設定」って何?

(a) 設定={設定値A, 設定値C, 設定値J, ...}みたいな形で
  最大10個まで設定値の好きな組み合わせを選べるものなのか、

(b) 設定1: 設定値F, 設定2: 設定値A, ...設定10: 設定値Kみたいに
  設定1から10までの項目があって、それぞれに設定値をセット
  するようなものなのか

・(a)だとして、設定値を選択した順番に意味はあるのか。

・(b)だとして、設定値のダブりはありか(設定2: 設定値F, 設定5: 設定値F)

・「設定」をテーブルで表現したとして、どういう検索をしたいのか
59NAME IS NULL:2009/03/09(月) 17:54:11 ID:???
設定値はユーザーが任意に入力できる正規表現の文字列なので、
多種多様な値が入ることになります。
検索はしないかもです。データベースでやる必要はないんでしょうか?
とりあえず後者のやり方でやってみます
60NAME IS NULL:2009/03/09(月) 18:11:32 ID:???
ユーザーIDで検索するだけってことだよね。
ところでユーザーIDも保持してるならIDを10倍して足す意味が無いような。
61NAME IS NULL:2009/03/09(月) 18:24:50 ID:???
>>59
後者だとして、「ID=ユーザーID*10+0」は多分使い勝手が
悪いので別の方法をとった方が良いよ。

単にユーザが正規表現を10個登録したいだけなら属性は
{ユーザID, 正規表現}だけで、この2属性の組にPK制約
かけておけば十分。

もし正規表現1は○○、正規表現2はXX、みたいにある
正規表現が何番目の正規表現であるかが重要なのであれば、
{ユーザID, 正規表現No, 正規表現}といった3属性にして
{ユーザID, 正規表現No}にPK制約をかける。正規表現Noは
1から10までの、ユーザごとの正規表現の通し番号です。

「ID=ユーザーID*10+0」という表現はユーザIDと正規表現No
の二つを表現しているので、すぐ隣に「ユーザID」属性もある
ことを考えると意味的にオーバーラップしています。
こういう属性は後日色々とトラブルの元であることが経験的に
知られています。
例えば今日から正規表現数を20個まで増量!などした時など。
62NAME IS NULL:2009/03/09(月) 20:28:49 ID:???
なるほど。
{ユーザID, 正規表現}でPK制約しようと思いましたが、
フレームワークがCakePHPなんで
IDは制約として必要で複合キーもサポートされていないみたいです。
しょうがないのでやっぱり、ID=ユーザID*10+0にしてみようと思います
ありがとうございました。
63NAME IS NULL:2009/03/09(月) 21:05:21 ID:???
なんでわざわざ SQL のスレで聞くのか・・・
64NAME IS NULL:2009/03/09(月) 21:51:22 ID:???
タイトルに「質問」「質疑」って書いてあるスレ他にあまり無いし。
DB設計の方は「語る」スレらしいのでこっちに流れてくるのも
仕方がないのではないかと。
65NAME IS NULL:2009/03/09(月) 22:13:58 ID:???
SQLServer2000を使用しています。
テーブルAに項目1がありそのMAX値に+1をした結果を
テーブルAにインサートするストアドプロシージャを作りました。

複数プロセスから同時実行する際に排他ロックをかけたいのですが、
デッドロックのような状態になってしまいました。(3プロセス同時)

ロックの考え方が間違っているのでしょうか?

@param1 output
AS
Begin Transaction

SELECT @param1 = MAX(項目1)+1
FROM テーブルA
WITH (TABLOCK,XLOCK)

INSERT INTO テーブルA(項目1)VALUES(@param1)

Commit Transaction
66NAME IS NULL:2009/03/09(月) 22:23:38 ID:???
ロックについてはわからんけど。

auto_increment 列を使うのが一般的じゃない?
67NAME IS NULL:2009/03/09(月) 22:57:06 ID:???
>>62
やめたほうがいいって回答されてるのにあえてやるってのは、回答者への
嫌がらせなんだろうかw

PKをIDにしても、べつにUNIQUE NOT NULLな制約は付けられるでしょ?
68NAME IS NULL:2009/03/09(月) 23:06:51 ID:???
>>62
複合キーを使えないというのであれば、普通にサロゲートキーに
しておいた方が良いと思う。
「ユーザID*10+x」なんてキーにするなんて、仕様に自ら爆弾を
仕込むようなものですぜ。
69NAME IS NULL:2009/03/09(月) 23:08:18 ID:???
SQLiteって、CHECK制約が使えないってひどくないですか。

データーの入る範囲を、1−100にしたい、とか思っても、
できないってことじゃないですか。
70NAME IS NULL:2009/03/09(月) 23:24:44 ID:???
>>69
MySQLの間違いじゃなくて?
71NAME IS NULL:2009/03/09(月) 23:30:57 ID:???
>>70
SQLiteのはなしだよ
72NAME IS NULL:2009/03/09(月) 23:31:52 ID:???
アプリ側で制約すればいいじゃん。
73NAME IS NULL:2009/03/09(月) 23:42:23 ID:???
>>66
ありがとう

ただ、他のテーブルも同じように排他ロックをかけようとしていたので
先ほどの条件でうまく排他制御できないことが気になってました。

もう少し自分で試してみます。
74NAME IS NULL:2009/03/09(月) 23:42:55 ID:???
>>71
う、う〜ん?

http://www.dbonline.jp/sqlite/table/index7.html

うっふん
75NAME IS NULL:2009/03/09(月) 23:50:15 ID:???
>>74
読んでる教科書が2005年発行のやつだったので
古かったようです。
76NAME IS NULL:2009/03/10(火) 10:13:25 ID:???
実際にやってみて困った話じゃないのかよ
77NAME IS NULL:2009/03/10(火) 21:31:56 ID:???
だって教科書読んでたら、
対応してない、って書いてあるんだもん
78NAME IS NULL:2009/03/10(火) 22:54:44 ID:???
でも他人様の成果物に対して「ひどい」なんて文句をここに
書き込む前にちょっとはクグろうや。
「sqlite check」で一瞬で見つかったよ。
79NAME IS NULL:2009/03/10(火) 23:17:37 ID:???
トリガーっていうの、
よくわかりません
80NAME IS NULL:2009/03/10(火) 23:21:03 ID:???
>>79
Insert とか Update とか Delete とかが発生したときに呼び出されるプロシージャ。

TableA のデータが削除されたタイミングで、TableB の関連データを削除する、
とかってときに使えるよ。
81NAME IS NULL:2009/03/11(水) 00:10:13 ID:???
ようはストアード・プロシージャの一種なのね。
違いがわからんかった。
82NAME IS NULL:2009/03/11(水) 00:21:19 ID:???
ユリウス暦ってのがよくわかりません
83NAME IS NULL:2009/03/11(水) 00:21:51 ID:???
スキーマとプラグマの違いがよくわかりません
84NAME IS NULL:2009/03/11(水) 00:22:03 ID:???
>>82
それは SQL に関係なさそうです。
85NAME IS NULL:2009/03/11(水) 00:23:58 ID:???
ランダムに1−5を生成して、
それをボタンが押されるごとに、
どんどん足していく、というプログラムなのですが、
SQL側でランダムに数字を生成して足す、という
構造に今、しているのですが、

「○を足しました」

とかってPHP側で表示したいのですが、今、
いくつの数字をランダムに生成して、いくつ足したのか、
って、PHP側で知る方法はあるのでしょうか?

それとも、前後の差分を取るしかない?
86NAME IS NULL:2009/03/11(水) 00:25:57 ID:???
>>84
だってユリウス暦を取得する、って関数があるんです。
昨日発見しました。
87NAME IS NULL:2009/03/11(水) 00:28:24 ID:???
>>85
SQL でどんな処理をしてるのか書こうな。

>>84
ユリウス歴が何かは Google とかで調べような。
SQL には直接関係ないから。
88NAME IS NULL:2009/03/11(水) 00:35:53 ID:???
>>79
もちっと厳密に言うと、active databaseという考え方が元になっていて、

・○○が起きたときに (Event: イベント)
・△△だったら (Contition: 条件)
・XXしちゃう (Action: アクション)

のECAの三つ組みをデータベーススキーマとして登録する仕組み。
外部キー制約などで表現しきれないリレーションやその間の制約
を表現したり、データ更新のログをとったりするのに使えたりします。

>>82
どっちかというとこの質問はWikipediaの領分かな。
欧米における日本の旧暦みたいなものです。
今でも正教会とか、お祭りを今のグレゴリウス暦ではなく昔の
ユリウス暦で祝うところがまだあるんです。

しかしこれを実装するのであればDATE値から大安とか丑年とか
計算してくれる関数がないと不平等だよな。
89NAME IS NULL:2009/03/11(水) 00:39:57 ID:???
>>85
> ランダムに1−5を生成して、
> それをボタンが押されるごとに、
> どんどん足していく、

なんか、最近似たようなモンを見たような気がするが、なんかの課題なのか?
90NAME IS NULL:2009/03/11(水) 01:10:43 ID:???
SQLite3で、
あとからAUTOINCREMENT 指定するのは
不可能?
91NAME IS NULL:2009/03/11(水) 01:29:47 ID:???
>>89
どれ?
92NAME IS NULL:2009/03/11(水) 01:50:35 ID:???
前スレでの話しだな。> ランダム

で、その前スレから疑問に思ってたけど、乱数生成をSQL側でしようとするのが疑問だった。
最終的にはUPATE Table SET val = val + random().... 的な使われ方だけで
済むのならSQLで済ませてもいいけど、いろいろ制約(乱数の範囲やvalの最大値)があるみたいだし、
素直にPHPで生成させておけば、そんなに悩むものでも無かろう。
93NAME IS NULL:2009/03/11(水) 01:53:49 ID:???
>>92
それで生成させたランダム値を
PHP側で知りたいんですけど、無理ですか?
94NAME IS NULL:2009/03/11(水) 01:55:05 ID:???
ようはコンビニでおでんを買って、
「たれは、ごまだれにしますか?からしにしますか?それとも何もつけないようにしますか?」
って聞かれて
「ランダムでいいです」
って答えて、
「でも、ランダムに決定して、その結果は教えてね」
みたいな。
95NAME IS NULL:2009/03/11(水) 01:57:29 ID:???
>>93
できるだろ。テーブルに1件だけデータを入れておいて、Update のあと Select するとか。
96NAME IS NULL:2009/03/11(水) 09:12:08 ID:???
テンポラリーテーブルか。
うまいね。
97NAME IS NULL:2009/03/11(水) 19:24:23 ID:???
SQLite3の最新版で、
alterで、テーブルを作成したあとに、
autoincrementを付加することは可能なの?
98NAME IS NULL:2009/03/11(水) 20:48:51 ID:???
http://sqlzoo.net/

いいページ見つけた。
ボタンを押すとSQL文を生成してくれるっていう。
99NAME IS NULL:2009/03/11(水) 21:03:16 ID:???
見せる… 行ロックを無限に発生させてしまうSELECT文が…
100NAME IS NULL:2009/03/11(水) 23:37:10 ID:???
>>4に関連して「最新のものの次点のレコード」を抽出したい場合は
どうすればいいでしょうか。
DBはOracle10gです。

<出力イメージ>
1 | 2007-11-10 | ccc
3 | 2007-11-11 | eee
101NAME IS NULL:2009/03/12(木) 00:16:43 ID:???
>>100
1 | 2007-11-11 | aaa
の間違いじゃね。

Oracle使いじゃないけど、WITH句を使うとこんな感じかな。
WITH RemoveMax AS (SELECT * FROM Table WHERE (id,date_) NOT IN (SELECT id,max(date_) FROM Table GROUP BY id))
SELECT * FROM RemoveMax JOIN
(SELECT id,max(date_) AS date_ FROM RemoveMax GROUP BY id) AS T1
USING (id,date_);

WITH句なしで、
SELECT * FROM
(SELECT * FROM Table WHERE (id,date_) NOT IN (SELECT id,max(date_) FROM Table GROUP BY id))AS T1
JOIN
(SELECT id,max(date_)AS date_ FROM
(SELECT * FROM Table WHERE (id,date_) NOT IN (SELECT id,max(date_) FROM Table GROUP BY id))AS T2
GROUP BY id)AS T3
USING(id,date_);

フィールド名にdateは使えないのでdate_としています。
102NAME IS NULL:2009/03/16(月) 20:39:51 ID:???
create table categorizings(
product_id integer not null references products(id),
category_id integer not null references categories(id),
sub_category_id integer references sub_categories(id),
created_at datetime not null default current_datetime,
updated_at datetime not null default current_datetime
)
というテーブルがあるのですが、重複しているレコードがあるので、それを抽出しようとしています。
はじめは
select product_id, category_id, sub_category_id
from categorizings
group by product_id, category_id, sub_category_id
having count(*) > 1
としていたのですが、重複しているデータのcreated_atとupdated_atも抽出するようにと言われて、困ってます。
今は
select c1.*
from categorizings c1
where concat(c1.product_id, '-', c1.category_id, '-', c1.sub_category_id) in
  (select concat(c2.product_id, '-', c2.category_id, '-', c2.sub_category_id)
   from product_categorizings c2
   group by c2.product_id, c2.category_id, c2.sub_category_id
   having count(*) > 1)
;
としているのですが、パフォーマンスが遅いし、これで正しいのかもよくわかりません。
なんかいい方法を紹介してください。よろしくお願いします。

MySQL 5.45
103NAME IS NULL:2009/03/16(月) 20:55:12 ID:???
未チェック。概念だけ

select A.*
from
categorizings A,
(select
product_id, category_id, sub_category_id,
count(*) as RNUM
from categorizings
group by product_id, category_id, sub_category_id
) B
where
A.product_id = B.product_id and
A.category_id = B.category_id and
A.sub_category_id = B.sub_category_id and
B.RNUM > 1
104NAME IS NULL:2009/03/16(月) 23:19:26 ID:???
>>102
パフォーマンスを気にするのなら、
product_id, category_id, sub_category_idのカラムを
複合primary keyに持つcategorizings_duplicatedなりの
別テーブルを作って前者のSQLをinsert intoして
それとjoinするのが最速かと。
105NAME IS NULL:2009/03/17(火) 08:55:52 ID:HhqqMBkm
vistaに11gの30日番をインストールしました。
sqlplusがコマンドプロンプトと変わりません。
よく見慣れた十字架のお墓みたいなアイコンのsqlplusだけをインストール
できないでしょうか?
106NAME IS NULL:2009/03/17(火) 09:29:05 ID:???
GUI版のSQL*Plusは11gから廃止されました。
107NAME IS NULL:2009/03/17(火) 12:52:28 ID:HhqqMBkm
>>102
ありがとうございます。
108NAME IS NULL:2009/03/17(火) 20:57:32 ID:???
以下のようなデータがあるとします。
id no data
1 1 aaa
1 2 bbb
1 4 ccc
1 5 ddd

このデータをidとnoで昇順でソートした後
noの番号を降りなおしたい。
つまり、以下のように更新したい
1 1 aaa
1 2 bbb
1 3 ccc
1 4 ddd

このようなsqlはどのように記述すればよいでしょうか。?



109NAME IS NULL:2009/03/17(火) 21:33:45 ID:???
>>108
idとnoの組合せで一意になる、かつDBMSがOracleと仮定して

update TableName a
set no = (select b.RN
     from (select id,
            no,
            row_number() over (order by id, no) as RN
        from TableName) b
     where a.id = b.id
     and a.no = b.no)
;
110NAME IS NULL:2009/03/17(火) 22:03:11 ID:???
>>108
ついでにたぶん汎用解

update TableName a
set no = (select count(*) + 1
     from TableName b
     where a.id > b.id
     or (a.id = b.id and a.no > b.no))
;
111>>108:2009/03/18(水) 01:43:48 ID:???
>>109
>>110
ありがとうございます。
ちなみにmysqlです。
112>>111:2009/03/18(水) 16:24:28 ID:???
mysqlの場合は、以下のようにする。

update hoge as a inner join (select *,(select count(*) + 1 from hoge where no<x.no) as rownum from hoge as x) as b on a.id=b.id and a.no=b.no set a.no=b.rownum where a.id=1
113NAME IS NULL:2009/03/18(水) 20:43:22 ID:???
mysqlだとそんな奇怪なSQLになるのか・・・
とはいえ、>>110も標準SQLではないな。(UPDATE句に相関名は書けない)
相関名をやめて
update TableName
set no = (select count(*) + 1
     from TableName b
     where TableName.id > b.id
     or (TableName.id = b.id and TableName.no > b.no))
;
にすれば標準だと思うけど。
114NAME IS NULL:2009/03/18(水) 23:45:02 ID:???
Oracle10gにて
SQL中の文字列(WHEREの後ろとかLIKEの後ろ)にそのままでは使えない文字の全量、対応方法ってわかりますか?
115NAME IS NULL:2009/03/18(水) 23:49:07 ID:???
>>114
質問の意味が分からん
116NAME IS NULL:2009/03/18(水) 23:50:26 ID:???
予約語の一覧が欲しいのかな。
各RDBMSのマニュアル読んで、ユニークな列名を考えて下さい。
117NAME IS NULL:2009/03/18(水) 23:59:52 ID:???
>>114
質問の意図が、予約語と解釈する人もいれば、エスケープが必要な文字と
解釈する人もいそうな曖昧な質問の仕方だなw
118NAME IS NULL:2009/03/19(木) 00:55:19 ID:???
114です
すみません…

'%_(シングルコーテ、パーセント、アンダーバー)のようなエスケープが必要な文字を知りたかったのです。
119NAME IS NULL:2009/03/19(木) 14:20:58 ID:???
>>118
なかなか回答つかないもんだな。
まぁ、本来はOracleスレで聞いた方がよかったんだろうが。
知りたい内容に対応する公式リファレンスは以下かな。

テキスト・リテラル
ttp://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/sql_elements.html#41297

LIKE条件
ttp://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/conditions.html#7948

デフォルトだとリテラル文字列は'、LIKE条件はさらに%_も
エスケープが必要となるが、それを変更する方法も提供されているということか。
バインド変数を使えば、これらのしがらみからも幾分は開放される。
120NAME IS NULL:2009/03/19(木) 15:36:30 ID:???
>>108
このテーブルってid た
121NAME IS NULL:2009/03/19(木) 15:49:28 ID:???
>>108
このテーブルってidとnoがprimary keyだと思うんだけど、更新するカラムをprimary keyのするのはよくないと思うんだけど、どうなんだろう。

もし、俺がテーブル設計するなら、以下のようなカラムを用意して、idとnoをprimary keyにして、no2を更新カラムにする。

id no no2 data

こうしないと、以下のデータがあったとして、
id no data
1 1 aaa
1 2 bbb
1 3 ccc

二行目以下のnoを、まとめて+1するようなsqlをじた、キー重複エラーが発生する。
122NAME IS NULL:2009/03/24(火) 15:04:34 ID:yR1qlEgs
ある条件でORDERBYした時の、あるレコードの前後のレコードを取得することって可能ですか?

全レコードを一旦取得して、ホスト言語で前後を抽出するか

ORDER BYが一個のカラムなら、対象レコードのそのカラムより大きいものをCOUNTして、
OFFSETでとってくることも可能かな
でも、ORDER BY対象がユニークなカラムじゃないとだめか・・

なんかどれも効率悪そうなんですけど、もっといい方法ありますか?
MySQLです。
123NAME IS NULL:2009/03/24(火) 15:36:53 ID:???
あるレコードの前後つーのは、
あるレコードの前→あるレコードより小さい中での最大
あるレコードの後→あるレコードより大きい中での最小
124NAME IS NULL:2009/03/24(火) 15:54:42 ID:???
ORDERBY対象がユニークなカラムじゃない
のに特定レコードの前後を取りたいとかアレなの?
氏ぬの?
125NAME IS NULL:2009/03/24(火) 17:54:44 ID:???
>>122
具体例を挙げないと、何をしたいのかわからん人がほとんどだと思う(俺も含め)。
ソートした結果の10位前後のレコードを取り出したいというのなら
「じゃあ select * from table order by key limit 9, 3; でいいじゃん」
と誰もが答えるだろう。
126NAME IS NULL:2009/03/24(火) 18:32:38 ID:yR1qlEgs
>>123
ああ、そうか、そう考えれば簡単ですね。ありがとうございます。


>>124
ありがとうございます。
例えば更新日時で時系列に次へ次へみたいにリンクを出したい時、
そういう場合どうすればいいのでしょう?
更新日時って同じタイムスタンプになる確率があるって聞いたんですけど
更新日時カラム自体をユニークにして万が一同じタイムスタンプになったら、再保存するようにするのでしょうか?

これが例えば変更されない登録日時なら主キーを使ってしまうって言う手もありますけど。

まあ、そもそも、更新されたら並び順が変わるし、このインターフェイス自体が問題あるきもしますけど。
127122:2009/03/24(火) 18:42:55 ID:yR1qlEgs
>>125
具体的には126にちょっと書きましたが
記事の表示ページに更新日時順で次へ、前へというリンクを出したいんです。

で、そのページはダイレクトに主キーで記事を指定してくることもあるのでLIMIT 1 OFSSET〜っていうわけには行かない感じなんです
128125:2009/03/24(火) 19:06:53 ID:???
>>127
ページング処理をしたかったのね。
俺も業務上そのテの開発はよくやるけど、やっぱり limit x, y だよ。
記事を指定して、その記事が含まれるページ(例えば81〜90件目を表示)とかに
飛ぶようなリクエストが発生するシステムであれば、
(順位, 更新日時, 記事ID) を持つソート済みテーブルをあらかじめ作成しておく。
レコード数が多いなら記事IDにindex付与。
更新日時が可変で順位が変わる可能性があるのなら、その頻度に応じてソート済みテーブルを再構築する。
129NAME IS NULL:2009/03/24(火) 20:06:31 ID:???
じゃ123でいいじゃん
130NAME IS NULL:2009/03/26(木) 08:01:10 ID:???
テーブルX(a,b)と
テーブルY(b,c)で
列bを結合キーにした場合、
テーブルXに無いレコードをテーブルYから削除するには
どのようなSQL文を書けば良いでしょうか
131NAME IS NULL:2009/03/26(木) 08:05:03 ID:???
where not in select b from A
でいいんじゃないの?
132NAME IS NULL:2009/03/26(木) 08:05:42 ID:???
ごめんAじゃなくてXだった
133130:2009/03/26(木) 08:13:50 ID:???
>>131
ありがとうございます

結合は不慣れでして…
ちゃんと勉強しないといかんな
(´・ω・`)
134NAME IS NULL:2009/03/26(木) 08:26:15 ID:???
>>133
結合は慣れです。
経験を積めば楽に結合出来るようにもなります。
慣れるまではプロの手ほどきを受けるのも良いかもしれませんね。
135NAME IS NULL:2009/03/26(木) 08:29:49 ID:???
131で書いたのは結合じゃなくてサブクエリだけどね
136NAME IS NULL:2009/03/27(金) 02:32:29 ID:p8FYVGy/
質問です。

以下のような、木構造のデータがあるとします。
東京→大田区→蒲田→羽田1丁目
東京→大田区→蒲田→羽田2丁目
東京→千代田区→秋葉原
大阪→住之江区→緑町

これを、テーブルに以下のような形式で入れるとします。
name prev_name
東京 東京
大田区 東京
蒲田 大田区
羽田1丁目 蒲田
羽田2丁目 蒲田
千代田区 東京
秋葉原 千代田区
大阪 大阪
住之江区 大阪
大阪市 大阪
緑町 住之江区

name=prev_nameなレコードが親トップとなります。(上記のデータですと、東京と大阪が親トップにあたります)

この状態から、name=大田区のレコードを削除されたと考えてください。
ここから、name=(蒲田、羽田一丁目、羽田二丁目)のデータを取得するにはどのようなSQLをかけばよいでしょうか?


※ 住所をこのような形式で管理するのはおかしい!と感じる方もいらっしゃると思いますが、
これは問題をわかりやすくするため、このようにしています。
実際に住所を上記のような管理をしようとしているわけではないので、あらかじめご了承ください。
137NAME IS NULL:2009/03/27(金) 03:02:29 ID:???
>>136
恐らく、あなたが欲しいであろう回答をもらうための
前提条件が十分に説明されていない。
name in ('蒲田', '羽田一丁目', '羽田二丁目')
で満たされてしまうからだ。
138NAME IS NULL:2009/03/27(金) 03:09:42 ID:p8FYVGy/
>>137
説明が足りず、すいません。

親がなくなってしまったname=蒲田のレコードと、その配下のレコード全部(つまり、羽田一丁目、羽田二丁目)を抽出したいという意味です。


139NAME IS NULL:2009/03/27(金) 03:33:47 ID:???
>>138
その説明でも曖昧さはまだ残るのだが…。
「親が存在しない、つまり不完全な構造になってしまった全てのレコード
およびその子ノードたち(一世代まで下)を列挙したい」
と勝手に解釈するなら
select name from table_name
where prev_name not in (select name from table_name)
union all
select name from table_name
where prev_name in
(select name from table_name
where prev_name not in (select name from table_name))
140>>139:2009/03/27(金) 03:57:31 ID:p8FYVGy/
>>139
解釈ありがとうございます。。。

>一世代まで下
ここは、一番最後の世代まで下、という解釈でお願いします。

ちなみに、MySQL使っております(後だしすいません。。)
141NAME IS NULL:2009/03/27(金) 04:04:34 ID:???
>>140
これ、難しいけど問題としては面白いな。
解けそうで、解けないというか、一番最後の世代というところが難しいわ。
142139:2009/03/27(金) 04:34:57 ID:???
>>140
そういうことなら、スマンが俺なら一つのSQLで済ますのはサジを投げる。
ストアドかホストアプリ側で列挙が完了するまでループ。
想定するシーンによっては、ホストアプリ側でn分木を再構築して
探索にはSQLに頼らない処理も考える。
いずれの方法も、循環参照の危険があるならそれも考慮しないと無限ループにハマるがな。
143139:2009/03/27(金) 04:47:26 ID:???
>>140
ふと思ったが、もしかしてディレクトリツリーの再帰削除みたいなことをしたいのか?
それならトリガで子ノード(一世代だけでよい)のDELETE書くだけで済むけど。
144NAME IS NULL:2009/03/27(金) 21:43:25 ID:???
>>143
MySQLってトリガのネストとか再帰とか可能なのか?
可能だとしても、階層に限界はあるだろうから、あまりにもネストが深いと失敗するかもな
145NAME IS NULL:2009/03/27(金) 23:11:51 ID:???
MYSQLはOLAP使えないの?
146NAME IS NULL:2009/03/28(土) 06:47:54 ID:???
どの程度の事をやりたいか判らないけどMYSQLのSELECT文には
WITH ROLLUP修飾子なるものが階層別の集計はやってくれる。

これ以上を求めるならMondrian辺りを突っ込んでMDXでクエリを
書いた方が幸せになれると思う。
147NAME IS NULL:2009/03/28(土) 07:07:21 ID:???
whereでヒットしたレコードの指定件目を
SQL文だけで取得したいのですが、
どうすれば良いですか><
148NAME IS NULL:2009/03/28(土) 08:02:24 ID:???
>>147
LIMIT 〜 OFFSET 〜が使えるDBMSならそれで
ROW_NUMBER()が使えるDBMSならそれで
149NAME IS NULL:2009/03/28(土) 08:46:18 ID:???
countでいいじゃん
150NAME IS NULL:2009/03/28(土) 09:19:08 ID:???
指定件目だぞ
なんでcountだよ
151147:2009/03/28(土) 10:20:03 ID:???
>>148
ありがとうございます
sqliteですが、使えるか確認してみます><
152NAME IS NULL:2009/03/28(土) 18:41:16 ID:???
>>147
orderを指定しないselectの、行が返される順番は保障されない
ということは覚えておいた方が良いかもしれない
153NAME IS NULL:2009/03/28(土) 23:07:57 ID:???
>136

パッと見たかんじ、最大何階層になるかだけ解れば可能なように見える(実際SQL叩いてないけどw)。
最大階層数が不明なら階層数調べるためにループさせる必要があると思うのでストアドっぽい気がする。
154NAME IS NULL:2009/03/28(土) 23:13:21 ID:???
>147
「ORDER BY」、「ROWNUM」
155147:2009/03/29(日) 05:03:08 ID:???
LIMITとORDERで出来ましたヾ(^▽^)ノ
教えて下さった方々、どうもありがとうございました
156NAME IS NULL:2009/03/29(日) 19:51:33 ID:???
礼にはおよばんよ。
またいつでも聞きにきなさい。
157NAME IS NULL:2009/03/31(火) 11:55:58 ID:???
データベースダイアグラム(リレーションシップ)っていままで使用せずに来ましたが、
これって使うのが一般的ですか?

例えば、伝票ヘッダテーブル・伝票明細テーブルがあったとして、データベースダイアグラムしておくと、
ヘッダテーブルのレコードを削除すると、そのレコードに対応する明細テーブルからも自動的に削除される
って認識でいるのですが、なんか使いにくい気がしていつもコードからヘッダテーブル・明細テーブルを削除
しにいってます。

どうなんでしょうか。
158NAME IS NULL:2009/03/31(火) 13:21:31 ID:???
データベースダイアグラムってMS SQL?
159NAME IS NULL:2009/03/31(火) 13:39:17 ID:???
そうです。MS SQLです。
ACCESSでもリレーションシップは使っていませんでした。。
160NAME IS NULL:2009/03/31(火) 15:12:25 ID:???
必要なきゃ使わなくていい。

ここは、SQL のスレであって、SQL Server のスレではないことに
気をつけような。
161NAME IS NULL:2009/03/31(火) 15:48:17 ID:???
要は外部キーみたいなものだろうから、普通使うだろ。
162NAME IS NULL:2009/03/31(火) 18:06:28 ID:???
みんな、サンクス。
すれ違みたいなので、そっちへ行くわ。。

163NAME IS NULL:2009/03/31(火) 22:56:36 ID:???
開発中はリレーション張って開発するけど
本番はインサート性能落ちるからリレーション張らないな
Webだけの常識かもしれないけど
164NAME IS NULL:2009/03/31(火) 23:11:28 ID:???
そうなんだ!?
情報サンクス〜^^
165NAME IS NULL:2009/04/01(水) 05:33:13 ID:???
>>163
本番で外すような制約を開発時につけてるのか?
俺は開発時はリレーションに制約付けない。データの作成とか変更とかやりにくくなるから

逆に、本番は制約付ける。
制約のそもそもの目的は不正データの排除だから、本番についてないなら意味だろう

どうしても性能の問題で制約外すことはあるかもしれないが、
Webだけの常識ってのは違うとおもうぞ
166NAME IS NULL:2009/04/01(水) 08:03:45 ID:???
Webシステムは伝統的にMySQLを使う事が多くて、
それにはMyISAMってのがあってだな、
設計時には勿論、外部キーを考慮してデータ設計するんだけども、
実際には云々以下略
167NAME IS NULL:2009/04/01(水) 10:04:18 ID:???
>>166
> Webシステムは伝統的にMySQLを使う事が多くて、

プゲラw

お前さんのところの伝統を語られてもな・・・
168NAME IS NULL:2009/04/01(水) 11:20:19 ID:???
まぁ実際問題Webサイトの大多数はMySQLだろうけどね
169NAME IS NULL:2009/04/01(水) 11:33:32 ID:???
まぁ、スレ違いだな
170NAME IS NULL:2009/04/01(水) 19:02:50 ID:???
クイズを出すPHPサンプルを弄っているのですが
問題を、AUTO_INCREMENTでIDを増やしつつ追加して
後で一部の問題を削除すると、空のIDでエラーになります。
つめて整理する方法&AUTO_INCREMENTを最後尾から
再スタートする方法はあるのでしょうか?
171NAME IS NULL:2009/04/01(水) 19:08:19 ID:???
エスパーだが1〜最大IDまでのランダムなIDで出題してるの?
もしそうならORDER BY RAND()とか
172NAME IS NULL:2009/04/01(水) 19:41:38 ID:???
そうです。
$id = rand(1, $count[0]);
としているのでハズレを引いていると思います。
ORDER BY RAND()調べてみます。
サンクス
173NAME IS NULL:2009/04/02(木) 06:44:19 ID:???
>>170
>質問するときはDBMS名を必ず付記してください。

空き番号をつめるのはupdate書けばできるだろうけど、
自動採番が設定されてるカラムをupdateできるかどうかはDBによるんじゃね

自動採番号の設定値変える方法もDBによるんじゃね
174NAME IS NULL:2009/04/02(木) 08:51:36 ID:???
DBMS?
175NAME IS NULL:2009/04/02(木) 09:07:21 ID:???
でーたーべーすまねーじめんとしすてむ
ようは、つかってるDBの種類かけと
いろいろあるだろ、ORACLEとかMySQLとかACCESSとか桐とかファイルメーカーとか
176NAME IS NULL:2009/04/02(木) 09:14:32 ID:???
だからそれDBじゃなくてDBMS
177NAME IS NULL:2009/04/02(木) 09:32:08 ID:???
この場合のDBはDBMSの意味で使ってる
DBMSという用語が理解できるなら文脈でわかると思うが
DBMSとDBの区別がついてない人にとっては、DB=DBMSだからな

DBとDBMSという用語を明確に使い分ける必要はあんまりないんじゃない
178NAME IS NULL:2009/04/02(木) 12:18:43 ID:???
あるんじゃないのかな。
アドバイス出来るほど理解出来ている人であればこの辺りは
誤解を招かないように意識して使い分けて書くべきだと思う。
文脈からも読めるかも知れないけど、ちゃんと言葉で明確に
区別するのに超した事はないよね。

スキーマとインスタンス、リレーションとテーブルとかと同様に
「似ているようで全然異なる、区別してもらわないと困る」類の
言葉だと思うよ>DBとDBMS
179NAME IS NULL:2009/04/02(木) 16:03:47 ID:???
明確に使い分ける方がいいって意見はまあ納得できるんだが
会話は相手に伝わらないことには意味がないからな

>>173は確かにDBMSと書くべきだった
>>175は、>>174がDBMSとは何かわからない人の発言かと思い、
あえてDBMSではなくDBと書いてある

DBという言葉は割と一般的に使われるが、DBMSという言葉は一般的ではないと思うんだ
そして一般にDBという場合、その多くがDBMSのことだったりすんだよな
俺は今のDBという言葉はDBMSを含んだ広い概念の言葉になってると思ってる
180NAME IS NULL:2009/04/02(木) 16:12:44 ID:???
一般にDBという場合はドラゴンボールだろ
この板出来たときから居るけど、最初の1年くらいは
ドラゴンボールのスレが沢山あったんだぜ
181NAME IS NULL:2009/04/02(木) 19:49:22 ID:???
実際の会話じゃないんだから
DBMSって言われて知らなかったら調べるだろ

相手をばかにしてるだけ
182NAME IS NULL:2009/04/02(木) 19:59:22 ID:???
スルーで良いだろ
わざわざ相手にする必要なし
183NAME IS NULL:2009/04/02(木) 20:25:20 ID:???
2003年に立ったドラゴンボールスレがまだ残ってるわけだが
184NAME IS NULL:2009/04/02(木) 20:42:00 ID:???
>一般にDBという場合はドラゴンボールだろ
一般の友人のブログで「DBが〜…」とか書いてあって、「え!?なんでRDBMS知ってんだ!!」と驚いて本文を読んだらウボォー('A`)
185NAME IS NULL:2009/04/02(木) 22:39:10 ID:???
>>179
お前がDBMSをDBと書くことによって相手に伝わってないじゃん
174で突っ込みもらってすら173のおかしさに気づけない時点で理解できてないことが見え見え
186NAME IS NULL:2009/04/03(金) 12:07:39 ID:???
そうだな。DBMSがわかるやつが、あの文で通じないとはたしかに理解できてなかった
あと、おもったより、>今のDBという言葉はDBMSを含んだ広い概念の言葉になってると思ってる
が支持されてないようなので、今後は考えを改めることにするわ

いいかげんスレ違いなのでこの話題は俺はここまでにする
187NAME IS NULL:2009/04/04(土) 23:48:34 ID:Zi6VTYVX
よろしくお願いします。
ある行の内容全て(主キーを除く)を、他の行へコピーしたいのですが、
どう書けばいいですか?

例)
ID | DATE     | DATA
--+----------+-----
1 | 2009-04-05 | aaa
2 | 2000-01-01 | bbb

ID=1のDATEとDATAの内容を、
ID=2のDATEとDATAへコピーしたい

理想の結果)
ID | DATE     | DATA
--+----------+-----
1 | 2009-04-05 | aaa
2 | 2009-04-05 | aaa ←ID=1と同じ内容になる

(SQL文のイメージ)
UPDATE テーブル名 SET 【ID2の"ID"以外の全ての内容】 = 【ID1の"ID"以外の全ての内容】
188NAME IS NULL:2009/04/04(土) 23:52:43 ID:???
サブクエリ
189NAME IS NULL:2009/04/05(日) 00:26:18 ID:???
Oracleとかだと
 update テーブル名
 set (DATE, DATA) = (select DATE, DATA
           from テーブル名
           where ID = 1)
 where ID = 2
って書けたりするけど標準SQLだと
 update テーブル名
 set DATE = (select DATE
       from テーブル名
       where ID = 1),
   DATA = (select DATA
       from テーブル名
       where ID = 1)
 where ID = 2
みたく書くしかないかな
190187:2009/04/05(日) 00:34:23 ID:???
>>189
ありがとうございます。とても助かりました。
標準SQLですので、後者を使わせていただきます。
191NAME IS NULL:2009/04/05(日) 00:44:22 ID:???
その解だとID毎に全部書かなきゃならんのだが・・
192NAME IS NULL:2009/04/05(日) 01:59:55 ID:???
>>187
コピーする件数にもよるだろうけど、多くなければdeleteしてinsert

delete from テーブル名 where ID = 2

insert into テーブル名 (ID, DATE, DATA)
select 2, DATE, DATA from テーブル名 where ID = 1
193NAME IS NULL:2009/04/05(日) 03:26:50 ID:???
>187
MS SQLなら

update work
set [date] = w1.[date],
data = w1.data
from work,work w1
where work.id=2 and w1.id=1;

MYSQLは

UPDATE WORK, WORK W1
SET WORK.`DATE`=W1.`DATE`,WORK.DATA=W1.DATA
WHERE WORK.ID=2 AND W1.ID=1;

POSTGRESQLでは

update work
set "date" = w1."date",
data = w1.data
from work w1
where work.id=2 and w1.id=1;
194NAME IS NULL:2009/04/05(日) 10:18:33 ID:???
おまいら家のPCにDB環境いくつある?
195NAME IS NULL:2009/04/05(日) 11:04:04 ID:???
Oracle Express EditionとDB2 Express-C
196NAME IS NULL:2009/04/05(日) 11:16:04 ID:???
何故そこにMS SQLの無料エディションが無い。
197NAME IS NULL:2009/04/05(日) 11:26:19 ID:???
・会社で使ってないから
・Linuxに乗らないから
198NAME IS NULL:2009/04/05(日) 11:30:37 ID:???

    ∧__∧
    ( ・ω・)   Windows以外はいやDOS
    ハ∨/^ヽ
   ノ::[三ノ :.、
   i)、_;|*く;  ノ
     |!: ::.".T~
     ハ、___|
"""~""""""~"""~"""~"
199NAME IS NULL:2009/04/05(日) 14:50:39 ID:???
>194

おれっくらいの達人になると脳内DBだぜ、
脳内DBは10行3列までしか格納できないのがちょっと不便。
200NAME IS NULL:2009/04/05(日) 15:19:07 ID:???
九九も入らないなw
201NAME IS NULL:2009/04/05(日) 16:03:03 ID:???
九九のDB作るには複合インデックスも必要だしね。
ににんがし〜
202NAME IS NULL:2009/04/05(日) 16:38:35 ID:???
>>197
スレチだがDB2は日本では普及してるの?
SQLServerの元になったRDBだよね?
203NAME IS NULL:2009/04/05(日) 16:40:19 ID:???
SQLServerの元はSybaseですがな。
204NAME IS NULL:2009/04/05(日) 16:50:18 ID:???
DB2はIBM関係の仕事してたらまず間違いなく使うことがある
逆にIBMと関係ない仕事してたらまず間違いなく使わない
HiRDBと日立、Symfowareと富士通みたいなもんだ
205NAME IS NULL:2009/04/05(日) 16:59:57 ID:???
そんなもんと一緒にすんなって怒られそうだな
206NAME IS NULL:2009/04/05(日) 17:59:00 ID:???
>HiRDB
日立系の人から「使ってる?」と聞かれたことがあるけど、「知りません」って答えたら「そうでしょうね」と納得していたのが忘れられない。
207NAME IS NULL:2009/04/05(日) 19:11:36 ID:???
うちは、日立の子会社だけど基幹は Oracle だし、
俺自身も使ったことないし。
208NAME IS NULL:2009/04/05(日) 20:10:37 ID:???
富士通も日立も普通にオラクルだよw
有名で実績あるからオラクルのほうが入れやすいんだと思う
少々高くても金はあるところにはあるし。
209NAME IS NULL:2009/04/05(日) 23:54:48 ID:???
しかしIBMはそういう場合でもDB2を入れてくる会社なんだぜ
210なまえ:2009/04/06(月) 00:20:55 ID:???
SQLの基礎はIBMの研究所で確立されたと聞いたことがあるぞ
そうなると、DB2はもっとも由緒あるRDBMSといえるんじゃないかな

ま、由緒があるから機能や性能が優れてるとは限らんがw
211NAME IS NULL:2009/04/06(月) 01:42:25 ID:???
>210
由緒はある、だが、パクって磨いて売りまくったのはオラクル。
212NAME IS NULL:2009/04/06(月) 22:39:19 ID:???
よろしくお願いします。
初めてaccess触ってるもんでさっぱりです・・・

レコードを、起算日から終了日までの日数分出力したいのですが、どうすればよろしいでしょうか?


例)

ID data 起算日 終了日
--------------------------
001 A 20080101 20080110 ←10日分出力したい
001 B 20080201 20080220
213NAME IS NULL:2009/04/06(月) 22:42:13 ID:???
(´・ω・`)…
214NAME IS NULL:2009/04/06(月) 23:03:48 ID:???
>212
そのテーブルの日付範囲を条件にして他のテーブルから日付範囲分のレコードを取ってきたいってことか?

select 起算日−終了日 from テーブル where 起算日−終了日 = 起算日−終了日

でOK。

解説は↓↓↓↓↓がする
215NAME IS NULL:2009/04/06(月) 23:35:28 ID:???
他のテーブル指定してねーじゃん
216NAME IS NULL:2009/04/06(月) 23:42:53 ID:???
>>214
抽出元は、このテーブルです
1行目の起算日から終了日までだと、日数が10日あるので10行表示するようなイメージです
217NAME IS NULL:2009/04/06(月) 23:45:34 ID:???
limitでいいじゃん
218NAME IS NULL:2009/04/06(月) 23:57:18 ID:???
>>216
20080101
20080102
.
.
20080110
ってことか? 標準的なSQLでは無理。
219NAME IS NULL:2009/04/06(月) 23:59:52 ID:???
まず、日本語で説明できるようになろうな。
220NAME IS NULL:2009/04/07(火) 00:03:51 ID:???
>>218
やっぱ、ダメか・・・
ありがとうございました。他の方法を考えてみます
221NAME IS NULL:2009/04/07(火) 00:21:15 ID:???
上司に説明してもらった方が解決しそう。
222NAME IS NULL:2009/04/07(火) 11:42:38 ID:???
変数に代入して+1してけばいいんじゃないの?
223NAME IS NULL:2009/04/07(火) 12:42:53 ID:???
BETWEENとかそういう話じゃなくてか
224NAME IS NULL:2009/04/07(火) 12:47:57 ID:???
RDBMSによってはできるな。
accessはわからんが
225NAME IS NULL:2009/04/08(水) 05:06:40 ID:???
テーブルをカラム A (ユニーク) でソートした時、A の値が 'HOGE' の行の
出現インデックスを取得するような SQL は書けますか?
先頭からループでブン回して出現位置を見つけるしかないんでしょうか?

Apache の Derby です。
226NAME IS NULL:2009/04/08(水) 05:39:49 ID:???
>>225
'HOGE' が何行目にあるか? ってことかな?
ApacheのDerbyは使ったことないが、
SELECT count(*) FROM Table WHERE A <= 'HOGE';
でいけるんじゃね?
227NAME IS NULL:2009/04/08(水) 08:11:16 ID:???
DBの統計情報を利用したいというように読める。
228社内SE:2009/04/08(水) 23:05:12 ID:???
>225
SQL書くんのめんどいからヒント

ソート
行番号
'HOGE'指定
最小

を1個ずつクリアしていけOK。
俺っくらいのレベルになると脳内DBでサクッとできるんぜ。
脳内DBのテーブルは3列10行制限

DBでインデックスとゆう用語は勘違いされるからむ
229NAME IS NULL:2009/04/08(水) 23:30:53 ID:???
ランクが知りたいんじゃないの?
230NAME IS NULL:2009/04/09(木) 11:33:54 ID:???
・oracle11g
・あろテーブルで、複数のカラムで一つのIDを持っているんですが、
 そのIDの重複の有無を調べるSQLを教えてください。
 型は全てnumberです。
231230:2009/04/09(木) 12:13:58 ID:???
勘違いしててすぐ解決しました。
232NAME IS NULL:2009/04/12(日) 23:57:56 ID:???
文字化けが直らない。
疲れ果てて質問も出来ない。
いじょう
233NAME IS NULL:2009/04/13(月) 00:06:52 ID:???
どのみちこのスレで文字化けの質問なんかしてもスレ違いだ
いじょう
234NAME IS NULL:2009/04/13(月) 00:36:36 ID:???
DB2は迷ったらUTF8、他のDBもおすすめの日本語文字コードがあります。
235NAME IS NULL:2009/04/13(月) 22:53:53 ID:z55NoKLw
達人の俺になんか問題を振ってくれ

age
236NAME IS NULL:2009/04/13(月) 23:02:01 ID:???
逆に今時どのDBでもUTF8だろ
Accessとかならともかく
237NAME IS NULL:2009/04/13(月) 23:27:03 ID:???
Accessは手軽にアプリケーションが作れるので気に入った。
238NAME IS NULL:2009/04/13(月) 23:45:35 ID:???
JIS 第一なら概ねあいうえお順だから JIS 順ソートが仕様になってる所は
UTF-8 使えないんじゃないの。
今時の DB は UTF-8 でも JIS 順ソート指定とかできるんか知らんが。
239NAME IS NULL:2009/04/13(月) 23:47:36 ID:???
UTF-8でSQLに渡してPHPから呼んで表に入れたら化けた。
SQLに渡したリストを表示するPHPは化けない。
化けてない方はブラウザもUTF-8で表示してる。
化けてる方はブラウザはEUC-JPで表示しててUTF-8に変更すると
SQL関係ない文字が化ける。
表作成のコードは一緒なのに。
もう嫌。
240NAME IS NULL:2009/04/13(月) 23:52:44 ID:???
なんだよ SQL って・・・
241NAME IS NULL:2009/04/13(月) 23:57:04 ID:???
IBMの研究所の偉い人が考えた言語
242NAME IS NULL:2009/04/14(火) 00:41:47 ID:???
仮にMySQLならset names スクリプトの文字コード やっちゃえよ
243239:2009/04/14(火) 14:12:12 ID:???
PHPファイル自体をUTF8で保存したら文字化け直った。
244NAME IS NULL:2009/04/14(火) 14:46:54 ID:???
要するに文字コード変換一切せずに突っ込んでたって事じゃないか
245NAME IS NULL:2009/04/14(火) 16:03:35 ID:???
   ∧∧
  ヽ(・ω・)/ ズコー
 \(\ ノ
、ハ,、  ̄
 ̄"
246NAME IS NULL:2009/04/14(火) 20:21:29 ID:???
何にせよスレ違い。二度と来んなよー
247NAME IS NULL:2009/04/14(火) 21:11:16 ID:???
where aaa<>'5'

と書くとaaa列がnullのレコードが取ってこれないのはどう理解しればいいですか?
納得いきません。

nullは'5'ではありませんので取ってくれよ、と思っています。
248NAME IS NULL:2009/04/14(火) 21:16:21 ID:???
>>247
DBにおけるNULLの扱いを勉強しましょう。
249NAME IS NULL:2009/04/14(火) 21:19:34 ID:???
>>247
null はどう評価しても null。つまり、true ではないから。
250NAME IS NULL:2009/04/14(火) 21:24:18 ID:???
>249
あんがと。

もうひとつ質問

''(シングルクォート2連続)はnullと同じですか?

aaa is null

aaa =''

は同じですか?
251NAME IS NULL:2009/04/14(火) 21:28:02 ID:???
>>250
252NAME IS NULL:2009/04/14(火) 21:33:09 ID:???
>>250
同じ扱いのDBMSもあったような気がする・・・Oracleだったかな?
253NAME IS NULL:2009/04/14(火) 21:34:12 ID:???
INSERT INTO ('')
INSERT INTO (NULL)

両者は同じになるのですが、どう理解しればいいでしょうか?
254NAME IS NULL:2009/04/14(火) 21:37:32 ID:???
>>250
DB による
255NAME IS NULL:2009/04/14(火) 22:35:24 ID:???
>>250
各RDBMSで挙動が異なる。
SQLの解説書によく出てくるよ。
256NAME IS NULL:2009/04/14(火) 23:24:22 ID:???
>>253
syntax error
257NAME IS NULL:2009/04/14(火) 23:26:04 ID:???
>256
なるほど。
どおりで同じわけだ。
258NAME IS NULL:2009/04/14(火) 23:37:17 ID:???
>>253
とりあえず、ここ読んでらっしゃ〜い
ttp://www.geocities.jp/mickindex/database/db_3vl.html
259NAME IS NULL:2009/04/14(火) 23:47:13 ID:???
よくある質問1の日付が未来まである場合のテーブルで、
今日未満の最新レコードを抽出する事は可能ですか?
260NAME IS NULL:2009/04/14(火) 23:50:22 ID:???
>>259
はい
261NAME IS NULL:2009/04/15(水) 00:05:41 ID:???
DATE型の大小関係で、「今日」という日付を使って
今日 <= MIN(DATE_column)

すべての日付の最小値をとり、今日を含む今日よりも新しい日付を抽出する。
262NAME IS NULL:2009/04/15(水) 00:55:28 ID:???
between句について質問です。(初心者です)
code between '123456' and '123459' で範囲指定した検索を行うと
検索結果に code 1234 も含まれます。 なぜでしょうか?
また、数値型に変換して cast句を使用したのですが、code に全角数字が
含まれる為、SQLエラーとなりうまくいきません。
何かよい方法は無いでしょうか?
263NAME IS NULL:2009/04/15(水) 00:59:43 ID:???
全角半角混在とは、、、
しょうがないから半角に統一するストアドファンクション作ろう
264NAME IS NULL:2009/04/15(水) 01:08:06 ID:???
>>263
ありがとうございます。
ストアドファンクションって何ですか?ってレベルなんですけど
調べてみます。
ちなみに、code には 「-」 も含まれます。。。。
265NAME IS NULL:2009/04/15(水) 01:22:27 ID:???
>>262
>>1

まあ code 1234 が '123456'より大きく'123459'より小さいと判断されてるのだろう
文字列の比較ルールは処理系や文字コードによるのでこれ以上はなんともいえない
266NAME IS NULL:2009/04/15(水) 01:35:00 ID:???
全角が入るって・・・エンドユーザの入力をそのままSQLに渡してるのか?
SQLインジェクションとか、別のとこで心配になってきたぞ。
ストアドで解決するよりも、ホストアプリ側でバリデーションすべきだと思う。
267266:2009/04/15(水) 01:42:32 ID:???
・・・と書いてから気づいたが、既存のレコードが全角なのね、勘違いしてた。
まあ、既に入っちまったもんは仕方ないか。
>>262 の使ってるDBが何か知らんが、「照合順序」がキーワードになるんじゃないかな。
268NAME IS NULL:2009/04/15(水) 02:22:41 ID:???
使っているDBはSQLSERBER2005です。照合順序をJapanese_binに設定しても同様にエラーがでます。。。
269NAME IS NULL:2009/04/15(水) 02:47:18 ID:???
>>268
全角半角を区別したくないんなら、Japanese_CI じゃないのか?
270NAME IS NULL:2009/04/15(水) 07:43:08 ID:???
質問です。

ISO規格のSQL(SQL-92)のみが使える機能を搭載したRDBMSはあるのでしょうか?
SASを使用しているのですがどうよらSQL-92が使える事は分かったのですが、各社の拡張機能をつい使ってしまう癖を直したくて質問しました。

よろしくお願いします。
271NAME IS NULL:2009/04/15(水) 13:50:48 ID:???
本来のもの以外は全く使えないって正月番組の英語禁止ゴルフかよ
272NAME IS NULL:2009/04/15(水) 15:12:05 ID:???
SQL Serverで
'1234' between '123456' and '123459' が真になるような
照合順序なんて無いと思うので、何かがおかしい
DBCC CHECKTABLEとかって2005でも実行できるのかな?
273NAME IS NULL:2009/04/15(水) 19:14:41 ID:???
>>270
Oracleだとalter session set flagger=fullとかやるとチェックできる。
他のDBMSでも似たような機能はあるんじゃない?(知らんけど)
274NAME IS NULL:2009/04/15(水) 20:26:48 ID:???
>>270
SQL92の良いリファレンスを買って手元に置く方が良いよ。
プロ野球養成ギプスじゃあるまいし、癖を直すにしても頭で
理解して直さないと意味がないでしょう。
275NAME IS NULL:2009/04/15(水) 20:36:27 ID:???
でもちょっとチューニングしようと思ったら SQL92 じゃどうしようもならんよね。
276NAME IS NULL:2009/04/15(水) 20:45:50 ID:???
BNFで充分だろ
ttp://savage.net.au/SQL/sql-92.bnf.html
まあ、BNFじゃ構文しか分からんが
277270:2009/04/15(水) 23:33:11 ID:???
ご意見ありがとうございます。
参考にします。
278NAME IS NULL:2009/04/16(木) 08:24:06 ID:???
質問です。
COLUMN Aの値がa1のところをa2に変えたいと思っています。
ただし制約があってCOLUMN AとCOLUMN Bでユニークなインデクスを作っているので
COLUMN Bの値がかぶらないようにチェックしないといけません。
COLUMN Bがかぶらない行だけを変える方法、あるいはCOLUMN Bがかぶる行を削除する方法を
教えてください。
279NAME IS NULL:2009/04/16(木) 13:45:19 ID:???
testテーブル
aid|bid|value|ip|created

このようなテーブルから、
ipが同じ、かつ同じcreatedが同じ日付のものを重複として取り除き、
valueの平均を出したいのですが・・・

サブクエリを使えば、

SELECT bid, avg( value )
FROM (

SELECT *
FROM test
GROUP BY bid, ip, date( created )
) AS tmp
GROUP BY bid

のようにできるのですが、
サブクエリを使わずに実現する方法はありますでしょうか?

よろしくお願いします。
280NAME IS NULL:2009/04/16(木) 14:10:38 ID:???
そのサブクエリ自体が間違っているような・・・
ipと日付が同じでvalueが異なる行があった場合は
どうするのだろうか。
281NAME IS NULL:2009/04/16(木) 14:19:44 ID:???
>>279
select ip, date(created), avg(value) from test group by ip, date(created)
これで事足りるんじゃないの?
282279:2009/04/16(木) 14:21:22 ID:???
>>280
説明が足りずすみません・・・
同じipで同じ日付ならば、時間が早いほうのvalueを使うほうにしたかったのですが・・・

SELECT bid, avg( value )
FROM (

SELECT *
FROM test
GROUP BY bid, ip, date( created )

ORDER BY created ASC

) AS tmp
GROUP BY bid

こんなかんじでしょうかね・・・

いろいろ間違ってるかもしれません;
283279:2009/04/16(木) 14:24:53 ID:???
>>281
またまた説明が足りませんでした・・・
同じipで同じ日付を重複として取り除いたものから、
valueの平均をbidごとに集計したかったのです・・・
284NAME IS NULL:2009/04/16(木) 14:51:18 ID:???
とりあえずそのサブクエリは文法エラーで評価出来ないと
言うことは意識しているかな。GROUP BYを使った場合は
無頓着に*は使えないよ。

あと「時間が早いほう」とは書いているけど、全く同時刻に
複数のvalueがある場合はどうなるのだろう。

最後に、やっぱりサブクエリ使わないと難しいと思う。
使えない理由がDBMSの仕様であるなら、DBMSの名前と
バージョンを書くべし。
285NAME IS NULL:2009/04/16(木) 20:02:54 ID:???
サブクエリ使えないなら一時テーブル使えば?
286NAME IS NULL:2009/04/16(木) 21:02:09 ID:???
達人の俺(まいど脳内DBの俺)が教えてやろう

>278
そーゆうとき、まずUPDATEするまえにDECODE関数を使って'a1'を'a2'に変えた表を作る
その表と元の無編集の表をキーで付き合わせればいいんだよ。
ポイントはdecode、not exists、from句に元の無編集の表と編集した表だ。
最終的にはDML一発でやりたい事ができるぞ。少なくとも俺の脳内では。
287NAME IS NULL:2009/04/16(木) 21:07:33 ID:???
>279
達人の俺がパッと見た感じではごく普通の難易度に見えるが
俺の脳内DBは3列10行までしか格納できないのでパス。
288NAME IS NULL:2009/04/16(木) 21:11:01 ID:???
aid|bid|value|ip|created

bid|ip|created

なら教えてあげてもいい。
289NAME IS NULL:2009/04/16(木) 21:22:17 ID:???
達人の脳内 DB はヒープどれくらい割り当ててるんですか?
290NAME IS NULL:2009/04/16(木) 21:35:05 ID:???
俺っくらいの達人になると

ひーぷ()笑

だ。決してヒープという用語を知らないわけではないぞ。
291NAME IS NULL:2009/04/17(金) 01:43:03 ID:???
良く解りませんがヒップへのアクセス権はguest可です
292278:2009/04/17(金) 02:44:23 ID:???
達人様ありがとうございました。
decodeが使えなかったのでcaseを使って実現しました。
結局様々な事情で実装は別の方法を取ったのですが
勉強になりました。
293NAME IS NULL:2009/04/17(金) 03:29:36 ID:???
公開したらヒップに SQL Injection 喰らいました。
294NAME IS NULL:2009/04/17(金) 03:43:47 ID:???
アクセス権はつけてるけどINSERT権限はつけてないから無問題
295DBの達人:2009/04/17(金) 05:56:38 ID:???
おはよう!
296NAME IS NULL:2009/04/17(金) 08:26:10 ID:uJNeHSTZ
DBからデータを取り出すときに、
今週のものだけを取り出すにはどのようにすればよいのでしょうか?
7日以内ではなく、「今週」のものなのですが。

プログラムなどで、今週の始めと終わりの日付などを計算する必要があるのでしょうか?
SQLで可能ならば教えてください。

また、カラムに更新日時が記録されているとき、
たとえば3日以上j更新されていないものを取り出すにはどのようにすればよいのでしょうか?

初歩的なことかもしれませんが、どうかお願いします。
297NAME IS NULL:2009/04/17(金) 10:01:39 ID:???
>>296
今週の日曜日から土曜日で、
WHERE date_column
BETWEEN CAST(NOW()-CAST(EXTRACT(DOW FROM NOW())||' day' AS INTERVAL) AS DATE)
AND CAST(NOW()-CAST(EXTRACT(DOW FROM NOW())-6 || ' day' AS INTERVAL) AS DATE)
298297:2009/04/17(金) 10:07:54 ID:???
見逃してた。下の質問だけど、更新日時が今日より3日以内って意味かな?
WHERE date_column BETWEEN CAST(NOW()-INTERVAL'3 days' AS DATE) AND CAST(NOW() AS DATE);
299297:2009/04/17(金) 10:28:50 ID:???
逆か>>298
WHERE date_column NOT BETWEEN CAST(NOW()-INTERVAL'3 days' AS DATE) AND CAST(NOW() AS DATE);
300296:2009/04/17(金) 15:48:09 ID:???
>>297-299

ありがとうございます!
試してみます。
301NAME IS NULL:2009/04/17(金) 19:44:40 ID:???
普通date_truncとか類似の関数で週単位の切り捨てもできるだろ
302達人:2009/04/17(金) 23:06:00 ID:???
俺が出るまでもないな。
303NAME IS NULL:2009/04/18(土) 02:23:43 ID:???
いまだに達人と聞くと、シューティングを思い出してしまう
304NAME IS NULL:2009/04/18(土) 03:15:53 ID:AF1CyfHl
社員(名前 char(32),社員番号 int primary key)
個人情報(社員番号 int primary key,年齢 int,支店番号 int)
という2つのテーブルがあるとき、制約条件として
foreign key 社員番号 references 社員
というのを個人情報テーブルに追加した方がいいですか、それとも
foreign key 社員番号 references 個人情報
というのを社員テーブルに追加した方がいいですか?
305NAME IS NULL:2009/04/18(土) 05:34:25 ID:???
社員番号がkeyなので社員テーブルを参照するのがいい。
つまり前者の制約でいいと思う。
でも、支店番号は社員テーブルにあったほうが良くないか?
306NAME IS NULL:2009/04/18(土) 05:47:55 ID:???
一つのファクトは同じテーブルに収めろよ
307NAME IS NULL:2009/04/18(土) 06:17:36 ID:???
>>304
そのテーブルの関係が1-0か0-1かによって決まる。
どっちかわかっていないなら付けられない。
308NAME IS NULL:2009/04/18(土) 20:02:40 ID:???
1つのテーブルに纏めるべきだとは思うけど、
参照制限をかけたいがためにわざと別テーブルにしてる・・・とかか?
309NAME IS NULL:2009/04/18(土) 22:14:51 ID:???
オッス達人だ。

>304
ある社員の

@名前はあるが、、年齢と支店番号がない。
A年齢と支店番号はあるが、名前がない。

どっちがイイのよ?
310NAME IS NULL:2009/04/18(土) 22:35:53 ID:???
なんか変なのが居ついちゃったな
311NAME IS NULL:2009/04/19(日) 02:00:42 ID:???
つか、それSQLの話じゃないし、設計の話はスレ違いだ
312NAME IS NULL:2009/04/19(日) 05:12:30 ID:gQJBptjI
テーブルのカラム名でDATE(もちろん意味は日付です)というのを使いたいんですが、DATEというデータ型とかぶってしまいます。
プロの皆さん方は、日付という意味のカラム名はどうされてますか?
313NAME IS NULL:2009/04/19(日) 05:38:03 ID:???
前になんか付ける。更新日ならUPD_DATEとか。
つかそれもこのスレじゃないな。
314NAME IS NULL:2009/04/19(日) 05:53:22 ID:gQJBptjI
ついでに後1個だけ。
カラム名は、大文字も小文字も区別されないと思っておいたほうがいいですよね?
315NAME IS NULL:2009/04/19(日) 19:59:55 ID:???
dbmsによる
316NAME IS NULL:2009/04/20(月) 00:55:55 ID:???
>>314
大文字か小文字だけを使うように設計するべき。
317NAME IS NULL:2009/04/20(月) 01:41:21 ID:???
Oracleなら全部大文字、MySQLやPostgreSQLは小文字って感じの規約が多いかな。
一応理由があって、Oracleは内部の情報としてカラム名やテーブル名を
大文字で管理してるから、大文字で最初から書いた方が効率が良くて、
逆にMySQLとかPostgreSQLは小文字で管理してるから逆になる。
ただどっちにしろSELECTとかINSERTみたいなコマンド部分は
大文字で書くのが一般的。
ただ、厳密な意味で大文字小文字を区別するってDBMSはあんまり無いと思う。
318NAME IS NULL:2009/04/20(月) 03:55:46 ID:???
今日(日付的には昨日)あった基本情報の問題についてですが
問3の設問4(SQL)が「ア」じゃダメな理由がわかりません
SQLの問題なのでここで聞いてみました

問題冊子:http://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2009h21_1/2009h21h_fe_pm_qs.pdf
解答:http://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2009h21_1/2009h21h_fe_pm_ans.pdf
319NAME IS NULL:2009/04/20(月) 04:46:24 ID:???
アだとジャガイモが在庫切れで非表示にしたい料理の他に
ジャガイモを元々使わない料理も出てこなくなる
320NAME IS NULL:2009/04/20(月) 05:55:14 ID:???
技術系の質問スレって「そんなDB使う奴がバカ」「そんなテーブル設計する奴がバカ」
みたいな、何の解決にもならない根本否定するだけのスレをよく見掛けるけど、ここは
それがあまりない。おまいら「DB屋は今そこにあるDBを何とかしなきゃいけない」って
よく分かってるプロだなーといつも感心する。
321NAME IS NULL:2009/04/20(月) 06:08:56 ID:???
ひんと: スルー力
322318:2009/04/20(月) 10:47:49 ID:???
問題文3行目の「使用する食材全てについて在庫が〜」というのを見逃してました。
しっかり問題文を読まねば・・・・・・
解説ありがとうございました。
323NAME IS NULL:2009/04/20(月) 10:53:59 ID:???
>>317
""でくくると大文字小文字を区別するけど、くくらないとすべて小文字扱いになるよ、PostgreSQLは
他のは知らないけど、似たようなもんじゃないのかなあ。
324NAME IS NULL:2009/04/20(月) 12:46:39 ID:???
>>321
何度見ても「するーか」と読んでしまう私のSELECT文
325NAME IS NULL:2009/04/20(月) 13:43:10 ID:???
ユンカース
326NAME IS NULL:2009/04/20(月) 18:26:07 ID:???
スツーカ
327NAME IS NULL:2009/04/20(月) 18:31:38 ID:???
暴力二男
328NAME IS NULL:2009/04/20(月) 20:44:32 ID:???
達人だ。

>312
「HIZUKE」または「HIDUKE」でOK。
ダサくても大規模プロジェクトでこんな名称使ってるとこたまにある
「〜_DATE」でOK。

よくあるのが
「INS_DT」「INP_DT」
「DEL_DT」
「UPD_DT」
運用日付なら「UNYO_HIZUKE」でオッケー牧場。
329NAME IS NULL:2009/04/20(月) 21:58:19 ID:???
意味の無い返答はやめていただきたい。
330NAME IS NULL:2009/04/21(火) 02:38:25 ID:6SQGommS
MySQLを使っているのですが、
ifnullとcaseの違いについてわからないことがあります。

以下のようなSQLファイルを作成しました。
-------------------------------------
~$ cat hoge.sql
use test;
drop table if exists hoge;
create table hoge (id int, no int, data text, primary key(id, no));
insert into hoge values(1, 1, 'aaa');
insert into hoge values(1, 2, 'aaa');
insert into hoge values(1, 3, 'aaa');
insert into hoge values(2, 1, 'bbb');
insert into hoge values(2, 2, 'bbb');
select ifnull(max(no)+1, 0) as no from hoge where id=3;
select (case when no is NUll then 0 else max(no)+1 end) as no from hoge where id=3;
-------------------------------------

これを実行してみたところ、以下のようになりました。
-------------------------------------
~$ cat hoge.sql | mysql -u root --table
+----+
| no |
+----+
| 0 |
+----+
+------+
| no |
+------+
| NULL |
+------+
-------------------------------------
なぜ、ifnullの場合は0なのに、caseの場合はNULLなのでしょうか?

よろしくご教示お願い致します。
331NAME IS NULL:2009/04/21(火) 02:46:51 ID:???
332NAME IS NULL:2009/04/21(火) 02:51:13 ID:???
いや単に前者がnull+1でnullになってるからだろ
333>>330:2009/04/21(火) 03:39:55 ID:6SQGommS
>>331
>.332
本当にありがとうございました。
334sql:2009/04/21(火) 05:28:21 ID:???
select distinct col1, col2, col3 from tablename;
とやると全行表示されるがこの件数だけを取得したい場合は一体どうかけばいいですか?
335NAME IS NULL:2009/04/21(火) 05:39:28 ID:???
標準ではないが DB によっては limit 20 とか fetch first 20 rows only とか
追加で書けたりする。DB の SQL リファレンス参照。
336NAME IS NULL:2009/04/21(火) 06:12:41 ID:???
select count(*) from tablename group by col1, col2, col3;
じゃないの?
337336:2009/04/21(火) 06:20:06 ID:???
寝ぼけてるな俺・・・
select count(*) from (select distinct col1, col2, col3 from tablename);
338NAME IS NULL:2009/04/21(火) 06:33:26 ID:???
あ欲しいのは件数か。「この件数」→「特定の件数」と勝手に脳内補完してしまった、失礼。
339sql:2009/04/21(火) 06:43:13 ID:???
>>337
oracleでは動くのですが、MySQLでは動作しません。なんか違うんでしょうか?
ERROR 1248 (42000): Every derived table must have its own alias
340NAME IS NULL:2009/04/21(火) 07:08:01 ID:???
>>339
エラーメッセージの通りじゃないの?(知らんけど。)
select count(*) from (select distinct col1, col2, col3 from tablename) a;
341sql:2009/04/21(火) 07:32:37 ID:???
>>340
出来たー!!有り難うございました
342NAME IS NULL:2009/04/21(火) 12:35:25 ID:???
MySQLには「SELECTしたものを、n件まで表示する」というのがあって便利だった。
343NAME IS NULL:2009/04/21(火) 12:52:45 ID:???
何でもう過去形なんだよw
344NAME IS NULL:2009/04/21(火) 14:07:14 ID:???
それ SELECT TOP n とはどう違うの?
345NAME IS NULL:2009/04/21(火) 14:10:13 ID:???
limit x となら完全に同じ。
さらに、limit x, y で開始行まで指定することもできて便利・・・だった
346NAME IS NULL:2009/04/21(火) 19:08:36 ID:???
>>343
商用でMySQLという案件が無かったから。
自宅で試す程度で、あまり自信が無くてね。
347NAME IS NULL:2009/04/21(火) 20:36:56 ID:???
>>343
そりゃ、ORACLEさんに買われて、お先真っ暗ですから
348NAME IS NULL:2009/04/21(火) 20:39:16 ID:???
>>346
> 商用でMySQLという案件が無かったから。

OracleのSun買収でこのあたりどうなるかね?
共にSQLを拡張して互換性を取るような動きになると、ありがたいんだけども。
349NAME IS NULL:2009/04/21(火) 21:23:55 ID:???
IBM「ちょwwwwwwwwおまwwwwwwwSQL作ったの俺たちのとこの博士だしw」
350NAME IS NULL:2009/04/21(火) 21:26:34 ID:???
>>342
逆にそれできないDBMSって何?
351NAME IS NULL:2009/04/21(火) 21:28:21 ID:???
>>350
Derby
352達人:2009/04/21(火) 21:47:59 ID:???
グルーピングは体で覚えるんだ
ロールアップまで使いこなせるようになるとGood
お偉いさん達は集計、小計、合計、率、比率、が気になってしょうがない生き物だから
353NAME IS NULL:2009/04/22(水) 07:05:44 ID:???
>>352
特に前年比がね〜
めんどうなんだよ!
頭の体操になるけどね
354NAME IS NULL:2009/04/22(水) 07:28:21 ID:???
orderみたいに、
そのままカラム名に指定するとエラーになってしまうカラム名を知りたいのですが、
どこかまとめてあるところご存じないでしょうか?

ここで質問していいんでしょうかね;
355NAME IS NULL:2009/04/22(水) 07:31:56 ID:???
マニュアルどぞー
356NAME IS NULL:2009/04/22(水) 07:36:49 ID:???
>>354
なんとなくわからないけ?
select *,order,where,select,group ,top,3 from from where where = order order by by
みたいな事できたらキモイでしょ
357354:2009/04/22(水) 07:39:40 ID:???
>>355
すみません・・・
マニュアルのどこらへんに書いてあるんでしょうか?

>>356
orderとかselectはまだわかるのですが、
keyとかでもエラーになったので・・・
ちなみにMySQLです。
358NAME IS NULL:2009/04/22(水) 08:21:23 ID:???
>>354
「SQL 予約語」でググる。
359NAME IS NULL:2009/04/22(水) 11:52:01 ID:???
>>357
どこに書いてあるかも聞かないと分からないとは・・・・(驚愕)
360NAME IS NULL:2009/04/22(水) 12:36:03 ID:???
自分が聞きたいことが何なのかが分からないことはよくある。
361NAME IS NULL:2009/04/22(水) 12:44:10 ID:???
予約語、という言葉を知らないと探しにくいかもなあ
362NAME IS NULL:2009/04/22(水) 17:33:23 ID:???
そんなことより僕と踊りませんか
363NAME IS NULL:2009/04/22(水) 19:53:06 ID:???
予約語でも”で括ると使えちゃったりするかも
364NAME IS NULL:2009/04/22(水) 20:54:11 ID:???
``じゃなくてか
365NAME IS NULL:2009/04/22(水) 21:20:42 ID:???
(''ω'')ふひひ さーせん
366NAME IS NULL:2009/04/22(水) 22:45:19 ID:???
いいから舐めろ
367NAME IS NULL:2009/04/23(木) 07:11:30 ID:???
どのていど消費されるかわからない主キー(オートインクリメント)のデータ型を
とりあえず全部BIGINTにしておくというのは、
なにかデメリットはありますか?

ほかにもLONGTEXTなども、多めに取っておくと何か不都合があるのでしょうか?
368NAME IS NULL:2009/04/23(木) 08:24:59 ID:???
>>367
MySQLだよね?
BIGINTのデメリットは消費データ量が4bytesから8bytesになること
LONGTEXTはMEDUIMTEXTにくらべてカラムヘッダが2bytesから4bytesになる

まあ2bytesとか4bytesをケチケチしなくていいと思う
369NAME IS NULL:2009/04/23(木) 12:06:21 ID:???
こういうのってできる?

○ テーブル1

1 aaa

○ テーブル2
aaa bbb
aaa ccc

○ テーブル3
bbb xxx
bbb yyy
bbb zzz
ccc kkk

○ 結果

1 aaa bbb xxx
- --- --- yyy
- --- --- zzz
- --- ccc kkk
370NAME IS NULL:2009/04/23(木) 12:21:51 ID:???
>>369
joinの左外部結合(右外部結合)

該当する行にはデータが、該当しない行にはNULLが入る。
「---」というデータが作りたいなら、置換してください。
371369:2009/04/23(木) 12:50:14 ID:???
>370
--- はNULLの意味です。
LEFT OUTER JOINだと、

1 aaa bbb xxx
1 aaa bbb yyy
1 aaa bbb zzz
1 aaa ccc kkk

になりませんか?
重複している行をNULLなどにできないのでしょうか?
372NAME IS NULL:2009/04/23(木) 12:57:13 ID:???
- --- --- yyyだけ見ると1 a bbb yyyなのか1 a ccc yyyなのか
わからないからねぇ。
>>369の結果テーブルは順序を持っている事になるから、結構
難しいと思う。
373NAME IS NULL:2009/04/23(木) 15:32:34 ID:???
うーんお手上げです。
1回限りのデータなら、Excel使って手でデータ作った方が早いと思います。
374NAME IS NULL:2009/04/23(木) 16:16:38 ID:???
>>369
問題を単純化するために、

1 aaa
1 bbb
2 ccc
2 ddd
2 eee

のテーブルを

1 aaa
- bbb
2 ccc
- ddd
- eee

と表示する方法から考えてみたら?
SQLでできないこともないだろうけど、俺ならホストアプリ側で制御かな。
ホストアプリのメモリで扱いきれないデータ量なら、表示用の別テーブルを作成する。
375NAME IS NULL:2009/04/23(木) 20:32:18 ID:???
>369

達人の出番だなw
376NAME IS NULL:2009/04/23(木) 21:15:37 ID:???
>>369
row_number()が使えるなら
1じゃなかったらnull、的な感じでいけると思う
377NAME IS NULL:2009/04/23(木) 21:20:22 ID:???
row_numberでできるけどSQLでやることじゃないよなw
378NAME IS NULL:2009/04/23(木) 21:22:03 ID:???
確かにw
やりたきゃ取得した側でやれって話だな
379達人:2009/04/23(木) 21:46:19 ID:???
まいど、達人だ。
俺の出番か、まかせとけ

@.外部結合で表示(>>371の表ね)、ソートし、各行に一意なID(オートナンバーとかROWNUMでいい)をふる。
結果は以下(列名を左から順に"ア","イ","ウ","エ","オ"とすし、このレコードセットを"ViewA"と名づけよう)

ア イ ウ エ オ
1 aaa bbb xxx 1
1 aaa bbb yyy 2
1 aaa bbb zzz 3
1 aaa ccc kkk 4


A.ひとつ前の行と比較して表示するか判定する。具体的には以下。

SELECT
DECODE(ZZZ.ア,(SELECT ViewA.ア FROM ViewA WHERE ViewA.オ-1=ZZZ.オ),NULL,ZZZ.ア) AS ア
,DECODE(ZZZ.イ,(SELECT ViewA.イ FROM ViewA WHERE ViewA.オ-1=ZZZ.オ),NULL,ZZZ.イ) AS イ
,DECODE(ZZZ.ウ,(SELECT ViewA.ウ FROM ViewA WHERE ViewA.オ-1=ZZZ.オ),NULL,ZZZ.ウ) AS ウ
,DECODE(ZZZ.エ,(SELECT ViewA.エ FROM ViewA WHERE ViewA.オ-1=ZZZ.オ),NULL,ZZZ.エ) AS エ
FROM ViewA ZZZ
ORDER BY 1,2,3,4


脳内ではできたが、実際にSQLは叩いてないからミス構文エラーかもしれん
少なくともヒントにはなっただろw
380NAME IS NULL:2009/04/23(木) 21:55:27 ID:???
天才現る

select '1', 'aaa', 'bbb', 'xxx'
union all
select null,null,null,'yyy'
union all
select null,null,null,'zzz'
union all
select null,null,'ccc ','kkk '
;
381達人:2009/04/23(木) 22:01:35 ID:???
へのつっぱりは、いらんですよ!!

>380
おしい FROM DUAL
382NAME IS NULL:2009/04/23(木) 22:20:29 ID:???
Oracle厨房の心のよりどころDUALw
383NAME IS NULL:2009/04/23(木) 22:22:56 ID:???
買収されたから、MySQLもDUALが強要されるように改悪されるかもしれんな。
384NAME IS NULL:2009/04/23(木) 22:27:24 ID:???
SCOTT, TIGER が入る日も近いな。
385NAME IS NULL:2009/04/23(木) 22:36:56 ID:???
まぁ、別にいいんじゃない?困る人は少ないと思うし
386NAME IS NULL:2009/04/23(木) 22:51:26 ID:???
こうか。
(テーブル1を(a, b)、テーブル2を(b, c)、テーブル3を(c, d)とする)

select case when RN1 = 1 then a else null end,
    case when RN2 = 1 then b else null end,
    case when RN3 = 1 then c else null end,
    case when RN4 = 1 then d else null end
from (select a,
       b,
       c,
       d,
       row_number() over (partition by a order by a,b) as RN1,
       row_number() over (partition by a,b order by a,b,c) as RN2,
       row_number() over (partition by a,b,c order by a,b,c,d) as RN3,
       row_number() over (partition by a,b,c,d order by a,b,c,d) as RN4
   from テーブル1
      inner join
      テーブル2
      using (b)
      inner join
      テーブル3
      using (c)
   )
;
387達人:2009/04/23(木) 23:08:45 ID:???
>386
Good。センスいい。
388NAME IS NULL:2009/04/23(木) 23:17:54 ID:???
しかし、本当にSQLに向いてない仕様だなw
389NAME IS NULL:2009/04/23(木) 23:48:28 ID:???
達人の
”ひとつ前の行のレコードと比較する”
ってテクはSQLでやれる事の可能性が広がったわ
ってかホントにできんの?
390NAME IS NULL:2009/04/24(金) 00:17:55 ID:???
>>389
サブクエリに任意に連番を振ることが可能なら、可能だとは思う
思うが、今回の質問のようなものは俺ならやらない
グループインジケーションはクライアントアプリの仕事だ
ちゃんとしたレポートツールとかなら、そのぐらいの機能は大抵あるしな

しかし、SQLの規則では、order by はサブクエリには書けなかったと思った
なんで中間テーブルなりビューなりを用意しないとダメじゃないかな
まあ、このへんはDBMSによって変わってくるだろうな

partitionは使ったことない(というか使えるDBMS使ってないw)からよくわからん
391NAME IS NULL:2009/04/24(金) 00:28:05 ID:???
>>389
やりたい事がそれであればlag関数でスッキリ実現可能。

ただ>>369をSQLで実現しようとすべきでは無いってのは自分も同意
392NAME IS NULL:2009/04/24(金) 00:40:01 ID:???
まぁ、SQLでやらなきゃならない事情があったんだろ
いろんな事情があるからな。
アプリ改造したいがソースを紛失したとかw
んで、SQLだけは外出ししてあったから直せるはずだろ、とか

テーブルの中にSQLを格納してあってSQLでSQL文を取り出すシステムとかもあるんだぜ
(データディクショナリとかそーゆーのじゃないくて)
393NAME IS NULL:2009/04/24(金) 01:25:56 ID:???
mysqlを触ろうとしてるんですが、
DELETE FROM xxx WHERE aaa= bbb AND ccc = (SELECT MIN(ccc) FROM xxx WHERE aaa= bbb)
↑を実行したらエラーになりました。
ググったら「mysqlは副問い合わせが出来ない」って出てきたんですが
こういう場合、mysqlではどのようにやるのが常套手段なんでしょうか…
394NAME IS NULL:2009/04/24(金) 01:55:52 ID:???
副問い合わせの結果をwhileやforeaceで回せばいいのでは
395NAME IS NULL:2009/04/24(金) 02:02:51 ID:???
>>394
どもです…ほんとに簡易sqlって感じなんですねぇorz
396NAME IS NULL:2009/04/24(金) 04:04:15 ID:???
>>395
version5.xでサブクエリ周りに機能追加なかったけ?
397NAME IS NULL:2009/04/24(金) 13:04:25 ID:???
MySQL(InnoDB)をperl-DBIで使ってます。

複数テーブルにわたる更新の場合はオートコミットを切ってトランザクション下で処理するんですが、
これはテーブルロックがかかってる状態ですよね?
ほかのユーザーは該当テーブルについてリードはできるが更新はできない状態なんですよね?
しかし、トランザクション中でもテーブルに書き込みできてるんですが、これはテーブルロックじゃなくて、行ロックを勝手にしてくれてるって事で良いんでしょうか?
398NAME IS NULL:2009/04/24(金) 16:35:56 ID:???
InnoDBは行ロックだよ
399NAME IS NULL:2009/04/25(土) 06:30:53 ID:???
>>395 >>396
サブクエリのDELETEはversion4.1からサポートしてますよ。
400NAME IS NULL:2009/04/28(火) 02:18:37 ID:aHnBfSXl
株価データをDBに入れて保持してるんですが、今は1つの大きなテーブルに入れてます。
(trade_date DATE, stock_name int, market_type int, open double, close double)
これ1個のテーブルで3000万件くらいになってます。しかも最近データの増える速度がどんどん
速くなってきた。
なにをやるにも時間がかかるので、テーブルをわけてしまおうかと思っているのですが、
銘柄単位でテーブルを分けるとテーブルが5000個とかになるし、
日にちでテーブルを分けると10000個近くになります。
両方をやると、データの冗長性があまりにもひどい気がします。

銘柄ごとでも日にちごとでも検索しまくるのですが、こういう場合どういう
形のテーブルにしておくのがよいでしょうか?
401NAME IS NULL:2009/04/28(火) 03:03:27 ID:???
>>400
カラムの意味と関連するテーブルのスキーマも見ないとわからん
あとテーブル設計に関してはスレチじゃないか?
402401:2009/04/28(火) 03:05:34 ID:???
こっちで聞いたほうがいいと思う
http://pc11.2ch.net/test/read.cgi/db/1223458453
403NAME IS NULL:2009/04/28(火) 03:12:20 ID:aHnBfSXl
すいません、そっちで聞いてみます。
404NAME IS NULL:2009/05/09(土) 12:43:28 ID:JoxlLn6y
DELETE * FROM WHERE NAME LIKE "%ii%";
みたいなことをやりたいのですが、DELETEにはLIKEは使えないようなので、
ほかにやり方がないかと思っています。
どうかやり方がないか教えてください。
405NAME IS NULL:2009/05/09(土) 12:49:33 ID:???
使えるだろ・・・。どこの DB だよ?
406NAME IS NULL:2009/05/09(土) 15:20:12 ID:???
>DELETE * FROM WHERE NAME LIKE "%ii%";
そもそもSQL文が間違ってないか?
DELETE文は「DELETE FROM (テーブル名) WHERE (評価式)」だぞ
407NAME IS NULL:2009/05/09(土) 17:24:17 ID:???
DELETE * って DELETE id,nameとかできたら便利だなw
408NAME IS NULL:2009/05/09(土) 19:10:13 ID:???
*もいらなく無いっけ?
409NAME IS NULL:2009/05/10(日) 16:37:38 ID:???
DELETEする前に、まずSELECT文としてきちんと評価されているかを確認するのが鉄則。
DELETEしたくない行を消したことが何度あったことか_| ̄|○
410NAME IS NULL:2009/05/10(日) 16:39:31 ID:???
まあSELECTで表示させてから、SELECT * をDELETEに差し替えるわな
411NAME IS NULL:2009/05/10(日) 17:25:38 ID:???
updateにwhere付け忘れた

あああああああああああああ
412NAME IS NULL:2009/05/10(日) 17:28:19 ID:???
(*´Д`)⊃ROLLBACK
413NAME IS NULL:2009/05/10(日) 18:04:04 ID:???
AUTO_COMMIT がえし!
414NAME IS NULL:2009/05/11(月) 09:55:08 ID:???
AccessではDELETE文に*つける。
415NAME IS NULL:2009/05/11(月) 10:20:32 ID:???
SQL SERVERの共通テーブル式でノードを辿る再帰クエリーを作成しているのですが、
ルートがループしているところがあります。
ループしている部分のデータの重複を避けたいのですが方法はありますでしょうか?
UNIONやEXCEPTを使用しようと思ったのですがダメでした。
416NAME IS NULL:2009/05/11(月) 13:22:01 ID:???
Accessは削除クエリ作ると裏で勝手にDELETE *のSQL文が作られるけど
SQLを手打ちするなら*なしでも普通に通るよ。
417NAME IS NULL:2009/05/11(月) 20:10:07 ID:???
漠然とした質問で申し訳ないんですが、効率のよいSQLの書き方について勉強するためのよい本や資料はどのようなものがありますか。
たとえば、
select users.* from users, groups where users.group_id = groups.id and group.name = 'Admin';

select users.* from users inner join groups on users.group_id = groups.id where group.name = 'Admin'

select users.* from users where users.group_id in (select id from groups where name = 'Admin')
のどれがいちばん効率がいいのかということを、自分で実験して調べるのもいいですけど、先人の知恵を使って勉強したいです。
なにかお勧めの本などを紹介してください。
418NAME IS NULL:2009/05/11(月) 20:18:59 ID:???
あなたの言う効率とは?
419NAME IS NULL:2009/05/11(月) 20:43:39 ID:???
単純に実在するテーブルで時間計測してみるとかでいいんじゃない?
RDBMSごとの得意・不得意よりも、稼働しているDBの構成に大きく依存する。

しかも正解が他で通用するとも限らない。
420NAME IS NULL:2009/05/11(月) 21:01:36 ID:???
普遍的に通用するセオリーみたいなのってほとんどないからねぇ
どこでも通用するものだけに搾ったら本一冊も書けないんじゃない?
421NAME IS NULL:2009/05/11(月) 21:49:46 ID:???
>>417
他の人も言ってように、DBMSやその構成に依存するから、コレってものは知らないなぁ。
昔はどこかのサイトに「こう書け」って事例があったよ。
でも、今となってはほとんど通用しないのじゃないかな。
例えば>>417の3つめのクエリは遅いクエリの代表みたいなものだったけど、
今じゃどれも一緒。IN述語の処理そのものが速くなったというよりも、
1つ目もしくは2つ目に書き換えて実行している。と考えた方がいい。

一番参考になると思うのは、実行プランを出力させてみること。
実際の処理時間だけを比較してみるのではなくて、
クエリがどのような手順で実行されるのかをも確認する。
そのうちに、どう書けば効率のいいクエリになるのかわかるようになる。

結合(JOIN)するときはテーブルの行数が、少ない行数同士、片方が多い、両方多い等によっても
結合方法などの実行プランが変わるから、実データでいろいろやった方がいい。
422NAME IS NULL:2009/05/11(月) 23:14:39 ID:???
DB2では人間が書いたSQL文が、RDBMSで自動的にどう解釈されているかが分かるログがあるよ。
単なるJOINであっても、内部的に挙動が異なる事があるとか、意外と考えさせられた。

今の自分は、自動化できる部分は全部自動化でいいと思ってる。
423NAME IS NULL:2009/05/11(月) 23:36:15 ID:???
ってか統計とってチューニングしながら実装しろよ
424NAME IS NULL:2009/05/11(月) 23:40:28 ID:???
よろしく、メガドック
425417:2009/05/12(火) 00:24:43 ID:???
みなさん、いろいろありがとうございます。
結局、これといった資料はないというのが実情なんですね。

>>421
>例えば>>417の3つめのクエリは遅いクエリの代表みたいなものだったけど、
>今じゃどれも一緒。IN述語の処理そのものが速くなったというよりも、
>1つ目もしくは2つ目に書き換えて実行している。と考えた方がいい。

ほしかったのはまさにこういうことが載っている本です。
explain でいろいろ調べたりするする前に、こういった先人の知識をあらかじめ知っておいた方がいいだろうと思ったのですが。
残念です。
426NAME IS NULL:2009/05/12(火) 00:26:52 ID:???
そのへん知りたかったら
Oracleコンサル雇うしかないかもね
飯の種だからね
427NAME IS NULL:2009/05/12(火) 01:25:05 ID:???
>>417
かなり昔の本なら、プログラマのためのSQL って本があったんだが
いかんせん古い

最近でその系統なら、アート・オブ・SQL とかどうだ

というか、スレ違いだな、そういうスレなかったか?w
428NAME IS NULL:2009/05/12(火) 03:44:41 ID:???
>>417
最適化のノウハウの背後にある理屈を理解したいのであれば、英語
ず大丈夫ならRaghu Ramakrishnanの教科書がおすすめ。
オプティマイザも含めてデータベースに関わる理論を広く薄く網羅
した本なので、一冊持っておくとデータベースのある部分について
理屈を理解したくなった時にとっかかりとして大変便利なはずです。
429NAME IS NULL:2009/05/13(水) 07:18:50 ID:R4pv+GIi
最近SQLの勉強を始めた者です。
VIEWって何のためにあるのかわかりません。結局いくつかのテーブルから自分の見たいカラムを
取ってきてJOINしているだけ(だからSELECTで同じことができるんじゃないか)という感じがするのですが、
VIEWの存在意義って何ですか?どういうケースで使うべきでしょうか?
430NAME IS NULL:2009/05/13(水) 09:52:33 ID:???
俺的には、ワンクッションおけるってのが大きい。

Table A と B から View_C を作ってるとして、
アプリの方で、Select * From View_C としてるとする。

後で変更の必要があり、Table D と E から View_C を作ることに
なっても、アプリの変更はいらないから。
431NAME IS NULL:2009/05/13(水) 20:54:09 ID:???
VIEWしか見れないユーザーであっても、テーブルの特定の行をいくらでも見れる。
(UPDATEやINSERTは不可)

これが大きな利点であると思います。
432NAME IS NULL:2009/05/13(水) 21:12:28 ID:???
前スレより転載(VIEWの利点・欠点)

734 名前:NAME IS NULL [sage] 投稿日:2009/02/05(木) 21:55:47 ID:???
>>731
こんなもんかな?

利点:
・クエリが(一見)単純になる
・あらかじめパフォーマンスチューニングしたVIEWを定義することで
 あとから書くクエリではパフォーマンスを考慮しなくて良くなる(場合がある)
・行や列ごとにセキュリティかけたい場合に使えたりする

欠点:
・あとからロジックを追うのが面倒(な場合がある)
・あとからパフォーマンスチューニングするのが面倒(な場合がある)
433NAME IS NULL:2009/05/13(水) 21:22:02 ID:raTYNme4
質問させてください。
複合インデックスを作成する際のキーの順番って関係ありますか?
またその場合はカーディナリティの高い順にするべきでしょうか?

よろしくお願いします
434NAME IS NULL:2009/05/13(水) 21:40:28 ID:???
>>432
利点の上2つは労力全然減ってないように思うけど
VIEWのSQL考えるかソースに書くとき考えるかの違いだけであって
435NAME IS NULL:2009/05/13(水) 22:00:33 ID:???
>>433
カーディナリが高い順が一般的だが、
それがパフォーマンスに影響するかどうかはDBMSによるかな。
なかにはOrcaleのCompress索引のように第1キーのカーディナリが
極端に低い場合専用の索引があったりします。
436433:2009/05/13(水) 22:50:51 ID:raTYNme4
>>435
ありがとうございます。
もう1つよろしいですか?
order byで使用する項目も基本的にはカーディナリティ順で良いのでしょうか?
datetime型を想定しています。

すいません。書き忘れてました。
DBMS:MySQL5
です。
437NAME IS NULL:2009/05/13(水) 23:28:06 ID:R4pv+GIi
SELECT * FROM A,B WHERE 条件;

SELECT * FROM A INNER JOIN B ON 条件;
って同じですか?
438NAME IS NULL:2009/05/13(水) 23:29:57 ID:???
違います。
439NAME IS NULL:2009/05/13(水) 23:39:24 ID:R4pv+GIi
ありがとうございます。
どっちのクエリも、AとBの積を求めて、そこから条件を満たすレコードだけを
残すから同じ結果になりませんか?
440NAME IS NULL:2009/05/14(木) 20:25:28 ID:???
>>438
where条件で外部結合した場合、評価や結合順序で結果が変わるってのは聞いたことがあるんだが
内部結合でも同様のことが起こりえる?

結果の問題じゃなくて内部の動作の問題だっていうなら、
オプティマイザ次第な所があると思うんだ
441NAME IS NULL:2009/05/14(木) 21:13:41 ID:???
>>437の最初のSQLの「条件」と後のSQLの「条件」が同じなら
そもそも前者は結合してない
442NAME IS NULL:2009/05/14(木) 21:38:19 ID:???
「条件」は同じって前提でしょ?(A.ID=B.IDとかで。)
前者は結合してないってどういう意味???
443441:2009/05/14(木) 21:45:27 ID:???
ああ間違えた。忘れてくれ。
444NAME IS NULL:2009/05/14(木) 22:20:28 ID:???
結論: >>437は、「条件」が内部結合条件であるとき、
・結果は同じ
・実行速度は違うかもしれんし同じかもしれん(オプティマイザ次第)
445440:2009/05/14(木) 22:22:07 ID:???
>>441,443
条件式の内容が書かれてないから、必ずしも結合に関する条件を
書いてあるというわけじゃないかもしれないがな
>441は直積は結合じゃないって言いたかったんじゃないかと思ったが

前者は直積とったテーブルをフィルタしてる
後者は条件に従った結合をする段階でフィルタする
そういう意味で結合してない、じゃないのかな

ただ、実際はオプティマイズ入るから直積とったようなワークなんぞつくらんだろうし、
内部結合においては同じ条件式なら同じ結果になる気がするんだが...ならない例があるかな?
446NAME IS NULL:2009/05/14(木) 22:38:43 ID:???
初心者が読んだらいいようなサイトと本を教えてください。
447NAME IS NULL:2009/05/14(木) 22:40:51 ID:???
448NAME IS NULL:2009/05/14(木) 23:19:03 ID:???
>>438の反応は、
結果は同じでも、そもそもそこに書いてあるSQL文は「違います」
というネタ的回答だと流してたわ。
449NAME IS NULL:2009/05/15(金) 02:51:17 ID:???
SQL文が違うんだからDBMSによっては
実行プランが異なる可能性もあるし、
実行プランが同一でもその作成過程が異なる、とかの
厳密な意味での「違います」だととったな、俺は。
あと、質問の内容からすると初心者っぽいから、
「結果が同じだからって、短絡的に同じだと思うなよ」と諌めたかったんでは。
450NAME IS NULL:2009/05/15(金) 09:56:31 ID:8Je7scRL
sqlStr = "select * from t_member where member_id = ○○";
↓OR
telephone1 = ○○";

これが出来るSQLを教えて欲しいです。

451NAME IS NULL:2009/05/15(金) 11:00:39 ID:8Je7scRL
単純に
select * from t_member where member_id=○○ or telephone=○○;

でいいのかな??
452NAME IS NULL:2009/05/15(金) 12:34:47 ID:???
アプリ側の実装の問題では?
453NAME IS NULL:2009/05/15(金) 13:45:43 ID:???
アプリが何かで答えは変わるな
454NAME IS NULL:2009/05/15(金) 14:05:47 ID:8Je7scRL
javaでアプリを作っています。
DBはMYSQL5.0でnetbeansを使用してます。
455NAME IS NULL:2009/05/16(土) 13:46:01 ID:???
456NAME IS NULL:2009/05/18(月) 16:27:42 ID:???
((レンタルテーブル))
レンタルID PRIMARY KEY,
インベントリID FOREIGN KEY

((インベントリテーブル))
インベントリID PRIMARY KEY,
映画ID FOREIGN KEY

((映画テーブル))
映画ID PRIMARY KEY

上記のようにレンタルテーブルはインベントリテーブルを、インベントリテーブルは映画テーブルをリファレンスしている場合に、
最も人気のある(レンタル数の多い)映画名を抜き出したいです。どのようなサブクエリを書けばいいでしょうか?
457456:2009/05/18(月) 18:31:02 ID:???
すみません
上記の問題については出来ました。取り消します
458NAME IS NULL:2009/05/20(水) 11:27:51 ID:???
TSUTAYAの中の人だったら嫌だなw 
459NAME IS NULL:2009/05/20(水) 12:39:11 ID:???
実際ML見てるとこれ業務そのものじゃないかなぁって質問あるし
あながち無いとは言えん
460NAME IS NULL:2009/05/21(木) 01:19:22 ID:216X3HC3
左外結合 右外結合 ってそれぞれ何と読むんですか?
左外部結合、右外部結合のことみたいですが、買った教科書には上記のように記述されていました

もう1つ、左、右外結合はどのようなところで使うのでしょうか?
概要はわかったのですが、あまり使われないような気がします・・・

よろしくお願いします
461NAME IS NULL:2009/05/21(木) 01:22:27 ID:???
sage忘れました すみません
462NAME IS NULL:2009/05/21(木) 01:29:06 ID:???
ダメだゆるさん
463NAME IS NULL:2009/05/21(木) 01:37:14 ID:???
使いどころがわかりやすいよう、業務に即した例を挙げると、
勇者テーブル
・勇者ID
・勇者名

勇者が覚えた魔法テーブル
・勇者ID
・魔法名

というテーブルがあったとする。

「勇者名」と「それぞれの勇者が覚えている魔法の数」を知りたい場合、
内部結合だと勇者が魔法使いならいいが、勇者が戦士だった場合魔法を1つも覚えていない。
すると一覧には、戦士は名前自体出てこないことになる。

外部結合であれば、戦士であっても名前だけは出てくる。
464NAME IS NULL:2009/05/21(木) 01:38:21 ID:???
ありがちな業務だな。
465NAME IS NULL:2009/05/21(木) 01:42:06 ID:???
どんなシステムでもその2テーブルは外せないよな
466NAME IS NULL:2009/05/21(木) 02:18:54 ID:???
>>460
ひだりがいぶけつごう、みぎがいぶけつごう
467NAME IS NULL:2009/05/21(木) 19:16:46 ID:???
>>460
そんなしょうもない教科書は捨てて他のを買った方がいい
468NAME IS NULL:2009/05/21(木) 21:24:04 ID:???
ちょっと今1週間習ってて不安があるので質問です
oracleでSQLを勉強してるんですが
いまいち覚えられてない・・・

どれをやるにも見なきゃ出来ない。
今のレベルはこういう場合は確かこれとこれを使うんだよな・・・くらい。

シルバーの本を借りたんだがやったことではあるんだが応用?見たいな感じで
さっぱりすぎてへこんだ
469NAME IS NULL:2009/05/21(木) 23:12:24 ID:???
いろいろ遊んでればそのうちに覚える
470NAME IS NULL:2009/05/21(木) 23:22:25 ID:???
仕事でやってれば自然と覚えるよ。
471NAME IS NULL:2009/05/22(金) 02:03:38 ID:MrqDSeOc
PostgreSQL でプライマリキーで検索かけてるのに、インデックススキャンになりません。
現在 100万行チョイ入ってるテーブルで、こんなインデックスになってます。

Indexes:
"txxx_pkey" primary key, btree (xxx_id)

explain してみると以下の通りインデックスが使用されないようです。

# explain select * from txxx where xxx_id=100000;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on teditlog (cost=0.00..49310.86 rows=1 width=193)
Filter: (xxx_id = 100000)
(2 rows)

実際に select すると秒単位で時間がかかります。
インデックスを使用させるにはどうしたらよいでしょうか?
472471:2009/05/22(金) 02:11:25 ID:???
>>471 の explain 結果のテーブル名が生のまま出ていましたね。
teditlog は見なかったことにして、txxx と読み替えてください。

追加情報ですが、xxx_id は BIGINT で、おおむね連番のシーケンス番号が付いています(たまに歯抜けになります)。
で xxx_id は、他テーブルから外部参照されています。

といった感じですが、インデックスが使用されない原因になっていそうでしょうか。
473471:2009/05/22(金) 02:52:55 ID:???
すみません、自己解決です。
該当カラムが BIGINT なので、検索したい値も BIGINT にしなくてはいけないようです。
つまり、

# explain select * from teditlog where elid=cast(100000 as bigint);
QUERY PLAN
--------------------------------------------------------------------------------
Index Scan using txxx_pkey on txxx (cost=0.00..3.04 rows=2 width=192)
Index Cond: (xxx_id = 100000::bigint)
(2 rows)

ということらしいです。
単に 100000 と書いただけじゃ BIGINT とは扱ってもらえないんですね・・・
バージョンを確認したら PostgreSQL 7.4.7 なんですけど、新しいのだと改良されてたりするんでしょうか。

ところでこれにちなんだ追加質問ですが、列挙した値をまとめてキャストする方法ってあるでしょうか。
たとえば

select * from txxx where xxx_id in (10000, 20000, 30000)

なんてやる場合、(10000, 20000, 30000) の全部の値を BIGINT にキャストしたいです。
(CAST(10000 AS BIGINT), CAST(20000 AS BIGINT), CAST(30000 AS BIGINT)) みたいにしないといけないでしょうか。
474NAME IS NULL:2009/05/22(金) 04:08:54 ID:???
>>471
8系だと型が完全一致しなくてもインデックス使うみたいだよ
475NAME IS NULL:2009/05/22(金) 13:48:07 ID:BGl6oKa6
>>468
シルバーでSQLだと9i?
状況が許せば10gの方がいいと思うけど。
自分的には「現場で使うSQL」(だっけ?)がお勧め

最初うちは、考える+本を見るの繰り返しになるのは
しょうがないんじゃないかな
基礎体力つけないと、なかなか応用力はつかん気がする
476NAME IS NULL:2009/05/22(金) 21:47:45 ID:???
・MySQL 5.1.33です
userID | groupID
1 | 1
2 | 1
3 | 1
4 | 2
5 | 3
5 | 3

列の一部が userID | groupID となっています
groupIDに所属しているuserIDが1つのレコードを抜き出したいです。
上の表だと 4|2 のデータだけ抜き出せるでしょうか?
GROUP BYをうまく使うのかな?と思って試したのですが、思い通りの結果が出ませんでした。
477NAME IS NULL:2009/05/22(金) 22:06:20 ID:???
group by groupID
having count(userID) = 1
478NAME IS NULL:2009/05/22(金) 22:17:18 ID:???
ばっちりです!
userIDとgroupIDの両方をGROUP BYしていたので
COUNTでうまく数えられなかったようです。助かりました−
479NAME IS NULL:2009/05/23(土) 06:14:06 ID:???
MySQL 5.1.34を使ってます

key  data1  data2  data3
-----------------------
1        a       b        c
2        a       a        c
3        c       c        a
4        b       c        b

こういうテーブルから
data1、data2、data3のいずれかにaが入っているものを取り出したいです。
480NAME IS NULL:2009/05/23(土) 07:31:25 ID:???
where data1 = 'a' or data2 = 'a' or data3 = 'a'
481NAME IS NULL:2009/05/23(土) 08:38:40 ID:???
>>479
SELECT * FROM TableName WHERE 'a' IN (data1,data2,data3);
482NAME IS NULL:2009/05/23(土) 11:10:48 ID:???
例を出すなら、希望の検索結果(この場合keyの一覧)も書かないと伝わりにくいかもよ
483NAME IS NULL:2009/05/24(日) 01:15:19 ID:???
質問です

classA
|__Name
|__AAA
|__BBB

classB
|__BBB
|__Name
|__CCC
select * from classA naturaljoin classb;

を実行すると
Name BBB AAA CCC

で中身が出力されると思うのですが、解釈としては両方にある列名が先に出てきて、
そのとき先に出てくるのはnatural join の前に指定した表通りの順
一致してない列名はnatural join の前に指定した表、次に後に指定した表 で出力される

ということでよろしいのでしょうか?

お願いします
484NAME IS NULL:2009/05/24(日) 01:19:35 ID:???
順番気にするなら*使わないからわからん
485NAME IS NULL:2009/05/24(日) 01:47:43 ID:???
実装依存入ってくるんじゃないのかなぁ。

ともあれコマンドラインから手打ちする場合はともかく、
プログラムにクエリ埋め込むときは絶対に*使わないから
>>484と以下同文。
486NAME IS NULL:2009/05/24(日) 02:00:34 ID:???
>>483
SQLでは、テーブル定義の列の順番は基本的に意味を持たないってのが原則
必要な場合は列リストを書いて指定する

俺の持ってる本ではその順番で出力されるようなことは書いてあるが、
それが定義された動作なのか実装に依存するのかは不明
>>484が言うように、順番を指定したいなら*ではなく列リストを書くべき
487NAME IS NULL:2009/05/24(日) 02:01:20 ID:???
>>483に対する答えとしては同意だけど、

>>485
> プログラムにクエリ埋め込むときは絶対に*使わないから

なんで「絶対」? たいていの言語にはカラム名を配列などの添字で
扱えるから、場合によっちゃ * は十分ありだと思うけど。
488NAME IS NULL:2009/05/24(日) 02:07:30 ID:???
そうですかー わかりました
まぁたぶんということで思ったとおりの解釈にします

ところで、自分はMySQL5.0.67を使ってるのですが、
・完全外部結合(A full outer join B)
・和集合(A union join B)
・共通集合(A intersect B)
・差集合(A except B)

で構文エラーが出ます
サポートしてないということでいいのですかねー?
もし、MySQLの仕様がわかるようなページがあればURLお願いします
バージョンアップを考えたいと思います
489NAME IS NULL:2009/05/24(日) 02:22:07 ID:???
>>487
スキーマ変わるとカラム数が変わってくるしDISTINCTとか
使っていると行数も変わってくるので。
そういう部分を曖昧にする積極的な理由もないので、基本*は
使っていません。

>>488
基本ここから追いかけて。
http://dev.mysql.com/doc/refman/5.1/ja/select.html

あと目的がシステム開発じゃなくてSQLの勉強なのであれば
MySQLよりPostgreSQLの方が良いよ。
こっちの方がSQL標準により対応しているので。
490NAME IS NULL:2009/05/24(日) 02:34:45 ID:???
>>489
勉強用に使ってます
ポスグレですか 使ったことがないのでイマイチとっかかりにくいです^^;

わざわざURLありがとうございます 見てみます
491NAME IS NULL:2009/05/24(日) 04:13:00 ID:???
>>487
俺も場合によってはありだと思うが
とあるプロジェクトでselect * 禁止ってルールがあったことがあるな

スキーマの変更がSQLに影響を及ぼすのを避ける
項目数の増減によるパフォーマンス変化を避ける
が主な理由だった気がする

まあ、プログラマ的立場からいえば、プログラム作らす前にDB設計終えとけとw
492NAME IS NULL:2009/05/24(日) 09:26:16 ID:p08hoVjs
>>490
本とセットなら、SQL鯖かOracle+現場で使うSQLがいいと思う

PostgresベースのSQL勉強用の本、あまりいいのがない気がする
#MySQLも同じ・・・・
#単なるお勉強しました じゃなくてその後の業務でも使えそうな本ね
493NAME IS NULL:2009/05/24(日) 16:48:38 ID:???
最初にSQL鯖やOracleなんて覚えたら環境依存激しすぎて
ああOracleだったらできるのにこれだからフリーのRDBMSはと愚痴る人間になっちゃうぞ
494NAME IS NULL:2009/05/24(日) 16:56:26 ID:???
そんなん何で始めても一緒。本人の資質次第だよ。
Postgresとかで始めても、やっぱり「Oracleは環境依存が激しすぎて」なんて
愚痴るようになる人だっているわけだし。
495NAME IS NULL:2009/05/24(日) 17:14:34 ID:???
う〜ん、もめていますが、>>489で書いたのは
>あと目的がシステム開発じゃなくてSQLの勉強なのであれば

と限定した上で、

>MySQLよりPostgreSQLの方が良いよ。
>こっちの方がSQL標準により対応しているので。

と書いたのですが。最大公約数としての標準SQLを学ぶので
あればMySQLよりPostgresがベターと言うだけの話であって、
システム開発にまつわる個別の実装の方言の問題はとりあえず
保留、で良いのではないでしょうか。
(参考書の書き方の問題もありますが。実践なんちゃら系の本は
標準と方言をちゃんと区別してないことが多いですし)
496NAME IS NULL:2009/05/24(日) 17:26:53 ID:???
現場で使うSQLがそもそも標準SQLじゃなくてOracle/SQLServer依存なんだから駄目だろ
497NAME IS NULL:2009/05/24(日) 17:32:34 ID:???
いや、だから現場で使うとは誰も言っていないじゃないですか。
498NAME IS NULL:2009/05/24(日) 17:34:21 ID:???
どうでもいいスレ違いはやめにして、次の質問どうぞー
499NAME IS NULL:2009/05/24(日) 18:29:24 ID:p08hoVjs
8.4からCTEも使えるし、そう違うとは思えないんだが>管理系は別
細かい部分の差異の読み替えは、慣れだしね
どんな時にどうすればいいのか、の考え方の方が重要でしょ?
500NAME IS NULL:2009/05/24(日) 18:51:00 ID:???
>>497
"現場で使うSQL"っていう書籍名
501NAME IS NULL:2009/05/24(日) 22:05:42 ID:???
こういう場面で一度も話題に上らないDB2( ´・ω・)カワイソス
502NAME IS NULL:2009/05/24(日) 23:45:23 ID:???
Sybaseより見ないからなぁDB2
503NAME IS NULL:2009/05/24(日) 23:47:34 ID:???
次期バージョンでは、PL/SQL が使えるらしいぞ
504NAME IS NULL:2009/05/25(月) 00:05:18 ID:???
うん。IBM社内的にもv9.xからv10.xになればいいじゃん、という声があったほど大きく変わった。
なのに「v9.7」
505NAME IS NULL:2009/05/25(月) 01:18:03 ID:???
PL/SQL使うならOracleでいいじゃんみたいな
506NAME IS NULL:2009/05/25(月) 07:43:45 ID:+IuRrIp9
Oracleからの移行狙いなんだろうね
商用のpostgresにも、そういうのなかったっけ?

>>504
DLして試してみたいかも>後一ヶ月くらいか
Express9.5 CentOS に入れて放置だわw
507NAME IS NULL:2009/05/25(月) 07:48:40 ID:???
ミドルウエアやERPがDB2に対応してくれないとそんなに移行しないだろ
PL/SQLさえ動けばいいわけじゃないんだし
508NAME IS NULL:2009/05/25(月) 12:50:32 ID:???
また皆さん痛いところをつく(ノД`)
509NAME IS NULL:2009/05/25(月) 13:09:28 ID:+IuRrIp9
その通りなのだが、試してみたくね?
SQL鯖メインだから、かんけーねーといえばそれまでなんだが
現行ではまず使うことないんだけど>DB2
510NAME IS NULL:2009/05/25(月) 19:42:08 ID:???
distinctで、かぶり無しで抽出したレコードを空白やカンマ区切りで結合するのは、
どのようにコードをかけばいいでしょうか?


SELECT disctinct(種類) FROM 商品リスト

レコードは
1 バナナ 果物
2 キャベツ 野菜
3 リンゴ 果物
4 イチゴ 果物
5 ニンジン 野菜

上では
果物
野菜

と2レコードで出るのですが、
果物 野菜

と1レコードで出したいです。
511NAME IS NULL:2009/05/25(月) 20:01:00 ID:???
SQLでは列の数が可変な問合せはできない
ストアド使えばできなくもないけど
アプリでやったほうがいいかと
512510:2009/05/25(月) 20:06:02 ID:???
>>511
すいません、
もしややこしいこと書いていればすいません。

上では
果物
野菜

と2レコード 1フィールドで出るのですが、
「果物 野菜」

と1レコード 1フィールドで出したいのです。

1レコード2フィールドではないのですが、
前者ならできますでしょうか?
513NAME IS NULL:2009/05/25(月) 21:12:46 ID:???
ごちゃごちゃ言っても回答は同じ
514510:2009/05/25(月) 21:21:43 ID:???
>>513
・・・orz
515NAME IS NULL:2009/05/26(火) 11:42:13 ID:???
煽りじゃなくて、少し入門書を読んだ方が良いね。
今のままじゃ、違和感ばかりたまって、いくらやっても向上しないよ。
516NAME IS NULL:2009/05/26(火) 20:37:27 ID:???
>>510
MySQLならGROUP_CONCAT
あとは知らん。
517NAME IS NULL:2009/05/30(土) 15:41:24 ID:???
昔Oracleでなんかの上位10個を検索して横に並べるってSQL見たことあるなぁ
どんなんしてたっけなぁ
やっぱプロシージャだったかな
518NAME IS NULL:2009/05/31(日) 10:03:59 ID:???
数固定ならSQLだけで何とかならんこともない
519NAME IS NULL:2009/05/31(日) 14:49:09 ID:???
LIMIT 1 OFFSET 0
LIMIT 1 OFFSET 1

いやなんでもない
520NAME IS NULL:2009/06/01(月) 00:06:43 ID:3TUTRBRK
初心者です。どうか教えてください。
visual studio 2005をADOを通してデータベースmdbを接続し
FPspreadへ表示できるようにしたいのですが全くわかりません。個人としては
dim cnn as adodb.connection
dim rs as adodb.recordset
'データベース接続したとする

ここからアクセスデータを取得したいのですが
SQL = "SELECT FROM * ;"
rs.open(SQL, cnn)
?????
ここからの文を作れずつまずいています。
SQL文からデータベースをスプレッドシートに表示するにはどういった構文に
すべきでしょうか?
521NAME IS NULL:2009/06/01(月) 00:13:36 ID:???
スレ違い
VB スレでも行け
522NAME IS NULL:2009/06/01(月) 00:15:27 ID:3TUTRBRK
わかりました。すみませんでした。
523NAME IS NULL:2009/06/01(月) 03:06:14 ID:???
SELECT FROM * ふいたwww
524NAME IS NULL:2009/06/01(月) 17:45:49 ID:???
525NAME IS NULL:2009/06/01(月) 19:00:30 ID:???
辞めちゃった人間の作ったJETデータベースエンジンのMDBを引き継がされて
テーブル名が*とかフィールド名がFROMとかSQLがSELECT [FROM] FROM [*]とかいう
ウンコDBを書き換える仕事はもうイヤだお・・・
526NAME IS NULL:2009/06/02(火) 06:28:03 ID:???
FROM SELECT *
527NAME IS NULL:2009/06/02(火) 21:07:07 ID:???
博士が泣いておられます
528NAME IS NULL:2009/06/02(火) 21:26:29 ID:???
select [where],[group by],count(where) from [from] where [order] is null
group by [group by] order by [null]
こういうのは?
529NAME IS NULL:2009/06/02(火) 23:15:09 ID:???
なんのナゾナゾだよw
530NAME IS NULL:2009/06/03(水) 22:21:44 ID:???
質問します。

【DBMS名】Oracle 10g
【バージョン】申し訳ありません。不明です。

【テーブルデータ】
ID | DATE     | DATA
--+----------+-----
1 | 2009-05-11 | aaa
2 | 2009-06-01 | bbb
3 | 2009-06-10 | ccc
4 | 2009-06-12 | ddd
5 | 2009-07-19 | eee

【説明と欲しい結果】
このようなテーブルから、下記のように

2 | 2009-06-01 | bbb
3 | 2009-06-10 | ccc
4 | 2009-06-12 | ddd

[DATE]が今月分のレコードのみを抽出するSQLの書き方を教えて下さい。
(システム日付は今日、2009/06/03とします)

よろしくお願いします。
531NAME IS NULL:2009/06/03(水) 22:29:29 ID:???
日付を yyyymm で取ってきて、200906 と同じかどうか。
あるいは、年が 2009、月が 6 のレコード。

日付操作関数を調べてね。
532NAME IS NULL:2009/06/03(水) 22:58:06 ID:???
普通に DATE > '2009-06-00'
又は DATA >= '2009-06-01'
でいいんじゃ?
533NAME IS NULL:2009/06/03(水) 23:02:21 ID:???
ヒント:trunc関数で月単位の切り捨てもできる
534530:2009/06/03(水) 23:56:43 ID:???
>>531
>>532
>>533
ご回答ありがとうございます。

Oracleが手元にないので、実際に試せないのですが、
システム日付を「yyyymm」で取得して、
その後、[DATE]が先ほど取得したyyyymmで始まるかどうか、
を抽出条件に入れることで対応したいと思います。

これで永眠できます。
535NAME IS NULL:2009/06/04(木) 18:40:31 ID:???
最近はじめたものなのですが
質問です。

SELECT*INTO 1○○ FROM 2○○
1を2に挿入するってことなのですか?
それとも2を1に挿入なのでしょうか?
いまいちわからないので教えてください。初歩的で申し訳ないです
536NAME IS NULL:2009/06/04(木) 20:04:55 ID:???
SELECT じゃなくて INSERT じゃねえの?
それともDBMS固有SQL?
537NAME IS NULL:2009/06/04(木) 21:09:22 ID:???
>>536
んー固有かどうかはわかないです。
他人の作ったACCESSのVBAコードだったんで・・・
538NAME IS NULL:2009/06/04(木) 21:17:57 ID:???
やってみればいいじゃん。
539NAME IS NULL:2009/06/04(木) 21:29:39 ID:???
SQL ServerとJetな。
INTO句で指定したテーブル名のテーブルがCREATEされるよ。
FROMがレコード抽出元テーブルの指定。
540NAME IS NULL:2009/06/04(木) 21:32:54 ID:???
え マジでこんな書き方許されるの?
541NAME IS NULL:2009/06/04(木) 21:39:28 ID:???
マイクロソフトだもん。
542NAME IS NULL:2009/06/04(木) 21:41:00 ID:???
SELECT INTO は PostgreSQLにもあるよ。
543NAME IS NULL:2009/06/04(木) 21:48:53 ID:???
用途は全く違うがSELECT INTO はoracleにもある
544NAME IS NULL:2009/06/04(木) 21:54:09 ID:???
Oracleのはいくらなんでも別物だろう。
545NAME IS NULL:2009/06/04(木) 21:57:34 ID:???
PostgreSQLはSELECT INTOよりもCREATE TABLE ASが推奨されてなかったっけ?
546NAME IS NULL:2009/06/04(木) 21:58:41 ID:???
Oracleで意味的に同じものは
CREATE TABLE AS SELECT
547NAME IS NULL:2009/06/04(木) 22:04:22 ID:???
548NAME IS NULL:2009/06/04(木) 22:23:13 ID:???
>>545
マニュアルにはそう書いてあるけど、>>539と使い方は一緒だね。
549NAME IS NULL:2009/06/05(金) 00:45:46 ID:???
どなたか教えてください。
テーブルに
ステータス、登録日、ID、…
といった情報をもつレコードがあるとき

IDでグルーピングして、複数のレコードが合ったときに
@ステータス 90>30>20 の優先順位で高いほうのレコードを抽出。
A同じステータスの場合は、登録日が昔のものを抽出

ということを一つのSQL文でやりたいのですが、やり方が全くわかりません
助けてください…
550NAME IS NULL:2009/06/05(金) 01:18:06 ID:???
order by field(ステータス, 90, 30, 20), 登録日
とかでいいんでなくて?
551NAME IS NULL:2009/06/05(金) 07:50:28 ID:???
おお、ステータスはこうやるのですか
ただ、これって、1レコードになるのでしょうか

ちょいと試してみます。出来なかったらまた伺います。。。
イッテキマス
552NAME IS NULL:2009/06/05(金) 17:25:22 ID:5dMjVb/r
SELECT name from X where name LIKE '%キーワード%'
→ 文字列「キーワード」を含むname「キーワード1」「重要キーワード」など
  が選べます。
逆に、文字列「キーワード」に含まれるnameを選ぶようなSQL文はありますか?
「素敵なSQL文」
→文字列「キーワード」に含まれるname「キー」「ワード」「ワー」などを選ぶ。

となるような「素敵なSQL文」です。よろしくお願いします。
553NAME IS NULL:2009/06/05(金) 17:37:02 ID:???
>>552
逆にすればいいんじゃね。

SELECT name FROM X WHERE 'キーワード' LIKE '%'||name||'%';
554552:2009/06/05(金) 18:13:38 ID:5dMjVb/r
ああああああああああああああああああ。
>>553
こんなことできたんですね。ありがとうございます。
(MySQLでは「||」はムリなのでしょうか。
'%'||name||'%'のかわりにconcat('%', name, '%')でイケました。)
555NAME IS NULL:2009/06/05(金) 21:04:27 ID:???
テーブル名をワイルドカード指定することは可能でしょうか?
例えば、A0,A1というテーブル名のテーブルがあった場合、
SELECT * FROM A*;
のように、テーブル名をワイルドカード指定して、A0,A1の内容を参照したいのですが。
556NAME IS NULL:2009/06/05(金) 21:21:22 ID:???
>>555
無理。
557NAME IS NULL:2009/06/05(金) 21:23:01 ID:???
出来たとしてどんな結果を期待してるんだろうな。
UNIONか?
558sage:2009/06/05(金) 21:28:43 ID:PrWmL95S
PRO*COBOL での プリコンパイラにて
「WHEN」の中に「式の記号」は書けない という旨のエラーがでます

CASE WHEN col_1 = 1
  THEN '○'
  WHEN col_1 = 2
  THEN '×'
  ELSE NULL
END

WHEN の中に 「=」 が プリコンパイラでエラーとなります

col_1 IN('1') としても、条件を逆にして
col_1 <> '1' としても
 「IN」、「<>」 が プリコンパイラでエラーとなります

実現したい条件は、 CASEが ネストで3階層あります

CASE when col_1 = ' '
 THEN
 CASE when col_2 = ' '
    THEN CASE when col_3 <> ' '
          THEN col_3 を比較条件のカラムにする
        END
    ELSE        col_2 を比較条件のカラムにする
 END
 ELSE     col_1 を比較条件のカラムにする
END col_x =:INP_ID

CASE WHEN を使わないで、上記の条件をどのように記述したらよいのでしょうか
559NAME IS NULL:2009/06/05(金) 21:29:42 ID:???
DB設計がとてつもなく汚い悪寒w
560NAME IS NULL:2009/06/05(金) 21:33:35 ID:???
スレ違いだな。COBOL スレでも行け。
561NAME IS NULL:2009/06/05(金) 21:34:49 ID:???
>>558
Pro*COBOLってことはOracleなんだろうから書けそうなもんだけど、
どうしても書けないなら
 where col_1 = なにか
 or (col_1 = ' ' and col_2 = なにか)
 or (col_1 = ' ' and col_2 = ' ' and col_3 = なにか)
とかするしかないんじゃね?
562NAME IS NULL:2009/06/05(金) 21:34:54 ID:???
PRO*COBOLは知らんけど
CASE col_1
WHEN 1 THEN
みたいに書けんの?
563NAME IS NULL:2009/06/05(金) 23:41:07 ID:???
>>558
まずはそのSQLがSQL*Plusとかで通るかどうか試すべき
564sage:2009/06/06(土) 14:08:20 ID:4vB1BD0o
>>559
DBリンクを使って、他業者のDBのテーブルを判断なので
確かにDB設計が汚いです @@;

>>561
ありがとうございます。その記述にして、やってみます

>>563
SQL*PLUSでは、実行でき、ちゃんと望みどおりの検索結果が返ってきます
565NAME IS NULL:2009/06/07(日) 03:52:32 ID:BvTw+nDU
HEXの形式で入っている文字列を普通の文字に変換したいのですが
  例) '31323334' →’1234’

どう書けばいいのでしょうか?DBはオラクル10gです

566NAME IS NULL:2009/06/07(日) 09:48:22 ID:H5yYzBMm
>>564
decode は?
567NAME IS NULL:2009/06/07(日) 11:48:09 ID:???
おしえてください。
ある整数の列があるとして、
昇順あるいは降順にソートしたものが
以下のようなデータだったとしてます。

1, 2, 3 , 10, 15, 60, 125, 524, 680

この結果の中において隣接する値と一番乖離している行番号を取得したいです。
どうすればいいでしょうか?

568NAME IS NULL:2009/06/07(日) 12:25:18 ID:???
>>567
「昇順時で次の値までが一番離れている」と受け取った。
LIMITクエリで手抜きだが。

SELECT num,(SELECT min(num) FROM Table AS T2 WHERE T1.num<T2.num)
FROM Table AS T1 ORDER BY 2 DESC NULLS LAST LIMIT 1;

NULLS LASTが使えないなら、2カラム目のサブクエリをCOALESCEで囲うか。
569NAME IS NULL:2009/06/07(日) 12:59:29 ID:???
>>567
select *
from (select T1.ColumnName,
       min(T2.ColumnName),
       min(T2.ColumnName) - T1.ColumnName,
       row_number() over (order by min(T2.ColumnName) - T1.ColumnName desc) as RN
   from TableName T1
      inner join
      TableName T2
      on T1.ColumnName < T2.ColumnName
   group by T1.ColumnName)
where RN = 1
;
差が同じところが2箇所以上あっても1つしか選択されないので注意
570NAME IS NULL:2009/06/07(日) 13:41:40 ID:???
date_sub()でのintervalの指定に
変数や別テーブルからselectした結果を使いたいのですが、

mysql> select @x:='interval ''6'' month';
+----------------------------+
| @x:='interval ''6'' month' |
+----------------------------+
| interval '6' month |
+----------------------------+
1 row in set (0.00 sec)

mysql> select date_sub('2009-4-30', @x);
ERROR 1064 (42000): You have an error in your SQL syntax

以上ではエラーになります。
クオート?かなにか必要なのでしょうか。

サーバはMySQL5.0を使っています。
お願いします。
571NAME IS NULL:2009/06/07(日) 14:07:44 ID:s0waBkcv
揚げ
572NAME IS NULL:2009/06/07(日) 14:27:47 ID:FbuXSqjn
567です。

>>568
>>569
お返事ありがとうございます。
MySQL5を使っているのですが、
例示していただいたコードではsyntax errorが出て
あれこれと考えていました。
autoincrement列を追加し、その値を取得することで対処しようと
思います。

SELECT id,(SELECT min(num) FROM test_table AS T2 WHERE T1.num<T2.num)-num as diff FROM test_table AS T1 order by diff desc;

ありがとうございました。
573NAME IS NULL:2009/06/07(日) 15:55:45 ID:???
>>565
昔やったときは文字単位でばらしてCHR()でがんばったなぁ。
なんでこんな基本的な機能がないんだろうって文句言いながら。
今ならあるのかな?
574NAME IS NULL:2009/06/07(日) 16:12:31 ID:???
>>567
はじめからDBいえよカス
575NAME IS NULL:2009/06/07(日) 18:30:30 ID:???
MySQL4.1.2(各文字コードはUTF-8)を使用し、形態素解析済みのカラムに対するFullText検索を試しているのですが、
SQLの書き方が悪いのか、結果が思うようにいきません。
検索ワードがひとつだとまずまずなのですが、ANDやOR・NOTといった複数語となると特に・・・

例として「赤ちゃん」「権力者」をAND検索する場合ですが、どう書けばいいのでしょうか。
試しているSQL文は以下のような感じです。※「権力者」は分かち書きされて「権力 者」となっています。

(例1※おそらく間違い)
SELECT * FROM some_table MATCH(some_column) AGAINST('+"赤ちゃん" +"権力 者" in boolean mode');

=>LIKE検索では結果は2件だが、131件ヒットする。
+や-記号が効いていないようで、上記「権力 者」の前の+を-に変えても結果は変わらない。
以下も同じで、LIKE検索に比べ数10件の誤差が出る(ワードにスペースが含まれない場合の例のつもり)
SELECT * FROM some_table MATCH(some_column) AGAINST('+赤ちゃん +権力 in boolean mode');

(例2※LIKE検索っぽい書き方をしてみた)
SELECT * FROM some_table MATCH(some_column) AGAINST('赤ちゃん') AND AGAINST('権力 者');

=>5件ヒットする。=>「赤ちゃん」しか含まない結果が3件ある&ググッてもこういう書き方をしてる例が見つからない
すみませんがお願いします。
576NAME IS NULL:2009/06/07(日) 18:43:23 ID:???
MATCHってWHERE句なくても動くんだ?
577575:2009/06/07(日) 18:53:06 ID:dWbdg2sE
>>576
申し訳ない、WHERE抜かしてました。正しくは
(例1)
SELECT * FROM some_table WHERE MATCH(some_column) AGAINST('+"赤ちゃん" +"権力 者" in boolean mode');
(例2)
SELECT * FROM some_table WHERE MATCH(some_column) AGAINST('赤ちゃん') AND AGAINST('権力 者');
578NAME IS NULL:2009/06/07(日) 19:07:37 ID:???
579NAME IS NULL:2009/06/07(日) 19:09:18 ID:???
'の位置を確認してみれ
580575:2009/06/07(日) 19:25:16 ID:dWbdg2sE
>>578-579
おしえていただいたページは両方とも参考にしていました。
しかし・・・'の位置orz

以下の文で正しい結果(LIKE検索と同じ2件取得)となりました。
SELECT * FROM some_table WHERE MATCH(some_column) AGAINST('+"赤ちゃん" +"権力 者"' in boolean mode');

ありがとうございました!
581580:2009/06/07(日) 19:27:03 ID:dWbdg2sE
くひっ。また間違えた・・・正しくは
SELECT * FROM some_table WHERE MATCH(some_column) AGAINST('+"赤ちゃん" +"権力 者"' in boolean mode);
です。
582NAME IS NULL:2009/06/07(日) 22:05:51 ID:???
まず落ち着こうよ。
読みやすい文章を書くのも大事なことです。
583NAME IS NULL:2009/06/10(水) 22:45:16 ID:zpAa6Yna
sqlserver 2000 を使っています。
varchar型の文字列に含まれる改行コードの数を出したいのですが、
何かいい方法はありませんか?
教えてください。
584NAME IS NULL:2009/06/10(水) 22:53:11 ID:???
動く環境無いんで想像だけど
replace(文字列,'\r\n','')

文字列
のlengthの差で出るかな。
585NAME IS NULL:2009/06/10(水) 23:09:04 ID:???
改行コード、数えて何したいかによるんじゃないのかな?

例えば、行数に応じて出力先の高さを可変にしたいとか
この場合、無理してSQLでやらずに、ホストのプログラムでやった方が楽だと思うよ

改行コードで分割して配列に詰め込むような関数を使う(自作する)とかね
586NAME IS NULL:2009/06/10(水) 23:31:44 ID:zpAa6Yna
>>584
select replace(len(文字列,char(10),'')) - len(文字列) from テーブル で
取得できました!
今日1日中考えていたのでちょっと感動です。
ぐっすり眠れます。
ありがとうございます。


>>585
まさにそうなんです。行数で高さを調節したかったんです。
明日改行数を取得する関数を作ってみようと思います。
SQLでなんとか出せないかと視野が狭くなっていました。

もっと柔軟に考えなきゃいけませんね。
ありがとうございました。
587585:2009/06/10(水) 23:35:59 ID:zpAa6Yna
くひっ。僕も間違えた・・・正しくは
select len(文字列) - replace(len(文字列,char(10),'')) from テーブル
です。
588NAME IS NULL:2009/06/11(木) 01:47:19 ID:???
>>587
落ち着けw
それでもおかしいだろ。
589NAME IS NULL:2009/06/11(木) 22:39:02 ID:/TZVY2cm
SQL Serverを使用しています。
例えばselect * from INFORMATION_SCHEMA.COLUMNS
のような内容をを特定の行だけ縦に表示するにはどう書いたらいいでしょうか?

colmun     data
--------------------
table_name   test
colmun_name   番号

みたいな感じです
590NAME IS NULL:2009/06/12(金) 19:48:45 ID:???
同じ行を何個もUNIONして…

AP側でどうにかしろ
591NAME IS NULL:2009/06/13(土) 07:40:51 ID:???
だいたいSQLに「表示」なんて概念は・・・・
592NAME IS NULL:2009/06/13(土) 14:52:14 ID:???
>>589
select * from INFORMATION_SCHEMAしてアプリ側で調整
593NAME IS NULL:2009/06/15(月) 18:15:08 ID:???
おはずかしいのですが REPLACE 文に付いて教えください。

ID DATA
--------
1 258.9
2 350.6
3 426.9
--------

ID 2 の行を置き換えようと

INSERT OR REPLACE INTO MYDB VALUES(2,330.8);

これだと2の行が置換でなく追加されてしまうので悩んでいます。
今は DELETE 文発行して、INSERT しています。
594NAME IS NULL:2009/06/15(月) 18:21:40 ID:???
where ID = 2 が要るだろ普通
595NAME IS NULL:2009/06/15(月) 18:34:52 ID:???
>>594
早速ありがとうございます。
VALUES() の後では文法エラーになってしまって(悩中)
WHERE 文の記述ヶ所教えていただけませんか?
596NAME IS NULL:2009/06/15(月) 18:56:42 ID:???
INSERT OR REPLACE も UPSERT(だったかな)もよくは知らないのだけど、
IDがプライマリーキーじゃないと拙いような気がする。
SQLは >>593のままでも通りそうだけど。
597NAME IS NULL:2009/06/15(月) 18:59:05 ID:???
INSERT OR REPLACEなんていう気持ち悪い構文はSQLiteか?
UPDATE文を使え
598NAME IS NULL:2009/06/15(月) 19:03:22 ID:???
>>596
あああ、PRIMARY KEY ・・
ありがとうございます。ID INTEGER PRIMARY KEY で置換しました。
599589:2009/06/16(火) 16:30:36 ID:???
遅くなったけどありがとう。
自前で処理することにします。
600NAME IS NULL:2009/06/17(水) 02:06:29 ID:tRvf1FDN

すみません、SQL初心者です。
下記のようにSQLを組んだのですが、「--エラー箇所」の場所で
「1つ以上の表が外部結合されています?」のようなエラーが発生してしまいます。
どのように修正したら良いか教えて下さい。

【やりたいこと】
CASE WHENで取得した、「A.コード1」または「A.コード2」に対応する「T.製品コード」が
ない場合でも、レコードを弾かず、T.製品名を空としてレコードを取得したい。

(+)を外すとエラーは発生しないのですが、対応するコードがないデータが
弾かれてしまいます。

【環境】
オラクル8i + ASP

---------------------------------------------------------------------------

SELECT
A.KEY1,
A.KEY2,
T.製品名
FROM
Aテーブル AS A,
Bテーブル AS B,
Cテーブル AS C,
Dテーブル AS D,
取引テーブル AS T
WHERE
A.KEY1=B.KEY1
AND A.KEY1=C.KEY1
AND A.KEY1=D.KEY1

AND A.KEY2=B.KEY2
AND A.KEY2=C.KEY2
AND A.KEY2=D.KEY2

AND A.KEY3=T.KEY3


--エラー箇所
AND T.製品コード(+)= CASE WHEN (C.条件コード判定='1' OR C.条件コード判定='2') AND D.フラグ='1'
THEN A.コード1
ELSE A.コード2
END

ORDER BY A.KEY1, A.KEY2, A.製品名

601NAME IS NULL:2009/06/17(水) 07:43:42 ID:???
AND A.KEY3=(+)T.KEY3
がいるんじゃなかろか
602NAME IS NULL:2009/06/17(水) 13:08:02 ID:???
AND CASE WHEN T.製品コード(+)= CASE WHEN (C.条件コード判定='1' OR C.条件コード判定='2') AND D.フラグ='1'
THEN A.コード1
ELSE A.コード2
END
THEN 1 ELSE 0 END = 1
603600:2009/06/17(水) 20:43:10 ID:???
>>601、602
返信が遅くなって申し訳ない。
今環境がなく試せないのですが
後日試してみます。ありがとうございます。助かります。
604NAME IS NULL:2009/06/20(土) 04:58:00 ID:???
クエリについて質問があります。
レス内容が長くなってしまいすみませんが、説明に分かり辛い部分がありましたら補足しますのでどうかよろしくお願いします。


【質問テンプレ】
・DBMS名とバージョン: SQLite 3
・テーブルデータ:長いため下記に記載
・欲しい結果:Mozilla Firefox 3.0.11のブックマークファイル(*.sqlite/SQLite 3)から特定の履歴(閲覧)を削除したいです。
・説明:長いため下記に記載


●テーブルデータ
==================================================================================================================
■moz_historyvisits
| id | from visit | place id | visit date | visit type | session |
------------------------------------------------------------------------------------------------------------------
■moz_places
| id | url | title | rev host | visit count | hidden | typed | favicon id | frecency |
==================================================================================================================


●欲しい結果と説明
 [moz_places]テーブルの[id]フィールドが、[moz_historyvisits]テーブルの[place id]フィールドと一致する場合に、
 [moz_places]テーブルのレコードを削除したいです。

 また、その際の追加条件として、[moz_places]テーブルの[url]フィールドに[http://www.test/]という文字列を含む場合は
 必ず削除、[http://www.example.com/*]または、[http://*.sqlite.localhost/*]という文字列を"含まない"場合も必ず削除、
 それ以外の場合は削除しないという条件を付け加えたいです。

 さらに、それと同時に上の条件で、[moz_places]テーブルからレコードを削除したら、[moz_historyvisits]テーブルの該当
 レコード(idとplace idを比較して一致した[moz_historyvisits]テーブルのレコード)も削除したいです。
 (>>80さんが言っているような事をしたいです。)


●自分で調べて書けた一部
DELETE FROM moz_places WHERE id IN (SELECT place_id FROM moz_historyvisits)
 AND (url LIKE 'http://www.test/%'
 OR (url NOT LIKE 'http://www.example.com/%' AND url NOT LIKE 'http://%.sqlite.localhost/%'))

 ※[moz_historyvisits]テーブルのレコードを同時に削除するという方法が分からないです。
 ・上のクエリは、長いので改行して投稿しました。
 ・一応実行できたのですが、添削していただければ幸いです。


●補足
 1.データベースファイル名は、[places.sqlite]です。
 2.[moz_historyvisits]テーブルの[place id]には、重複データが有ります。
 3.Windows XP Professional SP3 (32bit版)で、PupSQLite・TkSQLiteというソフトで操作しています。
 4.SQL(SQLite)については昨日あたりから調べ始めました。
   (プログラミング言語については、JavaScriptとVBSだけは、なんとか調べて基本的な事だけは若干理解できる程度です。)


以上、どうかよろしくお願いします。
605604:2009/06/20(土) 05:03:44 ID:???
連続で失礼します。
Firefox3のデータベースの事について載っているサイトです。

●places.sqlite テーブル情報等
 http://builder.japan.zdnet.com/sp/firefox-3-for-developer-2008/story/0,3800087566,20380782,00.htm
■moz_historyvisits フィールド情報等
 http://builder.japan.zdnet.com/sp/firefox-3-for-developer-2008/story/0,3800087566,20382307,00.htm
■moz_places フィールド情報等
 http://builder.japan.zdnet.com/sp/firefox-3-for-developer-2008/story/0,3800087566,20380856,00.htm

他にも質問に不備等があれば補足しますので、どうかよろしくお願いします。
606NAME IS NULL:2009/06/20(土) 08:52:26 ID:???
>>604
標準SQLでは複数テーブルからのDELETEはできない。
どうしてもやりたければ参照整合性制約やトリガーを使うけど
まあDELETE文2回でいいんじゃね?
607604:2009/06/21(日) 01:52:54 ID:???
>>606
レスありがとうございます。
できれば、そのトリガー(もしくは参照整合性制約)というものを使って同時に削除したいです。
よろしければ、>>604のクエリにトリガーという方法を加えたクエリを書いていただけますでしょうか?

下記のページを参考に調べているのですが、基本的な事しか理解できず複雑な式は分からず・・・。
net-newbie.com/sqlite/lang.html#createtrigger

お時間のある時で構いませんので、お手数ですが再度レスをいただけると助かります。
どうかよろしくお願いします。
608NAME IS NULL:2009/06/21(日) 02:15:17 ID:???
sqliteを使ったことがないけどこれでいけるかな

CREATE TRIGGER delete_history AFTER
DELETE ON moz_places
BEGEN
DELETE moz_historyvisits WHERE id = OLD.id
END

609NAME IS NULL:2009/06/21(日) 02:21:48 ID:???
被るところだったw
>>608のDELETE文はFROMがいるんじゃね
DELETE FROM moz_...
610604:2009/06/21(日) 03:10:18 ID:???
>>608,>>609
レスありがとうございます。
ちょっとそこまでくると、サッパリで分からないのですが、

>>604に書いた下記のクエリの下に追加すればいいのでしょうか?
>●自分で調べて書けた一部
>DELETE FROM moz_places WHERE id IN (SELECT place_id FROM moz_historyvisits)
> AND (url LIKE 'http://www.test/%'
> OR (url NOT LIKE 'http://www.example.com/%' AND url NOT LIKE 'http://%.sqlite.localhost/%'))
CREATE TRIGGER delete_history AFTER
DELETE ON moz_places
BEGEN
DELETE moz_historyvisits WHERE id = OLD.id
END

バックアップ取ってから試してみたいと思いますが、よろしければ再度レスをいただければ幸いです。
何度もすみませんが、よろしくお願いします。
611604:2009/06/21(日) 04:15:16 ID:Bz0yhBlW
604です。
色々弄っていたところ、下記のクエリ文で動作しました。 多分。(汗

●クエリ
CREATE TRIGGER delete_history AFTER
DELETE ON moz_places
BEGIN
DELETE FROM moz_historyvisits WHERE id = OLD.id;
END;

DELETE FROM moz_places WHERE id IN (SELECT place_id FROM moz_historyvisits)
 AND (url LIKE 'http://www.test/%'
 OR (url NOT LIKE 'http://www.example.com/%' AND url NOT LIKE 'http://%.sqlite.localhost/%'))

間違い等ありましたら、指摘していただけますでしょうか。
何度もレスをしてスレを伸ばしてしまってすみませんが、よろしくお願いします。
612NAME IS NULL:2009/06/21(日) 05:01:37 ID:???
DELETE FROM moz_places WHERE id IN (SELECT place_id FROM moz_historyvisits)
 AND (url LIKE 'http://www.test/%'
 OR (url NOT LIKE 'http://www.example.com/%' AND url NOT LIKE 'http://%.sqlite.localhost/%'))

が実行されると、自動的に

CREATE TRIGGER delete_history AFTER
DELETE ON moz_places
BEGIN
DELETE FROM moz_historyvisits WHERE id = OLD.id;
END;

が走る。
これがトリガね。
613NAME IS NULL:2009/06/22(月) 07:19:19 ID:???
614604:2009/06/23(火) 00:49:07 ID:???
返事が遅れてすみません。

>>612
レスありがとうございます。
なんとなく分かったような気がします。(・ω・;)

ただ、間抜けな事をしていて消すテーブルが逆でした。(爆
ただ今、修正中なのです。

回答・アドバイス等いただいた方々に大変感謝しています。
この度は色々とどうもありがとうございました。
615NAME IS NULL:2009/06/23(火) 16:46:57 ID:???
テーブルが作成されているかを確認する標準的な方法はあるでしょうか。
mysqlならCREATE DATABASE IF NOT EXISTSでいけるのですが。
616NAME IS NULL:2009/06/23(火) 22:02:19 ID:Lck5HQZ4
テーブル一覧のプロパティのファイルグループ名を
クエリで取得することって出来ますか?
617NAME IS NULL:2009/06/23(火) 22:05:06 ID:???
スレ違い。
618NAME IS NULL:2009/06/24(水) 11:02:20 ID:cpDMBc2F
以下のように、AとBのカラムがあるHOGEと言うテーブルがあったとして、
AとBのカラムを見てユニークなものだけをカウントするにはどういうSQL書けばいいでしょうか?
DBMSはMySQL5.0.67です。

A|B (TABLE HOGE)
-+-
1|2
3|5
7|3 この場合、1,2,3,5,7,9
9|5 よって、その合計の「6」が答え
619NAME IS NULL:2009/06/24(水) 17:00:53 ID:???
指定のMySQLで出来るかどうかは知らん
select count(distinct *) from (select A from HOGE union all select B from HOGE) as X
620NAME IS NULL:2009/06/25(木) 12:44:02 ID:???
SQLって統一規格じゃないんですか?
独自SQLのようなものがあるんですか?
621NAME IS NULL:2009/06/25(木) 12:48:35 ID:???
ある程度の機能と用件を満たせば準拠。
プログラミング言語と比べるとSQLは独自色が強い。
622NAME IS NULL:2009/06/25(木) 22:29:16 ID:???
統一規格はあるけど、方言に頼るところも多い。
文字列変換や時刻関数等はほとんど方言だな。
oracleの外部結合の方言はひどいw
623NAME IS NULL:2009/06/25(木) 23:23:34 ID:???
オラクルの外部結合って、SQL92が出てくる前からあったんじゃなかったけ。
各ベンダーの独自拡張があって、その後の標準化だから、
互換性のために方言として残るのは仕方ないだろう。
624NAME IS NULL:2009/06/25(木) 23:24:48 ID:???
DB2 に truncate 相当の機能が無いのには驚いた。
良い悪いって話じゃないけど。
625NAME IS NULL:2009/06/27(土) 23:05:42 ID:???
下のようなテーブルでIDが1のDATEの新しい順に10個取得したいのですが、もっと早くできる書き方はないでしょうか
IDにはインデックスが無く、DATEはインデックスがあります。
mysql 5.0.51aです

ID | DATE
--+----------
1 | 2009-01-11
2 | 2006-01-01
1 | 2006-11-10
3 | 2008-07-12

SELECT * FROM table WHERE id = 1 ORDER BY DATE DESC limit 10
626NAME IS NULL:2009/06/28(日) 02:18:02 ID:???
>>625
id = 1で検索してるから、idにインデックス付けてみたら?
で、実行計画取ってみて、インデックスの有無で変化があるか確認してみて
627NAME IS NULL:2009/06/28(日) 04:28:48 ID:???
IDの意味解って付けてんのかよ
628NAME IS NULL:2009/06/28(日) 13:31:46 ID:tWKLIY9h
もちろん、IDはプライマリキーです。

とかね。
629NAME IS NULL:2009/06/28(日) 14:38:30 ID:???
あるあるw
630625:2009/06/28(日) 18:03:08 ID:???
問題をわかりやすくするため単純にしたつもりだったのですが
横着してテンプレのものを流用したため、逆に誤解を招く書き方になったようですいません。
ほかで聞くことにします。失礼しました
631NAME IS NULL:2009/06/28(日) 18:38:29 ID:???
Y!知枝袋にでも逝っておいで
632NAME IS NULL:2009/06/28(日) 22:12:36 ID:???
つか、そこまで単純にしてしまって、
速度に差が出るほどバリエーションのある書き方できると思ってたのか?
633NAME IS NULL:2009/06/28(日) 22:45:55 ID:???
相変わらず厳しいやつらだ
634NAME IS NULL:2009/06/29(月) 00:57:01 ID:???
SQL Serverでストアドつくろうとしてるけど、
アプリからストアドに渡す引数がいっぱいあるんだけど普通?

これってアプリでやるべきじゃねぇのか。
アプリにするかストアドにするかの基準を教えてくれ。
635NAME IS NULL:2009/06/29(月) 00:59:57 ID:???
ここはSQL文を語るスレ
636NAME IS NULL:2009/06/29(月) 01:04:31 ID:???
引数がいくつでもスピード重視ならストアドにするんじゃない?
まあ、スレチ。
637NAME IS NULL:2009/06/29(月) 11:21:17 ID:???
Postgresql v8.3で
商品(商品番号(int),商品名(char))
分類(分類番号(int),分類名(char))
取り扱い(商品番号(int),分類番号(int),取り扱い時期(int))
という3つの表を
商品情報(商品番号,分類番号,商品名,分類名,取り扱い時期)という
一つの表集合として結合(4個目の表として存在させる)したいのですが、方法が良く分かりません。

新しく表を定義するのであればcreate tableかなと思ったのですが、表を結合表示させるときは
selectを使っていましたし、create tableとselectをどうやってつなぎ合わせるのか見当もつきません。
ヒントだけでも構いませんのでご教示願います。
638NAME IS NULL:2009/06/29(月) 12:20:27 ID:???
create table 商品番号 (〜〜〜)
insert into 商品番号 select 商品番号, 分類番号, 〜〜〜 from 〜〜 natural join 〜〜 natural join 〜〜
的な感じでいいんんじゃないの?postgres知らんけど
639NAME IS NULL:2009/06/29(月) 12:37:24 ID:???
MySQLです、↓のようなSQL文がありまして
SELECT DISTINCT aaa.*, bbb.name FROM {table_a} aaa LEFT JOIN {table_b} bbb ON aaa.uid = bbb.uid INNER JOIN {table_c} ccc ON aaa.snid = ccc.snid

これにaaa.mailが第四のテーブル({table_d} ddd)のddd.mailと一致しないものを抽出という条件を追加したいのですが
どういう風にすればいいでしょうか?
640NAME IS NULL:2009/06/29(月) 13:56:06 ID:???
度々すみません・・・。
>>637について、

create table 商品情報(
商品番号 int,
分類番号 int,
商品名 char(20),
分類名 char(50),
取り扱い時期 int
) insert into 商品情報 select 商品番号,分類番号,商品名,分類名,取り扱い時期
from 商品 natural join 分類 natural join 取り扱い natural join;
とやってみたのですが、どうもエラーになってしまいます。

insert付近でのエラーとなっているのですが、
insertとcreateを分けてしまうと、createまでは通っても、
insertで既に存在する表の作成云々というエラーになってしまいますし、
表の趣旨も全く意味をなさないものになってしまいます。

どこをどのように修正すればよいのでしょうか?
宜しくお願い致します。
641NAME IS NULL:2009/06/29(月) 17:00:39 ID:???
VIEW作るんじゃいかんの?
642NAME IS NULL:2009/06/29(月) 20:37:15 ID:???
>>640
最後の natural join が余計。
つか、キーワードが分かったら自分でマニュアル読んでみれ。
643NAME IS NULL:2009/06/29(月) 21:25:23 ID:???
>>640
恒常的に見るのであれば、
craete view 商品情報(・・・・)
select 〜
644NAME IS NULL:2009/06/30(火) 16:11:55 ID:???
実体作りたいって言ってんだろカス
645NAME IS NULL:2009/06/30(火) 16:39:18 ID:???
結合したいっていう話しか出てないだろ
人の話はちゃんと読め
646NAME IS NULL:2009/07/01(水) 03:12:25 ID:???
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
647NAME IS NULL:2009/07/01(水) 06:52:40 ID:???
>>646
うん。だからviewでいいよね。
648NAME IS NULL:2009/07/01(水) 10:48:26 ID:???
元質問者はVIEWの存在を知っているのかどうかが知りたいところではある
649NAME IS NULL:2009/07/01(水) 10:57:35 ID:???
ある時点のスナップショットをとりたい=>ワークテーブル
複数テーブルの結合結果を表として扱いたい=>VIEW
どちらをやりたいのかによるな
650NAME IS NULL:2009/07/01(水) 11:16:04 ID:???
>>647
よくない。SQL初心者?
651NAME IS NULL:2009/07/01(水) 12:08:55 ID:???
>>650
横からすみませんが、「ちゃんと読め」とか「よくない」とか文句だけ言うよりは、
自分で回答を示せば良くないですか?
652NAME IS NULL:2009/07/01(水) 12:35:29 ID:???
>>639
動作未確認だけど、WHERE句で条件付けるのはダメ?
WHERE NOT EXISTS(
SELECT *
FROM {table_d} ddd
WHERE ddd.mail = aaa.mail
)
653639:2009/07/01(水) 14:03:32 ID:???
>>652
行けました、NOT EXISTSという使い方があったんですね
前任者の書いたSQLに処理を追加する作業だったんですが安請け合いして後悔し始めたところです
dくすでした
654NAME IS NULL:2009/07/01(水) 18:05:32 ID:???
細かい話だけどNOT EXISTS ならSELECT 1 とかすべき
655NAME IS NULL:2009/07/01(水) 18:12:21 ID:???
細かい話だけど最近のRDBMSならSELECT *で十分最適化されるよ
656NAME IS NULL:2009/07/01(水) 21:55:46 ID:???
むしろ*のほうがいい
657NAME IS NULL:2009/07/02(木) 16:10:37 ID:???
で、どっちが正解?
658NAME IS NULL:2009/07/02(木) 17:13:52 ID:???
>>657
昔は定数の方が速かった。今は * の方が速い時もある。
659NAME IS NULL:2009/07/03(金) 11:43:01 ID:???
なるほど
660NAME IS NULL:2009/07/03(金) 18:05:06 ID:???
教えてくだせー
>>4で、例えば最新の3件を抽出するにはどうしたらいいですか?
661NAME IS NULL:2009/07/03(金) 18:10:02 ID:???
top n とかrow_number()とかrownumとか。
DBMSの種類によって書き方が違う。
662660:2009/07/03(金) 22:18:56 ID:???
>>661
ありがとう
ちょっとやってみます
663NAME IS NULL:2009/07/06(月) 21:30:55 ID:???
MSDEのData更新に困っております
AccessプロジェクトよりCSVファイルをインポートして
DataBase作成しているのですが、インポート先のCSVファイルは
常に更新されています
AccessプロジェクトのData更新の為、インポートを行うと
重複したDataになります・・・・
重複しないクエリもしくはVBEはないでしょうか?

664NAME IS NULL:2009/07/06(月) 22:18:16 ID:???
まず「インポート」の意味から勉強してこようぜ
話はそれからだ。
665NAME IS NULL:2009/07/07(火) 06:37:53 ID:???
importの前にdeleteすればOKだね
はい 次
666NAME IS NULL:2009/07/07(火) 09:46:04 ID:???
>>663
MSDEどこいった?
667NAME IS NULL:2009/07/07(火) 17:00:45 ID:???
−データベース桐からの挑戦−
「販売管理とか会計システムとかのSQLの例書いてみろよ」
だそうです。
ttp://pc11.2ch.net/test/read.cgi/db/1057318214/699
668663:2009/07/07(火) 20:04:57 ID:???
申し訳御座いませんマルチしておりました
反省しております
>>665さん
AccessプロジェクトのDataをdeleteしましたができませんでした
別のやり方があるのでしょうか・・・
MDBの様にリンクできればよいのですが
669NAME IS NULL:2009/07/08(水) 09:44:54 ID:???
>>668
あっちのスレでもいっぱい返事もらってるのに
並行で進めるのはやめれ
670NAME IS NULL:2009/07/08(水) 17:28:50 ID:???
>>669
質問の内容はどうでもいいことばかり。
だれかれに構って欲しいのさ。
あちこちに書くのは、2chに張り付いてるからだろ。
とにかくかまって欲しいんだよ。
671NAME IS NULL:2009/07/09(木) 14:22:20 ID:I1RDXwu9
postgresSQLを使っているのですが、以下の問題がわかりません。
以下の順序で列を表示するビュー定義を考え実行する
支払金額、明細
672NAME IS NULL:2009/07/09(木) 14:57:50 ID:???
>>671
宿題は自分で解く。
順序の指定は ORDER BY
673NAME IS NULL:2009/07/09(木) 15:14:05 ID:???
SQL Server 2005 互換性レベル8.0(2000)です。

別テーブルに問い合わせて、条件に該当するレコードが存在するかどうかを、列に表示したいのです。Boolで。
SELECT CM.CustomerID, CM.CustomerName,
FlagUriage = ( CONVERT( bit, ( SELECT COUNT(*) FROM UriageData UD WHERE UD.Nendo = 2008 and UD.CustomerID = CM.CustomerID ) ) )
FROM Customer CM ORDER BY CustomerID
現在は、このように件数をCountしたのをbitにConvertしてますが、これでいいんですかね。

EXISTS を使えば、booleanを返すのだから、
FlagUriage = ( EXISTS ( SELECT * FROM UriageData UD WHERE UD.Nendo = 2008 and UD.CustomerID = CM.CustomerID ) )
のようにすればよさそうだけどエラーになる。
キーワード 'EXISTS' 付近に不適切な構文があります。

一番りこうな書き方は何ですか。
674NAME IS NULL:2009/07/09(木) 15:58:07 ID:H2IBJWq1
>>673
どういう文脈で使いたいのかいまいち分からないけど
TSQL内で使うならIF
SQL分だけで使うならcoalesceでよくない?
675NAME IS NULL:2009/07/09(木) 15:59:19 ID:???
利口ってか、早いのは実行計画とってみないとわからん

外部結合してNULLかどうか判定するとかが一般的じゃないかな

あとはUNION使って
SELECT ..., 1 as FlagUriage WHERE ...
UNION
SELECT ..., 0 as FlagUriage WHERE not ...
とか
676NAME IS NULL:2009/07/09(木) 17:43:54 ID:???
>>673
SQL鯖はよく知らないが
> FlagUriage = ( CONVERT( bit, ( SELECT COUNT(*) FROM UriageData UD WHERE UD.Nendo = 2008 and UD.CustomerID = CM.CustomerID ) ) )
> FlagUriage = ( EXISTS ( SELECT * FROM UriageData UD WHERE UD.Nendo = 2008 and UD.CustomerID = CM.CustomerID ) )
なにこれ? よっとして (CONVERT .....) AS FlagUriage と同じことなのかな?
COUNT(*)するよりEXISTSの方が良さそうなので、

CASE WHEN EXISTS ( SELECT * FROM UriageData UD WHERE UD.Nendo = 2008 and UD.CustomerID = CM.CustomerID ) THEN 'あり' ELSE 'なし' END
で動かないかな?
677NAME IS NULL:2009/07/15(水) 14:14:11 ID:???
MySQL 5.0.45で質問です。

webのアクセスログをDBに格納しており
以下の様なTABLEになります。

FILE  | DATETIME
-----+---------------------
aa.txt | 2007-11-01 00:05:10
aa.txt | 2007-11-01 06:02:00
bb.txt | 2007-11-01 02:30:30
aa.txt | 2007-11-02 10:15:15
aa.txt | 2007-11-02 15:30:00
cc.txt | 2007-11-03 10:05:50

これを以下の様に、ファイルの日毎のアクセス数(COUNT)を
取得したいと思っていますが、どのようにSQLを書けば良いでしょうか?

FILE  | DATE | COUNT
-----+-------+-------
aa.txt | 11-01 | 2
aa.txt | 11-02 | 2
aa.txt | 11-03 | 0
bb.txt | 11-01 | 1
bb.txt | 11-02 | 0
bb.txt | 11-03 | 0
cc.txt | 11-01 | 0
cc.txt | 11-02 | 0
cc.txt | 11-03 | 1

理想は以下のようになれば良いですが、上記のようになってくれれば
あとはプログラムで対応したいと思ってます。

FILE | 11-01 | 11-02 | 11-03
-----+------+-----+------
aa.txt | 2   | 2   | 0
bb.txt | 1   | 0   | 0
cc.txt | 0   | 0   | 1
678NAME IS NULL:2009/07/15(水) 14:26:41 ID:???
mysql> select date_format(hiredate, '%m-%d'), count(*) from emp group by date_format(hiredate, '%m-%d');
+--------------------------------+----------+
| date_format(hiredate, '%m-%d') | count(*) |
+--------------------------------+----------+
| 01-23 | 1 |
| 02-20 | 1 |
| 02-22 | 1 |
| 04-02 | 1 |
| 04-19 | 1 |
| 05-01 | 1 |
| 05-23 | 1 |
| 06-09 | 1 |
| 09-08 | 1 |
| 09-28 | 1 |
| 11-17 | 1 |
| 12-03 | 2 |
| 12-17 | 1 |
+--------------------------------+----------+
13 rows in set (0.00 sec)
679NAME IS NULL:2009/07/15(水) 14:46:18 ID:???
このSQLはあまり性能がよくないので気をつけてね
680NAME IS NULL:2009/07/15(水) 15:02:23 ID:???
レスありがとうございます
ただファイル毎の統計が欲しかったので以下のようにしてみました
あとはプログラム側で加工していこうと思います。

select
  A.FILE,acdate,COUNT
from
  (select
    FILE, acdate
  from
    (select DISTINCT FILE from LOGTABLE) as A1
  CROSS JOIN
    (select DISTINCT date_format(actime,'%m%d') as acdate from LOGTABLE) as A2
  ) as A
LEFT JOIN
  (select
    FILE, date_format(actime,'%m%d') as acdate2, count(*) as COUNT
  from
    LOGTABLE
  group by
    concat(month(actime), '-', day(actime), FILE)
  ) as B
ON
  A.FILE = B.FILE and A.acdate = B.acdate2
order by
  FILE, acdate
681NAME IS NULL:2009/07/16(木) 22:01:04 ID:???
Oracle xeで、以下の機能を実現したいんですが...
どうにも長くなってしまいそうで...短く実現する方法はないでしょうか?

あるテーブル『TT』に
KEY
-----
3
5
6
10
11

って感じで入ってる値を1回のSQLで横に並べたいんです。

key1 | key2 | key3 | key4 | key5
----+------+-----+-----+-----
3 | 5 | 6 | 10 | 11

で、散々悩んだ挙句...

SELECT
T1.KEY KEY1, T2.KEY KEY2, T3.KEY KEY3, T4.KEY KEY4, T5.KEY KEY5
FROM
(SELECT KEY FROM (SELECT KEY, ROWNUM RN FROM TT) WHERE RN = 1) T1,
(SELECT KEY FROM (SELECT KEY, ROWNUM RN FROM TT) WHERE RN = 2) T2,
(SELECT KEY FROM (SELECT KEY, ROWNUM RN FROM TT) WHERE RN = 3) T3,
(SELECT KEY FROM (SELECT KEY, ROWNUM RN FROM TT) WHERE RN = 4) T4,
(SELECT KEY FROM (SELECT KEY, ROWNUM RN FROM TT) WHERE RN = 5) T5

こんなSQLを書いたんですが...
正直もっと簡単にならないものでしょうか?

682NAME IS NULL:2009/07/16(木) 22:19:25 ID:???
683NAME IS NULL:2009/07/16(木) 22:36:42 ID:???
このスレはまとめサイトがあったほうがいいかもわからんね
684NAME IS NULL:2009/07/17(金) 01:14:50 ID:???
>681
レスthx
そおですか...
一応maxが20の可変長なんで、自分の書いたSQLを20まで書けば実現できるんですが...

ストアドかアプリサイドで、ですね。
アプリサイドは通信料増えるのを嫌って最後の手段で考えてました。
ちょっと検討してみます。(´・ω・`)
685NAME IS NULL:2009/07/17(金) 01:15:36 ID:???
>682だった。(´Д`;)
686NAME IS NULL:2009/07/17(金) 03:42:40 ID:???
縦横変換の基本形に従うと次のようになる。

SELECT
MAX(CASE WHEN RN = 1 THEN KEY END) AS KEY1,
MAX(CASE WHEN RN = 2 THEN KEY END) AS KEY2,
MAX(CASE WHEN RN = 3 THEN KEY END) AS KEY3,
MAX(CASE WHEN RN = 4 THEN KEY END) AS KEY4,
MAX(CASE WHEN RN = 5 THEN KEY END) AS KEY5
FROM (
SELECT KEY, ROWNUM AS RN FROM TT
)

簡単になるかどうかはともかく全表検索は1回で済む。

質問したいんだけど、XEを業務で使っているの?
687681:2009/07/17(金) 17:07:04 ID:???
>686
thx。自分で考えた方法よかよっぽど良いですね。
結局、あれから検討した結果。。。他にも要因があってアプリサイドでやることになりました。

xeは業務で使ってますよ。
本ちゃん環境は10gらしいですが...
688NAME IS NULL:2009/07/17(金) 18:56:24 ID:???
>687
なるほど開発で使っているのか。
ちょうど俺も試しに使ってみようとしていたところなんだ。
ありがと。
689NAME IS NULL:2009/07/19(日) 16:28:56 ID:Ee/IhaoQ
下記のようなデータがあり、最新の3日分のデータを取得しようとしています。
このような場合、MySQLでのSQL文はどうなるでしょうか?

◎データベース

id | date    | memo
---+------------+------
1 | 2009-12-22 | test1
2 | 2009-12-23 | test2
3 | 2009-12-24 | test3
4 | 2009-12-24 | test4
5 | 2009-12-25 | test5

◎取得しようとしてるデータ(最新の3日分のデータ)

array(
'2009-12-25' => array(
array('id'=>5,'date'=>'2009-12-25','memo'=>'test5'),
),
'2009-12-24' => array(
array('id'=>3,'date'=>'2009-12-24','memo'=>'test3'),
array('id'=>4,'date'=>'2009-12-24','memo'=>'test4'),
),
'2009-12-23' => array(
array('id'=>2,'date'=>'2009-12-23','memo'=>'test2'),
),
);
690NAME IS NULL:2009/07/19(日) 20:51:49 ID:???
select * from test t1,
(select distinct date_format(date, '%Y-%m-%d') df
from test order by df desc limit 3) t2
where date_format(t1.date, '%Y-%m-%d') = t2.df
order by t1.date desc;
691NAME IS NULL:2009/07/19(日) 20:53:54 ID:???
>>689
SELECT * FROM table
WHERE `date` >= DATE_SUB(CURDATE() , INTERVAL 3 DAY)

で、どうでしょう?
692NAME IS NULL:2009/07/19(日) 21:06:22 ID:???
データの無い日をどう数えるかによるね
693689:2009/07/19(日) 22:37:34 ID:???
>>690-692
すみません、MySQLではなくSQLite(Ver.2)でした。
SQL文を実行してみましたがno such functionやsyntax errorでした。
694NAME IS NULL:2009/07/19(日) 23:02:40 ID:???
SELECT * FROM Table AS T1 WHERE 3 > (SELECT count(DISTINCT date) FROM Table WHERE date > T1.date);
SQLiteで動くかどうかしらね。
695NAME IS NULL:2009/07/20(月) 00:49:08 ID:???
Oracle 10g で質問です。

WITH句で書いたクエリをインライン展開するかどうかを
ヒントなどで制御する方法はないでしょうか?

「実行に時間はかからないが、SQLが長い/複雑になる」という場合に、
SQLはWITH句に1回だけ書きたいのですが、
実行結果をTEMP TABLE TRANSFORMATIONするとかえって遅くなるので、
参照箇所のそれぞれで(インラインで書いた場合と同じように)
実行して欲しいのです。

簡単に言うと、WITH句で、
 @同じクエリを複数回書かなくて良い
 A同じクエリを複数回実行しない
と出来るうちの、@だけ使いたいということです。

方法をご存知の方がいらっしゃいましたら、教えて下さい。
よろしくお願いします。
696NAME IS NULL:2009/07/20(月) 17:42:45 ID:???
Oracleをなめまくる
697NAME IS NULL:2009/07/21(火) 01:21:08 ID:???
>>695
どうも最終的にどんな結果が欲しいのか良くわからん。
簡単でいいからやりたいことをSQLで例示してくれないか。
698NAME IS NULL:2009/07/21(火) 01:59:06 ID:???
こういうことかな? たとえが適正かどうかは別にして

WITH WithT AS (SELECT * FROM Table WHERE col1 = true)
SELECT * FROM WithT WHERE col2 = 1
UNION ALL
SELECT * FROM WithT WHERE col2 = 2;

この場合、WITH句のクエリが1度実行されて、一時的に置いておいて
その中から col2 を2回検索される。
のだけれども、col2にはインデックスが張られているので、
SELECT * FROM Table WHERE col1=true AND col2 = x;
が2度実行される方が速い。
だから、そのように動かす方法は無いかや?

で、俺はその答えを知らない。Oracle使いでもないしな。
何かスイッチで制御できるものなのか、それとも各ベンダーの
プランナやオプチマイザでの性能UPを期待するしかないのか?
699NAME IS NULL:2009/07/21(火) 07:36:44 ID:???
本来はそこもオプテイマイザが適切に判断するはずなんだが、それが
実際には意図した実行計画になっていなかったから明示的にHINTで
指定したいのだと読んだが?
答は俺も知らん。
700NAME IS NULL:2009/07/21(火) 22:22:00 ID:???
ますますわからん
701695:2009/07/23(木) 02:11:26 ID:???
695です。言葉足らずですみません。
言いたかったことはほぼ>>698さん、>>699さんに書いてもらった内容でした。

ただインデックスがある場合に限らずで、
「一時的に置いておいて」の処理自体でそこそこ時間がかかってしまうようで、
2回実行した方が速いことが結構あります。
ですが実際はそうは動いてくれず、
ヒントなどで制御できないのかな?と思った次第でした。

それらしいヒントは調べても見当たらなかったので、
ヒント以外でも何か方法があればと思ったのですが、、、


702698:2009/07/25(土) 14:43:40 ID:???
>>701
>>699も言ってるが、プランナかオプティマイザが適切に判断するべきところなんだけど、
Oracleの仕様上WITH句のサブクエリだけ先に実行されてしまうようになっているのなら
どうしようもないが、判断上でサブクエリが実行されているのなら、コスト計算の問題かな?

一時テーブルへの待避コストを多く見積もるようにどこかにパラメータはない?
てか、Oracleスレで聞いた方がいいかも。
703NAME IS NULL:2009/07/25(土) 23:51:12 ID:???
SQLiteで以下のようなテーブルがあります。
hashが主キーです。

hash|name|size

LIKEでの検索時にdistinctでnameとsizeが重複するものを除外したいのですが、
hashも取得しなければなりません。

よってSELECT hash, name, sizeとしたいのですが、
distinctでhashは除外したいのです(そうしないと重複はあり得ないため)。

なにか良い方法はありますか?
704NAME IS NULL:2009/07/26(日) 01:05:23 ID:???
>>703
日本語でおk
ハッシュ値がユニークなのに、ほか二つの値が同じレコードをまとめたいなんて、一体どっちのハッシュ値をもってくればいいんだ?
705703:2009/07/26(日) 01:13:40 ID:???
>>704
あ、そういえばそうですね。
重複したname,sizeをリストから除去したいです。

ハッシュは最初に現れる値でも最後に現れる値でもどちらでも良いですが、重複をのぞく方法は他にあるのでしょうか?
706NAME IS NULL:2009/07/26(日) 01:53:42 ID:???
>>705
今端末さわれる場所にいないからなんとも言えんが、
select hash, name, size from table_name where name != (select name from table_name group by name, size having count(*) >1) and size != (select size from table_name group by name, size having count(*) >1);
で、いいのか?
汚いな...
707NAME IS NULL:2009/07/26(日) 02:49:31 ID:???
>>705
select distinct on (name, size) hash, name, size from table_name;
おやすみ。
708NAME IS NULL:2009/07/26(日) 03:29:26 ID:???
>>707
それポスグレだろ。

select hash,name,size from table_name group by name,size
でいける。他だと動かないみたいだけど。
709NAME IS NULL:2009/07/26(日) 03:52:42 ID:???
それ動くのかよw
むちゃくちゃだな
710NAME IS NULL:2009/07/28(火) 17:45:01 ID:???
SQLserver2005の処理で一つ教えてください。
2つの同じ項目のビューがあり、それを一つのビューにマージしようと思っています。
ただある項目が重複した場合は重複データを破棄したいのですが
UNIONだとキー以外の項目が違っていたら別データ扱いですし、
UNION ALLでは問答無用で入ってしまいます。
重複キーを指定してマージすることはできるのでしょうか?
711NAME IS NULL:2009/07/28(火) 19:08:16 ID:???
>>710
なんかデジャヴだな
キーが同じでキー以外の項目が違う場合はどのデータを残すん?
712NAME IS NULL:2009/07/28(火) 19:15:12 ID:???
select id, value from union_parts_1
union all
select id, value from union_parts_2 where not exists (select * from union_parts_1 where union_parts_2.id = id)

とか?
713NAME IS NULL:2009/07/28(火) 20:00:48 ID:???
>>711
破棄だから、重複したデータは結果から削除じゃないのか?

>>710
select id,value from table1 where id not in (select id from table2)
union all
select id,value from table2 where id not in (select id from table1)

で行けると思う。ためしてないけど
714NAME IS NULL:2009/07/28(火) 22:41:46 ID:???
>>713
両方破棄すんの?
715NAME IS NULL:2009/07/28(火) 23:22:27 ID:???
重複コードを破棄しちゃいかんだろ。
1つ残すととらえるのが自然だと思う。
716NAME IS NULL:2009/07/28(火) 23:29:32 ID:???
そう読むのが自然な気はするけどどっちを残せばいいのかわからん。
キー以外のカラムも同じならどっちでもいいんだろうけどそうでは無いんだよね?
717NAME IS NULL:2009/07/28(火) 23:55:26 ID:???
結局>>711に戻るわけだな
718NAME IS NULL:2009/07/29(水) 00:30:06 ID:???
そうね。>>713は先走ったかも
719NAME IS NULL:2009/07/29(水) 05:52:21 ID:???
>>714,715
どちらかのテーブルのデータ残すなら>>712で行けるんじゃないか
両方消すなら>>713
それ以外なら>>710の説明不足

やりたいことをちゃんと説明できないのは
自分自身も何をどうしたいのかはっきり分かってないって事だろうな
720NAME IS NULL:2009/07/29(水) 14:37:57 ID:???
こういうの、どうすればうまくいきますか?

テーブル

日付 | 数量
---------------
2009-6-10|1000
2009-6-11|2000
2009-6-13|3000
2009-7-10|1100
2009-7-13|1200
2009-7-15|1300

取得したい表(同日を比較したい)

当月     数量    前月 数量
-------------------------------
2009-7-10|1100|2009-6-10|1000
2009-7-11|1100|2009-6-11|2000 2009-7-11は無いため2009-7-10のデータをセット。
2009-7-13|1200|2009-6-13|3000
2009-7-15|1300|2009-6-15|3000 2009-6-15は無いため2009-6-13のデータをセット。
721NAME IS NULL:2009/07/29(水) 16:24:08 ID:???
>>720
先月との比較を曜日で合わせてる?
日付対応のルールが明確でないと色々厳しいと思うけど。
722NAME IS NULL:2009/07/29(水) 16:32:28 ID:???
>>720
PostgreSQL用、つっても汎用的に書いたつもりだが、
INTERVAL型指定とかEXTRACT(=date_part)なんかはお使いのDBに合わせてな。

SELECT
CASE WHEN T1.日付 IS NULL THEN T2.日付-INTERVAL'1 MONTH' ELSE T1.日付 END AS 当月,
CASE WHEN T1.数量 IS NULL THEN (SELECT 数量 FROM Table WHERE 日付 = (SELECT max(日付) FROM Table WHERE 日付 < T2.日付+INTERVAL'1 MONTH')) ELSE T1.数量 END AS 数量,
CASE WHEN T2.日付 IS NULL THEN T1.日付+INTERVAL'1 MONTH' ELSE T2.日付 END AS 前月,
CASE WHEN T2.数量 IS NULL THEN (SELECT 数量 FROM Table WHERE 日付 = (SELECT max(日付) FROM Table WHERE 日付 < T1.日付-INTERVAL'1 MONTH')) ELSE T2.数量 END AS 数量
FROM (SELECT * FROM Table WHERE EXTRACT(MONTH FROM 日付) = EXTRACT(MONTH FROM NOW())) AS T1
FULL JOIN
(SELECT * FROM Table WHERE EXTRACT(MONTH FROM 日付) = EXTRACT(MONTH FROM NOW()-INTERVAL'1 MONTH')) AS T2
ON EXTRACT(DAY FROM T1.日付) = EXTRACT(DAY FROM T2.日付);

実用的な速度が得られるかどうかしらんよ。
723NAME IS NULL:2009/07/29(水) 16:37:49 ID:???
07/01とか06/01のデータが無い場合が厄介だな
724722:2009/07/29(水) 16:48:22 ID:???
訂正

SELECT
CASE WHEN T1.日付 IS NULL THEN T2.日付+INTERVAL'1 MONTH' ELSE T1.日付 END AS 当月,
CASE WHEN T1.数量 IS NULL THEN (SELECT 数量 FROM Table WHERE 日付 = (SELECT max(日付) FROM Table WHERE 日付 < T2.日付+INTERVAL'1 MONTH')) ELSE T1.数量 END AS 数量,
CASE WHEN T2.日付 IS NULL THEN T1.日付-INTERVAL'1 MONTH' ELSE T2.日付 END AS 前月,
CASE WHEN T2.数量 IS NULL THEN (SELECT 数量 FROM Table WHERE 日付 = (SELECT max(日付) FROM Table WHERE 日付 < T1.日付-INTERVAL'1 MONTH')) ELSE T2.数量 END AS 数量
FROM (SELECT * FROM Table WHERE EXTRACT(MONTH FROM 日付) = EXTRACT(MONTH FROM NOW())) AS T1
FULL JOIN
(SELECT * FROM Table WHERE EXTRACT(MONTH FROM 日付) = EXTRACT(MONTH FROM NOW()-INTERVAL'1 MONTH')) AS T2
ON EXTRACT(DAY FROM T1.日付) = EXTRACT(DAY FROM T2.日付);

当月、前月の日付を表示する部分で、対応する日付がない場合の表示を±逆にしていた。

>>723
それはこのSQLだと前月最終データからとってくるだけなんだけど、
7月31日の前月データは6月30日('2009-07-31' - '1 month' の値次第)になる。
725NAME IS NULL:2009/07/29(水) 19:27:46 ID:JrJvF1CD
一つのSQL文内に、同じSELECT文が何度も出てくる場合、
あらかじめSELECTした結果に別名をつけておいて、
それを使い回すことってできますか?
726NAME IS NULL:2009/07/29(水) 20:05:07 ID:???
>>725
WITH句をサポートするDBMSならそれで
なければVIEWで
727NAME IS NULL:2009/07/29(水) 20:18:59 ID:???
一時テーブルかなー
728725:2009/07/29(水) 22:29:26 ID:???
ありがとうございます。
一文中では無理な感じでしょうか。
SELECTしか使えない環境なので、一文でなんとかしたかったのです。
PostgreSQLなのですが、DBMSはよく分かりません。
729NAME IS NULL:2009/07/29(水) 22:32:00 ID:???
SELECTしか使えない環境・・・? Accessか何かか?
730NAME IS NULL:2009/07/29(水) 22:53:12 ID:???
そこでSQLインジェクションですよ
731NAME IS NULL:2009/07/30(木) 00:03:16 ID:???
内容によってはなんかできるかもしれないけど、それだけだとちょっと難しいよね
732NAME IS NULL:2009/07/30(木) 01:38:14 ID:???
>>728
PostgreSQLは最新の8.4からWITH句をサポート
733NAME IS NULL:2009/07/30(木) 02:25:50 ID:???
初めて質問するので書き方が間違っていたらごめんなさい。

・MySQL 4.1


maintable
mid | field1 | field2
---------------
5 | 2 | 4
6 | 1 | 5
  ・
  ・
  ・

subtable
sid | tema
----------
1 | その1
2 | その2
3 | その3
4 | その4

field1=sid,field2=sidとして結合なり置換して

mid | tema1 | tema2
-------------------
5 | その2 | その4
6 | その1 | その5
   ・
   ・
   ・

としてselectすることはできるのでしょうか。どうかよろしくお願いします。
734NAME IS NULL:2009/07/30(木) 03:10:34 ID:???
>>733
SELECT T1.mid,T2.tema,T3.tema
FROM maintable AS T1
LEFT JOIN subtable AS T2 ON T1.field1=T2.sid
LEFT JOIN subtable AS T3 ON T1.field2=T3.sid;
735nanasi:2009/07/30(木) 06:17:30 ID:suQVAKTQ
http://kakaku.com/bb/ranking_ADSL3_120040290027000000000012/?sort=3&page=000&button=0&sc=7&count=15
都会系、受信局2km範囲。
光など不要。\
7ヵ月後2万円キャッシュバックって偉くない? ちなみにおいらは@nifty
何処かの糞みたいに高いプロバイダーが不要やねん。
 この世の中に。
 書類利用規約審査義務違反。あの画像さあ? 
 もっと改め直して?なっ?
書類不正利用規約義務違反 こっちそっちの手引きで免許証の裏に住所書いて、警察署でおしかり受けたがな。
なんで俺がそんなん喰らわなあかんねん?ヘボプロバイダーO○N。
736NAME IS NULL:2009/07/30(木) 11:05:29 ID:72K2TDMo
ほんと基本的な質問ですみませんが、テーブル定義書において、タイプ記述方法を調べたいのです。
CHAR,NUMERIC,DECIMALなどを書く方法もありますが、それ以外の方法(特に今回知りたいのは0,S,A,Oと書く方法)について、
教えていただけないでしょうか。
サイトの紹介でも結構です、よろしくお願いいたします。
737NAME IS NULL:2009/07/30(木) 12:01:17 ID:???
回答またはアドバイスをお願いいたします。
長文ですみません。

MySQLを使用しています。

[テーブルの項目]
・ID(主キー):数値(AUTO_INCREMENT)
・KEYWORD:文字列
・USER_ID:数値
・ENABLE_FLG:有効/無効設定フラグ (TRUE/FALSE)

[前提]
・ユーザはキーワードをデータベースにいくつでも登録できる。
・ユーザはそれぞれのキーワードに対して、有効/無効を設定できる。
・同じキーワードを別のユーザが登録することができる。
・1人のユーザが同じキーワードを2つ以上登録することはできない。

[取得したい情報]
・指定した複数のキーワードを全て登録しているユーザ(USER_ID)を知りたい。(AND検索)
(キーワードが有効になっていることが条件)
・条件を満たしている全てのUSER_IDを取得する。

検索するキーワードが'AA'と'BB'の場合は
↓のようになりますよね?

SELECT USER_ID FROM KEYWORD_TBL
WHERE KEYWORD == 'AA' AND ENABLE_FLG == 'TRUE'
AND USER_ID IN
(SELECT USER_ID FROM KEYWORD_TBL
WHERE KEYWORD == 'BB' AND ENABLE== 'TRUE');

キーワードが3つ以上だった場合(AA,BB,CC)は、
WHERE句と副問い合わせを伸ばすしかないでしょうか?
'AA','BB','CC'を登録してあるUSERを選ぶ、
という処理のスマートな書き方を教えてください。
738NAME IS NULL:2009/07/30(木) 12:11:48 ID:???
select user_id from keyword_tbl where keyword in ('AA', 'BB', 'CC')
group by user_id having count(*) = 3
とか?
実際に確認してないけれども。
739NAME IS NULL:2009/07/30(木) 16:28:37 ID:???
>>738
なるほど!その手がありましたか。
参考になりました。ありがとうございます。
740NAME IS NULL:2009/07/30(木) 18:21:49 ID:???
MySQLで、ある数値がカンマ区切りで数値の入っているフィールド
nums(text型)に含まれるかを判断するWHERE文を書きたいのですが、
どう書いたら良いでしょうか。
ANDで絞り込み条件として使いたいのですが、思いつきません。

イメージとしてはこんな感じです(128がnumsに含まれるレコード抽出)。

SELECT * FROM test WHERE 128 IN(nums);

どうか知恵をお貸しください。
741NAME IS NULL:2009/07/30(木) 18:46:34 ID:???
>>740
SELECT * FROM test WHERE nums REGEXP concat('(^|,','128','(,|$)');
かな? 自信なし。
742NAME IS NULL:2009/07/30(木) 18:48:26 ID:???
書き込んでから気づいた。直書きならわざわざconcatで連結する必要ないな。
nums REGEXP '(^|,)128(,|$)';
743NAME IS NULL:2009/07/30(木) 20:57:26 ID:EY3peTrf
postgreSQLで、
日付の差分を値の補正に使いたいのですが、
日付の差分を値に掛けると XXXX day みたいな日数表示になってしまいます。
この日数型を整数にするにはどうすればいいでしょうか。
744NAME IS NULL:2009/07/30(木) 21:21:46 ID:???
>>743
EXTRACT(DAY FROM INTERVAL型)
745743:2009/07/30(木) 21:22:24 ID:???
調べたらextractというのがありました。
(extract(year FROM age(日付1,日付2)) * 365) +
(extract(month FROM age(日付1,日付2)) * 31) +
(extract(year FROM age(日付1,日付2)))
これに月の日数と閏年の判定をいれれば、ゴリ押しでとれなくもないですが。。。
746743:2009/07/30(木) 21:31:47 ID:???
>>744
extract(day FROM (日付1-日付2)) で日数とれました。
ありがとう。
747740:2009/07/30(木) 21:36:55 ID:???
>>741-742
早速のレス有難うございます。
レスが遅くなり申し訳ありません。

ただいま確認したところ、期待通りに動きました。
大変助かりました。有難うございました。
748NAME IS NULL:2009/08/01(土) 01:13:32 ID:QhJyGjWf
私は、ある素材生地を扱っている者です。
加工賃の計算でSQLを使用したいと思っておりますが、
エクセル見たく上手いことができず、
お教えいただきたく質問させていただきました。
横(50〜200)は生地の幅、縦(100〜500)は生地の長さで
枠(3〜30)は生地をカットする加工賃を表しています。

MM | 50| 75|100|150|200
---+---+---+---+---+---
100| 3| 5| 8| 10| 15
150| 5| 7| 10| 13| 18
200| 8| 11| 15| 20| 21
300| 10| 15| 18| 21| 24
400| 12| 16| 20| 23| 26
500| 15| 18| 24| 27| 30

(例1)幅が100、長さが200のときの加工賃は15となる。
(例2)幅が80、長さが250のときの加工賃は18となる。
(例3)幅が175、長さが428のときの加工賃は30となる。

抽出するクエリを教えて下さい。お願い致します。
749NAME IS NULL:2009/08/01(土) 01:27:23 ID:???
それだと、長さで抽出するしかないね。
長さ n として、n <= MM で、かつ、一番小さい奴を取ってくる。

どうせなら、

長さ | 幅 | 加工賃

ってテーブル構造にしとけばいいのに。
750NAME IS NULL:2009/08/01(土) 06:54:26 ID:???
>>748
抽出するクエリより、まずテーブル構造考えないとダメじゃないか
まず考えたテーブル示してくれ
あとSQL使うデータベースは何を使うんだ?
751 [―{}@{}@{}-] NAME IS NULL:2009/08/01(土) 08:02:25 ID:???
これを見てくれ こいつをどう思う?

長さランクテーブル   幅ランクテーブル
ランク|長さ1|長さ2 ランク|幅1|幅2
 1 | 0|100        1|0|50
 2 |100|150       2|50|75
 3 |150|200       3|75|100
 4 |200|300       4|100|150
 5 |300|400       5|150|200
 6 |400|500

加工賃テーブル
幅ランク|長さランク|加工賃
1|1|3
1|2|5
中略
5|5|26
5|6|30

SELECT 加工賃 FROM 加工賃テーブル
WHERE 長さランク=(select ランク from 長さランクテーブル where 長さ1<ながさ and ながさ<=長さ2)
 AND 幅ランク=俺の尻の穴に貴方の野太いアー
752NAME IS NULL:2009/08/01(土) 08:35:58 ID:???
>>751じゃランクを細分化したくなったとき困るだろ

素直に>>749
 select min(加工賃)
 from TableName
 where 長さ >= 注文された長さ
 and 幅 >= 注文された幅
で初めてか?力抜けよ
753NAME IS NULL:2009/08/01(土) 10:43:15 ID:???
>>752
の方法でいけるね。
ちなみに同表をクエリで得るにはPIVOTを使う。

USE [MyDB]
GO
CREATE TABLE [dbo].[PriceTable](
[width] [int] NOT NULL,
[length] [int] NOT NULL,
[payment] [int] NOT NULL
) ON [PRIMARY]
GO

SELECT length as 'MM',[50],[75],[100],[150],[200]
FROM
(SELECT length,width,payment FROM PriceTable) AS SourceTable
PIVOT
(
MIN(payment) FOR width IN ([50],[75],[100],[150],[200]))AS PIVOTTABLE
754725:2009/08/01(土) 12:13:14 ID:iuklVi8s
レコードの値と、最大値、データ数などの集約情報とを、
演算したいのですが、例えば、

<得点テーブル>
id|得点
--------
1|100
2| 50
3| 70

SELECT id, (得点/MAX) AS 最大値との比率
FROM 得点テーブル, (SELECT MAX(得点) FROM 得点テーブル) AS 最大値

このSQLでは最終結果を出すときと、最大値を出すときで、
得点テーブルを2回フルスキャンしてる気がするのですが、
このSQLを効率化することってできないでしょうか?
755NAME IS NULL:2009/08/01(土) 12:41:15 ID:???
得点にインデックスが張ってあれば
SELECT MAX(得点) FROM 得点テーブル
の部分はフルテーブルスキャンにはならないだろ
756725:2009/08/01(土) 12:47:46 ID:iuklVi8s
まあそうなんですが、上のは簡単化した例えです。

実際は得点テーブルってテーブルは無くて、
得点テーブルの部分にはさらに副問い合わせが入ります。
こういう場合に、2回SELECTをしないで済む方法があれば教えて下さい。
757NAME IS NULL:2009/08/01(土) 13:04:39 ID:???
じゃあ
 select A.ID,
     A.得点 / max(B.得点)
 where 得点テーブル A
    cross join
    得点テーブル B
 group by A.ID,
      A.得点
とか?
こっちのほうが遅そうだけど
758725:2009/08/01(土) 13:14:36 ID:???
SELECT2回しなけりゃいいって問題じゃねえw
効率化したいんです。
759NAME IS NULL:2009/08/01(土) 13:21:18 ID:???
そりゃ情報小出しにしてりゃそうなるわな
760NAME IS NULL:2009/08/01(土) 13:21:20 ID:???
無い。
トリガを使って出入りを監視すれば。
761725:2009/08/01(土) 13:24:39 ID:???
『得点テーブル』は副問い合わせ結果なんだけど、
その副問い合わせが、中でさらに8回くらい副問い合わせしていて重い。
だから、2回同じことをやらずに済む方法があれば知りたいのです。
ちなみに、WITHは使えません。
762725:2009/08/01(土) 13:29:40 ID:???
>>760
どうもありがとう。
他のところでチューニングしてみます。
763NAME IS NULL:2009/08/01(土) 18:09:52 ID:???
SQLを見直すか、インデックスを見直すか、テーブルを再設計するか。
悩ましいね。
764NAME IS NULL:2009/08/01(土) 21:36:16 ID:qL1wMwr+
先輩方、質問させてください。
例えばこんなテーブルがあったとします。

  A  B  C
┌──┬──┬──┐
│  │身長│体重│
│佐藤│180 │ 80 │
│鈴木│170 │ 70 │


質問1
ABCの列はフィールドとカラムどっちが正しい呼び方?

質問2
Aのようなプライマリーな列は何と言うのですか?
765NAME IS NULL:2009/08/01(土) 21:51:56 ID:???
どっちが正しいっていうか
 カラムとロウ
 列と行
 フィールドとレコード
 属性とタプル
みたいに組み合わせを間違わなければ何でもいいかと。

リレーションの中でタプルを一意に識別できる属性または
属性の組み合わせは候補キーという。
候補キーの中でひとつを選んでプライマリキーとする。

ちなみに氏名じゃ一意性に欠けるから普通は候補キーにならない。
766764:2009/08/01(土) 22:00:55 ID:qL1wMwr+
>>765
なるほど。ありがとうございます。
カラム(列)
ロウ(行)
フィールド(属性)
レコード(タプル)ってことですよね?

質問2の答えは候補キーですか。英語でなんて言うんだろ?Candidate keyでいいのかな。
767NAME IS NULL:2009/08/02(日) 01:29:40 ID:???
氏名を候補キーにするのは通常しないって。
同姓の人なんていくらでもいるでしょ。
プライマリキーになれるのは、Nullじゃなく一意なカラムだけですよ。
768NAME IS NULL:2009/08/02(日) 01:54:48 ID:???
候補キーになるかどうか判断するんであって、「候補キーにする」もんじゃないね。
769764:2009/08/02(日) 03:54:10 ID:???
>>767
すみません。
都道府県や数値を書くべきでした。
ただの例なので一切つっこまれないと高を括っていましたが、甘かったです。
2chを舐めすぎていました。反省します。
770NAME IS NULL:2009/08/02(日) 14:41:21 ID:???
ちょっと舐めるくらいにしておけ
771NAME IS NULL:2009/08/02(日) 16:11:30 ID:???
例がおかしかったらつっこまれるのは2chに限った話じゃない
772NAME IS NULL:2009/08/02(日) 16:25:25 ID:???
ただまぁ、質問の前提情報が不足してるってのも、そこを勝手に判断して
思い込みで回答したり突っ込み入れたりするのも同じ穴の狢なんだよな。
>>764がもし全国の苗字毎の平均身長、体重の集計データとかだったら
何もおかしなことはない。
773NAME IS NULL:2009/08/02(日) 16:45:06 ID:???
そんな特殊例なんて無視するのが当然だろ。
何言ってんの?w
そんなデータ誰が欲しがるんだよ。
頭おかしいとしか思えないw
774NAME IS NULL:2009/08/02(日) 17:29:51 ID:???
そりゃ、>>772は単なる例だから。
ただ、分析や設計をする立場の人間なら、

>そんなデータ誰が欲しがるんだよ。

というように、書いてもいないことを思い込みで勝手に判断するのは
戒めるべきだってこと。
775NAME IS NULL:2009/08/02(日) 23:07:01 ID:???
違うだろ。
わけのわからない要求があがってきたら、それを客と話し合って相談する。
>>772みたいに勝手に想像をふくらませて「ありえないことないな」と判断するほうが危険だろ。
新入社員か?
776NAME IS NULL:2009/08/03(月) 00:04:48 ID:???
勝手に判断するなって書いてんのに、なんで「ありえないことないな」と判断したことになるんだよw
777NAME IS NULL:2009/08/03(月) 00:27:09 ID:???
>>773
ワインバーグは「奇跡はどこにでも存在する」と書いているが、同じような意味で
現実の案件はみんな特殊例と言ってもいいかもね。
778NAME IS NULL:2009/08/03(月) 02:13:02 ID:???
まあまあ。
きっとジンバブエのフリー家計簿ソフトが今も正しく動くのかについて考えないか
779NAME IS NULL:2009/08/03(月) 02:14:10 ID:???
いろいろ書いてる途中でKITTがのこってしまいました。
780710:2009/08/04(火) 17:14:06 ID:???
>>711-719
せっかくレスいただいたのにレス返していなくてすいません。
言いたかった事はAとBというビューをマージし、Cというビューを作ろうと思ったのですが
AとBで重複しているレコードがあり、それは片方だけCに持って行きたかったんです。
ただAとBで若干内容が違っている項目があるので、それは無視して
主キーのみで重複チェックをかけたかったのですが、その方法がわかりませんでした。
とりあえず教えていただいた式をよく見て試してみたいと思います。
本当に遅くなってしまいましたがありがとうございました。
781NAME IS NULL:2009/08/04(火) 17:16:55 ID:???
>>780
うん、それはみんな分かってる。
その上で、重複したときにどっち捨てるのかが分からなかったんだよ。
782NAME IS NULL:2009/08/04(火) 17:23:22 ID:???
自分ならビューをマージせず元テーブルをマージするが
783710:2009/08/04(火) 18:48:56 ID:???
早速サンプルを参考に試したら無事できました!
アドバイスありがとうございました。

>>781
すいませんホント言葉足らずで・・・。
どっちが残ってもいいかと思っていたので書いてませんでした。
>>782
確かに本当は余計なものは作りたくなかったのですが
特別な処理のINPUT用にビューが欲しくて別途作ろうとしていました。
784NAME IS NULL:2009/08/04(火) 19:53:10 ID:???
ただ単なる重複キーだけを知りたかったら

select
distinct 主キー
from tableA

union

select
distinct 主キー
from tableB

でいいじゃん・・・。
本当に他のデータがどうでもいいならね。
785NAME IS NULL:2009/08/04(火) 19:56:58 ID:???
それは何もかも違う
786NAME IS NULL:2009/08/04(火) 20:02:39 ID:???
ID HOGE
01 A
01 B
01 C
02 A
03 B

HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか
787NAME IS NULL:2009/08/04(火) 20:08:35 ID:???
DISTINCTしたのをCOUNTして3件のヤツとか
788NAME IS NULL:2009/08/04(火) 20:27:20 ID:???
groupするんじゃなくて?
789NAME IS NULL:2009/08/04(火) 20:44:09 ID:???
いやもちろんGROUPしてCOUNTだけど
先にDISTINCTしとかないとAABとかでも3件だしな。
そういうケースがあるかは知らんけど。
790NAME IS NULL:2009/08/04(火) 21:05:00 ID:???
>>786
hogeがA,B,Cの3種類のみでってことなら、
SELECT id FROM Table GROUP BY id HAVING count(DISTINCT hoge) = 3;

hogeが3種類以上あり、そのうちのA,B,Cを有するものなら、結合するしかないかな。
SELECT distinct id FROM
(SELECT * FROM Table WHERE hoge = 'A') AS T1
JOIN
(SELECT * FROM b_test WHERE hoge = 'B') AS T2
USING(id)
JOIN
(SELECT * FROM b_test WHERE hoge = 'C')AS T3
USING(id);
791NAME IS NULL:2009/08/04(火) 21:07:05 ID:???
やっぱ商演算テンプレに入れようぜ
これでどう?(標準SQLなのにOracleで動かないというオマケつきだけど)

select *
from TableName T1
where not exists (select *
         from (values 'A', 'B', 'C') T2 (HOGE)
         where not exists (select *
                  from TableName T3
                  where T1.ID = T3.ID
                  and T2.HOGE = T3.HOGE
                  )
         )
;
792790:2009/08/04(火) 21:07:30 ID:???
下段のSQL修正
SELECT distinct id FROM
(SELECT * FROM Table WHERE hoge = 'A') AS T1
JOIN
(SELECT * FROM Table WHERE hoge = 'B') AS T2
USING(id)
JOIN
(SELECT * FROM Table WHERE hoge = 'C')AS T3
USING(id);
793NAME IS NULL:2009/08/04(火) 21:16:37 ID:???
existsもjoinも汚いんだよな。
もう少しなんとかなりそうなんだが。
794790:2009/08/04(火) 21:21:56 ID:???
>>793
そういわれて、思いついたSQL
SELECT id FROM b_test WHERE hoge in ('A','B','C') GROUP BY id HAVING count(DISTINCT hoge) = 3;
795790:2009/08/04(火) 21:24:47 ID:???
あ、id=1でDも持っている可能性があるから、ABC"しか"じゃなくてABCを持っているなら
HAVING countDISTINCT hoge) >= 3;
ですね。
796NAME IS NULL:2009/08/04(火) 21:25:55 ID:???
WHERE hoge in ('A','B','C') と書いてるのに?
797790:2009/08/04(火) 21:27:45 ID:???
>>796
そうだった...orz

ついでに、>>791のSQLはPostgreSQLだと
SELECT DISTINCT id
FROM Table T1
WHERE NOT EXISTS (SELECT *
FROM (VALUES('A'), ('B'), ('C')) T2 (hoge)
WHERE NOT EXISTS (SELECT *
FROM Table T3
WHERE T1.id = T3.id
AND T2.hoge = T3.hoge
)
)
;
で動く。
798NAME IS NULL:2009/08/04(火) 21:31:46 ID:???
SQLパズルにヒント乗ってそうだが参照するのが死ぬほどめんどくさい。
799738:2009/08/04(火) 22:15:16 ID:???
ABCのどれかが欠けてるやつ以外という逆説手法でいけるのか。
質問主じゃないけど参考になった。
800NAME IS NULL:2009/08/04(火) 22:24:36 ID:???
逆説は考えてみたけどNOT A OR NOT B OR NOT Cじゃできなくて諦めたが、NOT EXISTSが正解だったんだな。
>>797にthx。
801NAME IS NULL:2009/08/04(火) 22:47:53 ID:JCPNsOCy
何が知りたいかと言えば、シルバーでダイタイ平均いくらかかりますか?
あとゴールドは?
802NAME IS NULL:2009/08/04(火) 22:54:44 ID:???
Oracleだと>>791
 from (values 'A', 'B', 'C') T2 (HOGE)
の部分は
 from (select 'A' as HOGE from dual
    union all
    select 'B' from dual
    union all
    select 'C' from dual
    ) T2
かな?
803786:2009/08/04(火) 23:03:33 ID:???
おお、予想以上の反響でびっくり
みなさんありがとう
hogeの指定は動的なんですわ
やっぱりwhere一発とかじゃ簡単にできないか
明日になっちゃうけど教わったやつ試してみる
804NAME IS NULL:2009/08/04(火) 23:06:35 ID:???
>>791はSQLServer2008でも動かないんだが。
805NAME IS NULL:2009/08/05(水) 04:07:48 ID:???
>>803
動的ってことは別テーブルに条件保存したら、その方が簡単な気が

select ID from (
select テーブル.ID,テーブル.HOGE from 条件 join テーブル on 条件.HOGE=テーブル.HOGE) as T
group by ID
having COUNT(*) = (select COUNT(*) from 条件)

テーブルの(ID,HOGE)がユニークならこれで行けるっぽ
806NAME IS NULL:2009/08/05(水) 04:33:07 ID:RB7uuMhx
PostgreSQL8.1 です。
シーケンスを含むDB を pg_restore したのですが、そのシーケンスに対する curval の取得が失敗します。
一度 nextval 等で値を取得すれば curval も取得できるようになるのですが、こういうものでしょうか?
CREATE SEQUENCE したばかりのシーケンスの curval が取得できないのと同じような感じです。
807NAME IS NULL:2009/08/05(水) 07:08:18 ID:???
>>805
検索の度にテーブル作り直すの?
808NAME IS NULL:2009/08/05(水) 09:31:08 ID:???
怪盗1412号を怪盗KIDと読むくらい無理があるな
809NAME IS NULL:2009/08/05(水) 12:15:15 ID:???
>>807
作り直すの意味するところが掴みかねるが
条件に対応するレコードをセットするわけで、テーブルそのものを作り直す必要はないが
たとえば条件がA,B,Cなら、条件テーブルにA,B,Cの3レコードセットしとく

810NAME IS NULL:2009/08/05(水) 12:34:14 ID:???
SELECT文を発行するたびにそれをやるのはなぁ。
811NAME IS NULL:2009/08/05(水) 13:00:14 ID:???
>>806
そういうもの。
812NAME IS NULL:2009/08/05(水) 13:00:51 ID:???
じゃあ条件に合わせて毎回SQL作り直すか?
813NAME IS NULL:2009/08/05(水) 15:03:36 ID:???
普通にSQL動的に作った方が楽じゃね?
814NAME IS NULL:2009/08/05(水) 16:25:58 ID:???
条件の個数が固定なら動的SQLでもいいかもしれん
条件の個数が変わるなら動的SQLのが大変じゃないかな

まあ、状況次第だな
815NAME IS NULL:2009/08/05(水) 16:36:28 ID:???
個数がどうであるかは大した問題ではないけれど
delete→insert(またはその逆)は大変面倒な気がする。
そんなことをするくらいなら一時テーブルを作る方が
よほどいいんじゃないかと思うのは俺だけ?
816NAME IS NULL:2009/08/08(土) 01:19:33 ID:???
Oracle 10g で質問です。

UPDATE文でテーブルの指定の列 (カラム)全てを
順番にAでアップデート、Bでアップデート、Cでアップデート
みたいに3パターンのアップデートを繰り返し
3000件あったとしたらAで1000件、Bで1000件、Cで1000件
見たいな感じにしたいのですが
どうすればよいでしょうか?

ご指導をお願い致します
817NAME IS NULL:2009/08/08(土) 02:57:48 ID:???
1000件ずつにきちんと分けれたらいけるだろ。
テーブルの構成を書かないならこれ以上はアドバイスできない。
818NAME IS NULL:2009/08/08(土) 13:29:50 ID:???
ROWNUM
819NAME IS NULL:2009/08/08(土) 15:53:09 ID:ZMe9F3VY
SQLITEでテーブルに入ってる列の名前を表示させるSQL文を教えてください
820NAME IS NULL:2009/08/08(土) 16:19:47 ID:???
.help にヒントがあるようにおもう >> 819
821NAME IS NULL:2009/08/08(土) 20:32:43 ID:???
>>817-818
説明不足スミマセン

ROWNUMで解決しました

ありがとうございました
822NAME IS NULL:2009/08/09(日) 18:28:23 ID:???
MySQL 5

テーブル
data1 data2 data3
a あ 100
b あ 150
c あ 130
d あ 190
b い 120
c い 180
a い 160
d い 110
c う 140
b う 115
d う 125
a う 155


欲しい結果

あ い う
a 100 160 155
b 150 120 115
c 130 180 140
d 190 110 125

こういうのってSQLで出来るのでしょうか?
823NAME IS NULL:2009/08/09(日) 18:58:03 ID:???
3列固定なら簡単にできる。
動的なら難しい。
824NAME IS NULL:2009/08/09(日) 19:03:26 ID:???
>>823
> 3列固定なら簡単にできる。
> 動的なら難しい。
>

レスどうもです
列は固定です
825NAME IS NULL:2009/08/09(日) 23:41:30 ID:???
>>822
data1、data2の組み合わせでユニークになるのなら

select
data1,
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'あ') as "あ",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'い') as "い",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'う') as "う"
from テーブル t
group by data1

826NAME IS NULL:2009/08/10(月) 00:18:48 ID:???
3列固定で、かつ
あ い う
a 100 160 155
b 150 120 115
c 130 180 140
d 190 110 125
みたいな取得をしたいんだったらテーブルの作りを変えるのも考慮してみては
827NAME IS NULL:2009/08/10(月) 08:17:00 ID:???
>>826
ありがとうございます

テーブルの構造を作り変えることも検討したいと思います
828827:2009/08/10(月) 22:29:14 ID:???
select
data1,
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'あ') as "あ",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'い') as "い",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'う') as "う"
from テーブル t1
group by data1

Subquery returns more than 1 row
となるのですがどうしてでしょうか・・・

select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'あ'
は、このSELECT文で欲しい値が返ってくることは確認しました

select data3 from テーブル t1 where t.data1 = 't1.data1' and t1,data2 = 'あ'
と t1.data1 にシングルクォートを付けると処理は正常終了しますが
当然ですが、結果は data3 は NULL が返されてしまいます

教えていただいた SQL に間違いはないと思うのですが
何が悪いのか教えていただけないでしょうか
829NAME IS NULL:2009/08/10(月) 22:39:04 ID:???
>>828
3つのサブクエリの最後、
and t1(カンマ)data2 = 'あ'
になってる。
830NAME IS NULL:2009/08/10(月) 22:39:15 ID:???
どっちも t1?
831NAME IS NULL:2009/08/10(月) 22:50:33 ID:???
読んだ通りのエラーだよ。
select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'あ'
select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'い'
select data3 from テーブル t1 where t.data1 = t1.data1 and t1,data2 = 'う'
この3つのSQLのいずれかが複数件の結果を返してしまっているということ。
832NAME IS NULL:2009/08/10(月) 22:51:47 ID:???
構文エラーにならないんだねえ。
where句のカンマ演算子ってどういう扱い?
833827:2009/08/10(月) 22:55:04 ID:???
>>829
select
data1,
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1.data2 = 'あ') as "あ",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1.data2 = 'い') as "い",
(select data3 from テーブル t1 where t.data1 = t1.data1 and t1.data2 = 'う') as "う"
from テーブル t1
group by data1

結果変化ありませんです

>>830
>>822 に書いたとおり全てのデータがひとつのテーブル内に記述されてるんです
834NAME IS NULL:2009/08/10(月) 22:56:06 ID:???
mysql5でできるかはわからんが
MSSQLの解

SELECT data1 as 'data1',[あ],[い],[う]
FROM
(SELECT data3,data1,data2 FROM Table1) AS SourceTable
PIVOT
(
MIN(data3) FOR data2 IN ([あ],[い],[う]))AS PivotTable
835NAME IS NULL:2009/08/10(月) 22:57:21 ID:???
>>825が間違ってるね。まぁすぐ気づきそうだけど、俺も828で気づかなかったしw

正しくはこうか。
select
data1,
(select data3 from テーブル t2 where t2.data1 = t1.data1 and t2.data2 = 'あ') as "あ",
(select data3 from テーブル t3 where t3.data1 = t1.data1 and t3.data2 = 'い') as "い",
(select data3 from テーブル t4 where t4.data1 = t1.data1 and t4.data2 = 'う') as "う"
from テーブル t1
group by data1;


別解。
SELECT T0.data1 AS T0 ,T1.data3 AS あ ,T2.data3 AS い ,T1.data3 AS う FROM
(SELECT data1 FROM テーブル GROUP BY data1) AS T0
LEFT JOIN
(SELECT * FROM テーブル WHERE data2 = 'あ') AS T1 ON T0.data1 = T1.data1
FULL JOIN
(SELECT * FROM テーブル WHERE data2 = 'い') AS T2 ON T0.data1 = T2.data1
FULL JOIN
(SELECT * FROM テーブル WHERE data2 = 'う') AS T3 ON T0.data1 = T3.data1;
836835:2009/08/10(月) 23:00:44 ID:???
俺も間違ってる。
別解の1行目。
×SELECT T0.data1 AS T0 ,T1.data3 AS あ ,T2.data3 AS い ,T1.data3 AS う FROM
○SELECT T0.data1 AS T0 ,T1.data3 AS あ ,T2.data3 AS い ,T3.data3 AS う FROM
837NAME IS NULL:2009/08/10(月) 23:02:23 ID:???
ちゃんと実行してから書け
838827:2009/08/10(月) 23:08:43 ID:???
みなさん ありがとうございました!
できました

感謝します
勉強しないといけないです・・・ orz
839NAME IS NULL:2009/08/11(火) 15:37:39 ID:pDd9m9X6
今月の誕生日の人の検索はどうすれば良いでしょうか?
誕生日はYYYY-MM-DDの形式で保存されております

%08%や____08__などやってみてもだめでした。
840NAME IS NULL:2009/08/11(火) 15:40:23 ID:???
どのDBMSでも月を取得できる関数が何かしら用意されてるはず
841NAME IS NULL:2009/08/11(火) 15:41:43 ID:???
もし無ければ文字列に変換して比較
842839:2009/08/11(火) 16:00:33 ID:???
ありがとうございます。
843NAME IS NULL:2009/08/11(火) 20:23:39 ID:???
MySQL 5.1.37 Windows
MySQLで勉強している最中なんですけど、教えてください
select now();で
2009-08-11
select extract(year_month from now());で
200908
が返ってくるのはいいんですけど、そこに01を連結して
20090801が返ってきて欲しくて
select concat(extract(year_month from now()),01)とすると
2009081になってしまいます。
20090801にしたいのですが、どうすればいいのでしょうか
844NAME IS NULL:2009/08/11(火) 20:34:06 ID:???
>>843
クォーテーションで括ればよくね。
select concat(extract(year_month from now()),'01');
他、
SELECT DATE_FORMAT(CURRENT_DATE,'%Y-%m-01');
845843:2009/08/11(火) 20:40:19 ID:???
>>844
ありがとうです!
846703:2009/08/12(水) 12:36:16 ID:???
>>708
今更ですが、無事動きました。
この記述はSQLiteオンリーなのでしょうか?
847NAME IS NULL:2009/08/12(水) 12:40:13 ID:???
Select句にhashがあんのにGroupBy句にないから普通ならエラーだな。
848NAME IS NULL:2009/08/12(水) 13:28:49 ID:???
「ありがとうございました」と言え
849NAME IS NULL:2009/08/12(水) 14:18:21 ID:???
あー、あざーす
850NAME IS NULL:2009/08/12(水) 17:32:23 ID:???
DBMS名: PostgreSQL 8.3系

データ
id | date    | memo
---+------------+------
1 | 2009-12-22 | test1
2 | 2009-12-23 | test2
3 | 2009-12-24 | test3
4 | 2009-12-24 | test4
5 | 2009-12-25 | test5

test1があったらこれ
id | date    | memo
---+------------+------
1 | 2009-12-22 | test1

test2があったらこれ
id | date    | memo
---+------------+------
2 | 2009-12-23 | test2

test3があったらこれ
id | date    | memo
---+------------+------
3 | 2009-12-24 | test3

上記のテーブルより
一度に"test1"、"test2"、"test3"の条件を指定してデータを抽出する際、
どれか1パターンのみのデータを抽出したいのですが
可能でしょうか?
851NAME IS NULL:2009/08/12(水) 17:38:53 ID:???
優先順位とか関係ないなら、in ('test1', 'test2', 'test3') で、TOP 1。

PostgreSQL で使えるか知らんけど。
852NAME IS NULL:2009/08/12(水) 17:44:55 ID:???
rder by memo = 'test3', memo='test2', memo='test1' limit 1

とか、、苦しいか
853NAME IS NULL:2009/08/12(水) 21:22:44 ID:???
本当に test1, 2, 3 の優先順位ならば ORDER BY memo LIMIT 1 だけでいけそう。
もっと複雑ならば ORDER BY CASE memo CASE 'test1' THEN 1 CASE 'test2' THEN 2 ... END LIMIT 1 とか。
854NAME IS NULL:2009/08/13(木) 11:53:03 ID:???
一応、こんな感じでまとめた。

select
*
from
table1
where
memo = 'test1'

union all

select
*
from
table1
where
memo = 'test2'
and (select count(*) from table1 where memo = 'test1') <= 0

union all

select
*
from
table1
where
memo = 'test3'
and (select count(*) from table1 where memo = 'test1') <= 0
and (select count(*) from table1 where memo = 'test2') <= 0

相当おかしい感じがするのは気のせいと思っている
855NAME IS NULL:2009/08/13(木) 12:20:18 ID:???
気のせいじゃないよ。
856NAME IS NULL:2009/08/14(金) 04:10:04 ID:???
Oracle10gで
○○都○○市〜〜
○○○県○○市〜〜
のように住所が入っているaddress列から
都道府県名だけを抽出したい場合
どんな文を書けばいいんでしょうか
857NAME IS NULL:2009/08/14(金) 04:40:48 ID:???
それはSQLの仕事じゃ無いような・・・
858NAME IS NULL:2009/08/14(金) 04:51:58 ID:???
REGEXP_SUBSTRでもつかえば?
859NAME IS NULL:2009/08/14(金) 04:54:03 ID:???
簡単なのは正規表現を使って、
REGEXP_REPLACE(address,'^(...*?(都|道|府|県)).*$','\1')
かなあ・・・パフォーマンス悪いだろうなあ
860NAME IS NULL:2009/08/14(金) 04:59:27 ID:???
頻繁に発生するなら都道府県マスタ作って前方一致で結合して…とかがいいかも
861NAME IS NULL:2009/08/14(金) 05:10:08 ID:???
>>859
それだと京都府が...
PostgreSQL用だけど、要は正規表現で関数は書き直して。
SELECT substring(address , '^(.*?(東京都|道|府|県))') FROM Table;

>>860
前方一致で1行ごとに47都道府県と比較するのと正規表現とどちらが速いだろうな。
862NAME IS NULL:2009/08/14(金) 05:13:05 ID:???
'京都府'はいけるように作ったぞ
全部の都道府県をテストしたわけじゃないが
863NAME IS NULL:2009/08/14(金) 05:27:42 ID:???
>>862
スマソ ...*? 頭の..を見逃していた。
864NAME IS NULL:2009/08/14(金) 05:45:19 ID:???
抽出はREGEXP_SUBSTRを使えばいいのか・・・
勉強になるわあw
865NAME IS NULL:2009/08/14(金) 14:39:48 ID:???
というか都道府県なんて50も無いんだから手で抽出(というか記述?)した方が早くね?
866NAME IS NULL:2009/08/14(金) 14:43:10 ID:???
>都道府県なんて50も無い
それは856の抽出結果が50しかないということを意味する訳ではないし
何度もやるかもしれない
867NAME IS NULL:2009/08/14(金) 15:12:58 ID:???
都道府県とは書いてあるが、市区町村まで分けようとしてるんじゃないの?
868NAME IS NULL:2009/08/14(金) 23:59:57 ID:TqQmlfGr
カラム
a char (4) not null
b decimal(4) not null
がある場合、
条件句で
'2000' < a

2000 < b
はどちらが速いでしょうか?
(データとインデックスは同じ)
869NAME IS NULL:2009/08/15(土) 00:23:04 ID:???
後者の方が速いでしょ。
870NAME IS NULL:2009/08/15(土) 01:12:06 ID:???
aにインデックスがある
bにインデックスがある
の2つを比べるなら一緒でしょ
871NAME IS NULL:2009/08/15(土) 15:55:43 ID:c8dfsvTH

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 前回の衆院選の投票率は
  小選挙区が67.51%
  比例代表が67.46%

 次の衆院選は

   めざせ投票率72%!

 ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ∧_∧   ∧_∧    age
 (・∀・∩)(∩・∀・)    age
 (つ  丿 (   ⊂) age
  ( ヽノ   ヽ/  )   age
  し(_)   (_)J

◆◆◆投票率ageageブラザーズ◆◆◆

872NAME IS NULL:2009/08/17(月) 14:38:36 ID:???
72.1%じゃあかんの
873NAME IS NULL:2009/08/19(水) 21:04:19 ID:???
DBMS名: PostgreSQL 8.3系

データ
key1|key2 | date   
---+------+------------
0001|001 | 2009-12-22
0001|002 | 2009-12-24
0001|003 | 2009-12-24
0002|001 | 2009-12-24
0002|002 | 2009-12-25

上記より
key1|key2 | date   
---+------+------------
0001|001 | 2009-12-22
0002|001 | 2009-12-24

key1とkey2でユニークなキーになりますが
key1のキー単位に1件ずつ抽出したいのですが?

874NAME IS NULL:2009/08/19(水) 21:09:19 ID:???
key1 は group by で求めるとして、key2 はどういう基準なの?
875NAME IS NULL:2009/08/19(水) 21:23:27 ID:???
key2、dateはkey1に紐づくデータで特に指定はないです
876NAME IS NULL:2009/08/19(水) 21:30:34 ID:???
そんじゃ、>>4 でいいだろ。
877NAME IS NULL:2009/08/19(水) 22:21:00 ID:???
すみません。すっかり忘れてました。
ありがとうございます。
878NAME IS NULL:2009/08/19(水) 22:24:40 ID:???
>>873
PostgreSQLならDISTINCT ONで

SELECT DISTINCT ON (key1) * FROM Table;
普通ORDER BYと組み合わせるがな。
879NAME IS NULL:2009/08/21(金) 01:37:47 ID:xrxomkXj
テーブルabc( id , create_date , flag )に1万件のデータが存在します。
create_dateでソートした先頭の千件以外にflag=1をセットするにはどうすれば良いでしょうか。
副問い合わせ使って1度にやりたいのですが上手くできません。
データベースはPostgreSQL(8.3)です。

update abc set flag=1 where id = (select id from abc order by create_date desc limit 1000);

〜以外というのができれば良いのですが・・・
880NAME IS NULL:2009/08/21(金) 01:39:09 ID:???
ポスグレさわったことないけどNOT EXISTS
881NAME IS NULL:2009/08/21(金) 01:45:55 ID:xrxomkXj
>>880
おぉ、こんな便利なものが。やってみます!
882NAME IS NULL:2009/08/21(金) 03:18:54 ID:xrxomkXj
Postgresqlの場合はNOT EXISTSではなくてNOT INでした。

update abc set flag=1 where id not in (select id from abc order by create_date desc limit 1000);

上で行けました!
883NAME IS NULL:2009/08/21(金) 03:28:06 ID:xrxomkXj
>>880
おかげでホームページの更新出来ました!
abでパフォーマンス計ったらSQL修正前の4倍早くなった!ちょー嬉しいっす!!
ありがとうございました。

http://www.tarikin.net/
884NAME IS NULL:2009/08/21(金) 11:18:57 ID:???
PostgreSQLにはNOT INもNOT EXISTSもあるよ
NOT INでパフォーマンスが問題になったらNOT EXISTSに置き換えるのが手っ取り早い
885NAME IS NULL:2009/08/21(金) 19:54:25 ID:???
DB初心者です。すごく初歩的な質問かもしれませんがよろしくお願いします。

■以下環境
・DBMS:SQL Server2005 Express & Management Studio
・テーブルのある列には、数字+文字(例.1日目、2日目、5日目)などの
 値が格納されています。
・欲しい結果:数字+文字の[数字部分]のみをビューの列に格納したいと
       考えています。

■質問
ビューの指定列に関数などを使用して数字のみ取り出すことは可能でしょうか?
無理な場合、どのようなSQL構文を書けば実現可能でしょうか?

886NAME IS NULL:2009/08/21(金) 20:02:11 ID:???
replaceで'日目'を''に、とか。
887NAME IS NULL:2009/08/21(金) 20:24:18 ID:???
>886
replace(指定列,'日目','')で、できました!

とりだした部分を使って数値計算がしたく、
文字部分が邪魔でどうすればいいか悩んでいたのですが、
すっきりしました!

ありがとうございます!
888NAME IS NULL:2009/08/21(金) 20:51:18 ID:???
どういう使い方してるかわからんからアレだけど
一般的にはテーブルに「日目」を付けない状態で格納する。
889NAME IS NULL:2009/08/21(金) 21:16:48 ID:???
金額に「円」つけて格納してたりして
890NAME IS NULL:2009/08/21(金) 21:34:13 ID:???
格納は別の人がやってるor既存データ
とかなんでないの?
よくあること。
891885:2009/08/21(金) 23:23:50 ID:???
>890

おっしゃるとおりです。
別のアプリケーションでデータをテーブルへ格納するので、
そこからビューを作って特定の列どうしを計算したりするつもりでした。
892NAME IS NULL:2009/08/22(土) 00:17:21 ID:???
テーブルの中身をさっさと修正した方が今後の為に良いように思うけどなぁ
893NAME IS NULL:2009/08/23(日) 14:37:25 ID:???
|   A   |   B  |   C   |
――――――――
|   1   |   1  |   a   |
|   1   |   2  |   b   |
|   1   |   3  |   c   |
|   2   |   1  |   c   |
|   2   |   2  |   b   |
|   2   |   3  |   a   |
|   2   |   4  |   c   |
|   3   |   1  |   b   |
|   3   |   2  |   a   |
|   3   |   3  |   c   |

こういう時に
Cの値を複数指定してそれがBで指定した順に連番になっているときだけAを抽出する
というSQL文って書けますでしょうか?

複数しているCの値を cb とした場合
抽出されるのは2だけとなります
894NAME IS NULL:2009/08/23(日) 15:06:36 ID:???
select T1.A
from TableName T1
   inner join
   TableName T2
   on T1.A = T2.A
where T1.C = 'c'
and  T2.C = 'b'
and  T1.B = T2.B - 1
;
とか?
895893:2009/08/23(日) 16:03:22 ID:???
>>894
うまく行きました
本当にありがとうございます

重ねて質問で申し訳ないのですが

現在A,B,C各々にインデックスは張っています
さらに高速化が望めるインデックスの張り方ってありますでしょうか?
896NAME IS NULL:2009/08/23(日) 16:07:38 ID:???
>>893
cbで指定したときはA=2ではなくてA=1じゃないのか?
897NAME IS NULL:2009/08/23(日) 16:10:47 ID:???
俺なら

A | C
-----
1 | abc
2 | cba
3 | bac

ってテーブルにする。
898NAME IS NULL:2009/08/23(日) 16:11:51 ID:???
もうカラムCを横に繋げて持っちゃえよ
899NAME IS NULL:2009/08/23(日) 16:12:50 ID:???
ああスマンかぶった
900NAME IS NULL:2009/08/23(日) 16:17:58 ID:???
>>895
create index IndexName on TableName (C, B, A);
かな?
やってみんとわからんが
901NAME IS NULL:2009/08/23(日) 16:23:22 ID:???
>>894の例だとCの値の数だけSQL作らないといけないな。
動的SQLでもいいが。
902NAME IS NULL:2009/08/23(日) 16:32:31 ID:???
>>896-901
いろいろ議論ありがとうございます.

最近まで横に繋げて持ってたんですが,
あまりにも文量が多かったのでSELECTしても
HDDIOが遅いせいでかなり時間がかかっていました

それでなんとか早くする方法がないかと試行錯誤しているところです

>>900
インデックスはってみます
903NAME IS NULL:2009/08/23(日) 16:35:46 ID:???
時間がかかるとか、不都合な部分を自分以外に原因を持って行くのは楽だよなあ
904NAME IS NULL:2009/08/23(日) 16:44:44 ID:???
>903
気を悪くさせたなら申し訳ありません

select Table.A from Table where match(C) against('cb');

というクエリを実行してUPU使用率はほとんど上がらないまま
一定時間後に値が返ってきたので
HDDIOによるタイムロスと思ってたのですが
他に原因がありそうでしょうか?

いまさらですがMySQLで
メモリは2GBのPCでmysqldに1Gほど割り当てられています
905 [―{}@{}@{}-] NAME IS NULL:2009/08/23(日) 22:14:06 ID:???
A B C1 C2
1 1 a b
1 2 b c
2 1 c b
2 2 b a
2 3 a c
3 1 b a
3 2 a c

「ac」を探すときは、where c1='a' and c2='c'

「abc」を探すときは、
select T1.A
from Table T1 LEFT JOIN Table t2 ON t1.A=t2.A and t1.A=t2.B-1
where T1.c1='a' and T1.c2='b' and T2.c2='c'

「cbac」を探すときは、
select T1.A
from Table T1 LEFT JOIN Table t2 ON t1.A=t2.A and t1.A=t2.B-2
where T1.c1='c' and T1.c2='b' and T2.c1='a' and T2.c2='c'
906NAME IS NULL:2009/08/23(日) 22:34:38 ID:???
そんなテーブルどうやってメンテするんだよ
まあもともとのテーブルも似たようなもんだが
907NAME IS NULL:2009/08/23(日) 22:51:16 ID:???
列名はA、B、Cとかじゃないんだろうけど、
もうちょっと相関性のあるデータの入れ方を力説した方が良かったんじゃないかな〜
908NAME IS NULL:2009/08/24(月) 07:10:01 ID:TouBA/nc
SQLiteを使っています。(質問としてはSQL一般です)

趣味のDB設計中に、テーブルとかカラムの構成の仕様がどんどん変わっていくような場合
データの追加・修正・削除を簡単に行う方法はないでしょうか。

GUIのDB操作ツール(PupSQLite等)を使うのが一見よさそうですが、
内部インデックス(ユーザからは見えない)の整合性を取りながら追加・修正・削除を行うのはなかなか面倒です。

トリガーを使って整合性を取り、GUIツールでデータ編集する方法もありますが、
もっと直感的な方法はないでしょうか。
(複数のテーブルの同種のインデックスを関連付けるなどして、簡単にデータ編集できるツールなどないでしょうか)

DB初心者のため、的外れな質問かもしれません。
より適切なスレッドがあれば誘導してください。
よろしくお願いいたします。
909NAME IS NULL:2009/08/24(月) 07:33:00 ID:???
インデックスと言っているのは外部キーの事だよね?
Accessで連鎖更新・削除が出来た気がする。
つかここはSQL文のスレだからツールとかはスレ違い。
910908:2009/08/24(月) 08:08:48 ID:???
>インデックスと言っているのは外部キーの事だよね?
はい。SQL用語のインデックスのことではないです。
(SQL用語に"インデックス"があるのを今調べて知りました)
紛らわしくてすみません。

"外部キー"も理解が曖昧で、全く設定していなかったのですが
便利そうなので使ってみます。

>Accessで連鎖更新・削除が出来た気がする。
考えていたことに近いです。
>つかここはSQL文のスレだからツールとかはスレ違い。
やはりツールに依存する機能なんですね。すみません。
911NAME IS NULL:2009/08/24(月) 08:54:31 ID:???
初歩的な質問、すいません MySQLです。

日付の入っている列 input_date があります
input_date
--------
2008-12-11
2008-12-15
2009-04-05
2009-04-08
2009-05-10
2009-05-15
2009-07-01
2009-07-05


ここから例えば 2009年4月のデータのみを extract関数で取り出す事って出来ますか?
月初と月末を指定すれば between や <、>を使って出来るのは判るのですが。

912NAME IS NULL:2009/08/24(月) 09:11:12 ID:???
>>839-843あたり
913NAME IS NULL:2009/08/24(月) 09:15:15 ID:???
>>912
thxです
914NAME IS NULL:2009/08/24(月) 21:33:10 ID:???
質問です。
下記のようなデータがあり、

顧客テーブル
顧客番号 連番 フラグ
00000001 001  0
00000001 002  0 ←
00000002 001  0 ←
00000003 001  0
00000003 002  0 ←
00000004 001  0 ←

各顧客の最大の連番レコード(←)のみフラグを'1'に更新したいのですが、
そのSQLに悩んでいます。

SELECT 顧客番号, MAX(連番) FROM 顧客テーブル GROUP BY 顧客番号

この結果を上手くUPDATE文に絡めたいのですが……
Oracle8iです。よろしくお願いします。
915NAME IS NULL:2009/08/24(月) 21:42:44 ID:???
適当に書いたから、動かないかもしれん

update 顧客テーブル set
フラグ = 1
where
顧客テーブル.連番 = (
select MAX(T.連番) from 顧客テーブル T
顧客テーブル.顧客番号 = T.顧客番号
)

916NAME IS NULL:2009/08/24(月) 21:44:37 ID:???
row_numberが1のものを更新する
917NAME IS NULL:2009/08/24(月) 21:48:22 ID:???
>>914
in句を使って絡めてみた。

update 顧客テーブル set フラグ='1'
where (顧客番号, 連番) in (SELECT 顧客番号, MAX(連番) FROM 顧客テーブル GROUP BY 顧客番号)

どうすか?
918914:2009/08/24(月) 21:57:31 ID:???
>>915
>>917
早速試してみましたところ、いずれの方法でも求める結果が得られました!
みなさんありがとうございました。
919916:2009/08/24(月) 21:58:57 ID:???
シカトかよ
920NAME IS NULL:2009/08/24(月) 22:00:18 ID:???



ぷっ



921NAME IS NULL:2009/08/24(月) 22:24:03 ID:???
row_numberって、where句に直接使えるんだっけか?
select句にしか使えないんだったら、maxの方が簡単だべ。
個人的には相関サブクエリを薦めるけども。
922NAME IS NULL:2009/08/26(水) 01:12:53 ID:K0v/cQev
select id,(Case when status in ('SWAP','SWAPT') then SUBID else (SUBID*(PRICE/100)) end)::NUMERIC(38,8)
ここで、(Case when ....)::NUMERIC(38,8)というのは何をやっているのでしょうか?
()の中のCASE文の内容をNUMERICに変換しているのでしょうか?
よろしくお願いします。
923NAME IS NULL:2009/08/26(水) 01:26:25 ID:???
>>922
CASE文の結果(出力)をNUMERIC(38,8)にキャストですね。
キャスト演算子"::"はPostgreSQLの方言だと思っていたけど、
他にも使えるのかな?
924NAME IS NULL:2009/08/26(水) 01:29:38 ID:K0v/cQev
ありがとうございます。PostgreSQL派生のDBからの質問でした。
オラクルではできない書き方なのですね。
925NAME IS NULL:2009/08/26(水) 03:52:24 ID:K0v/cQev
すいません、もうひとつだけ。
SELECT 'my name'::"NAME";
とやると、
my name
と表示されるのですが、これはいったいなにをやっているのでしょうか?
926NAME IS NULL:2009/08/26(水) 06:10:51 ID:???
>>925
それはしらんw
ひょっとして
SELECT 'my name' AS "NAME";
じゃなかろうか?

PostgreSQL派生(PowerGres?)で依存ぽいから
PostgreSQL Part.6
http://pc11.2ch.net/test/read.cgi/db/1224318817/
でどぞー。
927NAME IS NULL:2009/08/26(水) 08:44:37 ID:???
DB2なんだけど、

品名、日付、数量
A、2009-01、1000
A、2009-02、2000
A、2009-03、3000
B、2009-02、1000

こんなテーブルがあって、下記のような結果を得たい場合は
どんなSQLが考えられますか?

品名、2009-01数量、2009-02数量、2009-03数量
A、  1000、     2000、      3000
B、  NULL、     1000、      NULL

928NAME IS NULL:2009/08/26(水) 11:35:59 ID:???
最初のテーブルとほとんど変わってないように見えるけど。
NULLも出したいということ?
929NAME IS NULL:2009/08/26(水) 18:26:16 ID:???
勉強中のど素人ですが、強引にやってみたw
こういうのスマートになかなか出来ないなあ

SELECT 品名, t1.数量 "2009-01数量", t2.数量 "2009-02数量", t3.数量 "2009-03数量"
FROM (SELECT * FROM tablename WHERE 日付 = '2009-01-01') t1
FULL OUJTER JOIN (SELECT * FROM tablename WHERE 日付 = '2009-02-01') t2 USING(品名,)
FULL OUJTER JOIN (SELECT * FROM tablename WHERE 日付 = '2009-03-01') t3 USING(品名,)
930NAME IS NULL:2009/08/26(水) 19:01:28 ID:???
select 品名,
sum(case when 日付 = '2009-01' then 数量 end) as "2009-01数量",
sum(case when 日付 = '2009-02' then 数量 end) as "2009-02数量",
sum(case when 日付 = '2009-03' then 数量 end) as "2009-03数量"
from TableName
group by 品名
;
931930:2009/08/26(水) 19:05:45 ID:???
てか>>5そのままだた
932NAME IS NULL:2009/08/26(水) 19:21:07 ID:???
ほんとだw
933NAME IS NULL:2009/08/26(水) 19:31:18 ID:???
つか文法間違えてない?w
日付もTO_DATEがいりそうな
934NAME IS NULL:2009/08/26(水) 19:48:54 ID:???
            /)
           ///)
          /,.=゙''"/
   /     i f ,.r='"-‐'つ____   こまけぇこたぁいいんだよ!!
  /      /   _,.-‐'~/⌒  ⌒\
    /   ,i   ,二ニ⊃( ●). (●)\
   /    ノ    il゙フ::::::⌒(__人__)⌒::::: \
      ,イ「ト、  ,!,!|     |r┬-|     |
     / iトヾヽ_/ィ"\      `ー'´     /
935NAME IS NULL:2009/08/26(水) 23:18:39 ID:cAgACWNL
(Mysql5.0での実行を予定しております。)

enginテーブル(検索エンジンのドメインと、検索ワードの項目名が格納されている)
----------------
エンジン  | id |
----------------
google.com | q |
yahoo.co.jp| p |


URLテーブル
-----------------------------
  url  | search |
-----------------------------
google.com?q=aaaa |    |
yahoo.co.jp?p=bb  |    |
google.com?q=c&u=1 |    |
   ・
   ・
   ・

SQL1発で「URLテーブルのsearch列に対応したidの文字を入れ、下記のような状態にしたいです。」
副問い合わせやGROUPBY句などを組み合わせたりして色々考えましたが、解決策が見当たりません。
お分かりになられる方が居られましたらご教授よろしくお願いいたします。


------------------------------
   url      | search |
------------------------------
google.com?q=aaaa  | aaaa  |
yahoo.co.jp?p=bb   |  bb  |
google.com?q=c&u=1 |  c  |
    ・
    ・
    ・

936NAME IS NULL:2009/08/26(水) 23:27:46 ID:???
>>934
TRUNCATE
937NAME IS NULL:2009/08/27(木) 01:19:25 ID:???
>>935
最後のパターン以外はとれた
確認はSQLiteだけど、MySQLでも多分いけるんじゃない

select d1.url, substr(d1.url, length(v.engine)+1) as search
from URLテーブル d1
cross join (
select d2.engine || '?' || d2.id || '=%' as engine from エンジンテーブル d2
) v
where
d1.url like v.engine;
938NAME IS NULL:2009/08/27(木) 01:41:57 ID:???
またまた度素人が(ry
最後の状態を見る限りだと、
最初の'='の後の文字列をsearch列に入れる、
'='のすぐ後の2文字が'c&'ならsearch列に'c'を入れる、
てことでいいのかな?

URLテーブルにナンバリングしたUNIQUEキーをつくって、
相関副問い合わせで、とか^^;


update URLテーブル "URLt1" set serach =
     (select case substr(url, instr(url,'=')+1,2)
         when 'c&' then 'c'
         else substr(url,instr(url,'=')+1)
          end
     from URLテーブル "URLt2" where URLt1.no = URLt2.no);

お門違いの回答ならすいませぬ。
939NAME IS NULL:2009/08/27(木) 02:04:55 ID:???
pやqが?直後に来るとは限らないし、=以後は&か文末が現れるまででしょ。
正規表現で書くなら engineテーブルのidをIDと書くけど。
[\?&]ID=([^&$]*?)
かな。MySQLの文字列連結だとconcat('[\?&]' , id , '([^&$]*?)') な具合だろうけど、
MySQLがどこまで正規表現に対応しているのかしらね。
実際はホスト言語側でURLテーブルに挿入する時点で処理(search分離)しておくべきでしょうね。
940NAME IS NULL:2009/08/27(木) 06:17:03 ID:0vbJ9O4e
>>937-939
>pやqが?直後に来るとは限らないし、目的の項目(例えばq=aaa)以後は&か文末が現れるまででしょ。
おっしゃる通りです。説明不足ですみませんでした。

昨夜まで「あれ?これ無理なんじゃない?」と思ってたんですが
皆様のご提示内容を参考にすると出来そうな感じになってきました。
ありがとうございます!
今日一日空き時間使って悩んでみます!
941939:2009/08/27(木) 06:34:02 ID:???
正規表現間違えていたので、一応訂正しておく。
× [\?&]ID=([^&$]*?)
○ [\?&]ID=([^&$]*)
○ [\?&]ID=(.*?)(&|$)
こんな感じかな。テストしていないけど。
942927:2009/08/27(木) 15:22:35 ID:???
>929,930

ありがと、解決しました。
943935:2009/08/30(日) 13:27:40 ID:IiFjmKoL
>>935です。
すみません、色々試してはみたのですが、なかなかうまくいかず、まだ完成していません。
というのも、肝心のsearch列に値を設定する部分がわからないのです。

例えば、(下記テーブルの例で言うと)
url列の値がgoogle.comの情報ならsearch列にbbbやaaa(q=の後の値)を格納するということがしたいのですが、
「下記SQLの????の部分にbbbとかaaaとかを持ってくる方法」
がわかりません。

  UPDATE URLテーブル SET search = ???? where url LIKE '%google.com%'

低レベルな質問ですみませんが、お分かりになられる方がおられましたら
ご教授よろしくお願いいたします。


  (pやqが?直後に来るとは限らないし、目的の項目(例えばq=aaa)以後に&が続く場合もある)
URLテーブル
-----------------------------------------
       url      | search |
-----------------------------------------
google.com?q=bbb       |    |
google.com?q=aaa&u=1     |    |
google.com?u=1&q=ccc&u=1   |    |
yahoo.co.jp?p=bbb       |    |
yahoo.co.jp?p=ccc&d=fff    |    |
yahoo.co.jp?g=x&p=ttt&t=g   |    |



※こんな風に更新したい。
-----------------------------------------
       url      | search |
-----------------------------------------
google.com?q=bbb       | bbb |
google.com?q=aaa&u=1     | aaa |
google.com?u=1&q=ccc&u=1   | ccc |
yahoo.co.jp?p=bbb       |   |
yahoo.co.jp?p=ccc&d=fff    |   |
yahoo.co.jp?g=x&p=ttt&t=g   |   |
944935:2009/08/30(日) 15:28:52 ID:IiFjmKoL
うーん、よくよく考えてみれば、これ絶対無理ですよね。
基本的な考え方が抜けてました。
ストアドプロシジャとかカーソルとかを使わない限り、
1回のUPDATE文で1つの列に複数種類の値を設定できないですもんね。

例えば、
 aaa
 bbb
 ccc
という3種類の値を、下記のような1回のUPDATE文でsearchに設定できないですもんね。
(????の所に複数の値を返すサブクエリを書いたらエラーになるし)
  UPDATE URLテーブル SET search = ????;
945名無しさん@そうだ選挙に行こう:2009/08/30(日) 15:39:15 ID:???
>>943
ググってみたんだけど、MySQLの正規表現で部分抽出や置換が出来そうにないのよね。
出来るのなら、その関数なり演算子のURLを教えてくれたら、わかるかもしれない。
それが出来ないのなら、ホスト言語側で一行ずつ処理するしかないと思う。
946名無しさん@そうだ選挙に行こう:2009/08/30(日) 15:41:15 ID:???
>>944
> 1回のUPDATE文で1つの列に複数種類の値を設定できないですもんね。

いや、そのあたりは何とかなりそうな気がする。
947935:2009/08/30(日) 16:05:31 ID:IiFjmKoL
>>945
おっしゃるとおりmysqlの正規表現では不可能なようです。
http://okwave.jp/qa4636418.html

>>946
多分無理だと思う。
 UPDATE urltable SET search = (複数レコードを返すサブクエリ);

 UPDATE urltable SET search IN ('f','d','a');
も無理だし。
やはりUPDATEを連続実行する必要がありそうorz
私の知らないテクがあればご教授よろしくお願いいたします。
948名無しさん@そうだ選挙に行こう:2009/08/30(日) 19:05:21 ID:???
>>947
945=946なんだが、

>  UPDATE urltable SET search = (複数レコードを返すサブクエリ);
こいつはどのDBMSでも無理だが、元質の例えで出てきた範囲ななら
正規表現で抽出することが出来るDB、PostgreSQL等だと

UPDATE url SET search = substring(url from E'[\?&]'||id||'=([^&$]*)') FROM engin WHERE url.url ~('^'||engin.engin);
みたいな感じで可能。
ま、WHERE url.url ~('^'||engin.engin); で一行しか返らないという条件付きな。
949935:2009/08/30(日) 19:30:22 ID:IiFjmKoL
>>948
レスありがとう。
でも、すんませんorz 私のレベルが低すぎて解読できないorz

>substring(url from E'[\?&]'||id||'=([^&$]*)')
fromの後のEとか、substringの引数の指定の仕方とか、UPDATE文にFROMやWHEREがあるところとか。
多分上級者の人ならピンと来るんだと思うんですが、できれば若干の解説を・・・。
orz
950名無しさん@そうだ選挙に行こう:2009/08/30(日) 19:54:21 ID:???
下記のような空白交じりの情報を出力するとき、
空白が1つの場合はそのままで、
空白が2つの場合は空白を1つにして出力することはできますでしょうか?

あい うえ  お
あい(空白)うえ(空白)(空白)お
951名無しさん@そうだ選挙に行こう:2009/08/30(日) 19:56:15 ID:???
1つか2つしか無いのであれば
空白2つを1つにREPLACEすればいいんじゃないの
952名無しさん@そうだ選挙に行こう:2009/08/30(日) 20:06:44 ID:???
回答ありがとうございます。
3つ以上もありえるんです。
重複する空白を1つにする方法をご存じないでしょうか。
953NAME IS NULL:2009/08/30(日) 20:16:52 ID:???
>>949
PostgreSQLのsubstringの仕様はマニュアルをググってね。
Eはエスケープするよん宣言。Eなしで [?&] でも良さそうだけど。
UPDATE ... FROM ... WHEREは結合(JOIN)している。

SELECT * FROM urlTable JOIN enginTable ON urlTable.url ~ ('^' || enginTable.engin);
と同じようなこと。

>>952
DBは? PostgreSQLなら
regexp_replace( 文字列 , ' +', ' ')
954NAME IS NULL:2009/08/30(日) 20:18:25 ID:???
訂正
×regexp_replace( 文字列 , ' +', ' ')
○regexp_replace( 文字列 , ' +', ' ' ,'g')
955935:2009/08/30(日) 20:45:51 ID:IiFjmKoL
>>954
なるほど!
やっと内容が把握できました。確かにこれならイケます。
でもこれ、Mysql(実行環境がmysql5.0なんです)で実行できるんだろうか(汗)
mysqlで出来る出来ないは置いといて、超勉強になりました!
956935:2009/08/30(日) 20:46:45 ID:IiFjmKoL
アンカミス><
>>953でした。
957NAME IS NULL:2009/08/30(日) 21:01:02 ID:???
>>953
回答ありがとうございます。
DBはMysqlです。
958NAME IS NULL:2009/08/30(日) 23:35:41 ID:???
>>950
mysqlの正規表現は>>945が言ってる通りMySQLの正規表現で部分抽出や置換が出来ない。
プログラムで対処するしかない。
959NAME IS NULL:2009/08/30(日) 23:37:43 ID:???
再帰的にREPLACEする関数を作ればいいんじゃないの
960NAME IS NULL:2009/09/03(木) 16:35:27 ID:gPIw7unu
DB:MySQL5.1

insert into AAA ( date1 ) values ( last_day(date_add(NOW(),interval 1 year)) );

この場合だと1年後の月末の00:00:00が入ります。
やりたいのは1年後の月末の23:59:59(ここが固定)で投入したいのです。
方法がありましたら教えてください。
961NAME IS NULL:2009/09/03(木) 16:50:39 ID:???
23:59:59 足せばいいんでないの??
962NAME IS NULL:2009/09/03(木) 17:23:02 ID:???
>>961
できた!ADDTIMEを知りませんでした・・・。

select addtime(date_format(last_day(date_add(now(),interval 1 year)),'%Y/%m/%d %H:%i:%S'),"23:59:59");

ありがとうございます。
963NAME IS NULL:2009/09/03(木) 20:41:36 ID:x4DugVd9
t
964NAME IS NULL:2009/09/03(木) 20:48:58 ID:???
↑すいません。

accessでインポートしてきた、テーブル1を更新クエリを使ってnull値を埋めたいと思っています。
F1 F2 F3
ke ek 03
oe 0w 93
qi 93
oq 92
zp ie 32

こんなテーブルを、更新クエリ

レコードの更新:[テーブル1].[F1] = [テーブル1].[F1]-1
抽出条件: Is Null
または、
レコードの更新:[テーブル1].[F2] = [テーブル1].[F2]-1
抽出条件: Is Null

で、更新しようとしたのですが、更新すべき件数を認識してくれますが、
データは反映されません。
初歩的な質問な気がしますが、ヒントだけでもお願いします。
965NAME IS NULL:2009/09/03(木) 20:50:26 ID:???
SQL を勉強してから来い
966NAME IS NULL:2009/09/04(金) 13:46:31 ID:???
Oracle10gを使用しています。
MERGE文で、
WHEN MATCHED AND TBL_1.CD_A <> TBL_2.TCD_A THEN
....
という感じで指定したいのですけど、
Oracleではどのように指定するのでしょうか?><
967NAME IS NULL:2009/09/04(金) 14:40:13 ID:???
MERGE INTO TBL_1
USING TBL_2
ON (TBL_1.CD_A <> TBL_2.TCD_A)
WHEN MATCHED THEN
...

という感じじゃね
968NAME IS NULL:2009/09/04(金) 14:50:20 ID:???
>>967
ご回答ありがとうございます。
いろいろ勘違いしてたみたいです。
969NAME IS NULL:2009/09/05(土) 18:22:57 ID:GS7w5l+v
access 2000使ってます

2つのテーブルがあり、
片方のテーブルには
[データ名]フィールドと
[ID1]フィールドと
[ID2]フィールドがあります。

もう片方のテーブルには
[データ内容]フィールドと
[ID3]フィールドがあります

[ID1]と[ID2]の値を連結した8桁の文字列が[ID3]に対応します。

以上の内容で[ID3][データ名][データ内容]の入ったクエリを作成したいのですが、
SQLだとFROMの部分がうまく指定できません。

初歩的な質問でしょうが、どうかお願いいたします。

970NAME IS NULL:2009/09/05(土) 18:44:59 ID:???
select * from tbl1, tbl2
where tbl1.id1 + tbl1.id2 = tbl2.id3
971NAME IS NULL:2009/09/05(土) 19:18:19 ID:???
こんな簡単に出来たんすか・・
すいません、ありがとうございました
972NAME IS NULL:2009/09/07(月) 00:15:54 ID:???
MySQL5.1 Tritonn でDBを構築しています.
特定のクエリがどうしても遅いので高速化したいのですが,行き詰ってしまいました.

現在次のような3つのテーブルがあります.

TableA (RIDとRCodeは二つ揃って一意 RID一つに対して複数のRCodeIDを登録)
RID: INTEGER
RCodeID: INTEGER

TableB
ID: INTEGER
TableA_ID: INTEGER
Text: Text

Master
ID: INTEGER
Code: Text

TableBのText内に任意の文字列が含まれている項目を抽出し
Master.Codeごとにどれだけ使われているのか取得したいのです.

現在次のようなクエリを発行しています.
SELECT COUNT(Master.ID), Master.Code
FROM TableA
LEFT OUTER JOIN TableB ON TableA.RID = TableB.TableA_ID
LEFT OUTER JOIN Master ON TableA.RCodeID = Master.id
WHERE match(TableB.text) against( 'Term')
GROUP BY Master.id ORDER BY count(Master.id) DESC;

Explainしてみると,
1, 'SIMPLE', 'TableA', 'index', '', 'PRIMARY', '8', '', 1417619, 'Using index; Using temporary; Using filesort'
1, 'SIMPLE', 'TableB', 'ref', 'Index1', 'Index1', '4', 'DBName.TableA.RID', 1, 'Using where'
1, 'SIMPLE', 'Master', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'DBName.TableA.RCodeID', 1, ''
となりました.

まずTableAのインデックス追加が必須のようなのですが,
RID,RCodeID,RCodeID RID, RID RCodeID
と無駄があるのも承知で4つ(Index BTREE)を作成しましたが改善されません.

どなたかご助力いただけませんでしょうか
973NAME IS NULL:2009/09/07(月) 00:22:35 ID:???
MYSQLてフルテキストインデックスて無いんだっけ?
974972:2009/09/07(月) 00:38:04 ID:???
>973

標準のMySQLには英文のものしかありません.
ですので
http://qwik.jp/tritonn/
こちらの全文検索エンジンを導入しています.
975972:2009/09/07(月) 17:16:52 ID:???
自己レスです.

うまくいったので内容を記述します.
Where句を
WHERE match(TableB.text) against( 'Term')
 ↓
WHERE TableB.TableA_ID > 0 AND match(TableB.text) against( 'Term')
これでうまくいきました.
TableB.Table_IDはすべて1以上の値が入っているので結果は変わらないのですが,
これにすることでIndexが有効に使われるようになったようです.

うまくいったのはいいのですが,
なぜうまくいくのか理由がわからないので,
次回のためにもどなたか解説いただけませんでしょうか.
976NAME IS NULL:2009/09/08(火) 01:34:20 ID:LRxN+yRN
下記のテーブルがありまして、
TABLE_A
TABLE_B
TABLE_C
その中に、COLUMN_KEYという同じ種類の列があります。

この3つのテーブルの中で、
(1)COLUMN_KEYが3つのテーブルにあるもの
(2)COLUMN_KEYが3つのテーブルにあるもの
のデータを取得したいのですが、一回のSQLで書く方法はありますか?

一時TABLEを作って、GROUP BYとHAVINGを使って処理する方法は思いついたのですが、
一時TABLEを作わずに、一回のSQLで処理する方法が分かりません。

データベースは、MYSQL5+WindowsXPです。
宜しくお願いします。
977NAME IS NULL:2009/09/08(火) 01:35:13 ID:LRxN+yRN
すみません。
コピペミスです。

> (2)COLUMN_KEYが3つのテーブルにあるもの
は(2)COLUMN_KEYが2つのテーブルにあるもの、の間違いです。

大変失礼しました。
978NAME IS NULL:2009/09/08(火) 01:43:59 ID:???
select count(column_key) from
(
select column_key from table_a
union all
select column_key from table_b
union all
select column_key from table_c
)
group by column_key having count(column_key) = 3(もしくは2);

単純にだとこうかなぁ。
979NAME IS NULL:2009/09/08(火) 01:44:06 ID:???
>>976
(1)と(2)のそれぞれのSQLが知りたいのか?
それとも(1)と(2)同時にとりたいのか?
前者の(1)なら普通にJOINすればいいだけなんだから、(1)がわからないのはあり得ないか?
なら後者? でもどういう出力が欲しいのかわからないので、出力サンプル出してみ。
980NAME IS NULL:2009/09/08(火) 01:45:03 ID:???
ああ、(1)はJOINでよかったかorz
981NAME IS NULL:2009/09/08(火) 01:54:55 ID:???
>>975
最適化以前にいくつか気になることがあるんだが

1.TableAとMasterを外部結合させているが、内部結合にすることはできないのか?
TableA.RCodeID = Master.idを満たさない場合、Master.ID, Master.CodeともにNULLとなる。

有効なMaster.ID+NULLとなったMaster.IDをカウントしたい様に見えるが、
COUNT(Master.ID)としているため、NULLとなったMaster.IDはカウントされない

2.TableBも外部結合させているが、TableA.RID = TableB.TableA_IDを満たさない場合、TableB.textはNULLになるため、内部結合でも良い様に見える。

3.蛇足だけど、count(Master.id)を二カ所に記述しているのが気になる.
MySQL 5.1は表式が使えるようなので、

SELECT * FROM (
SELECT COUNT(Master.ID) AS ID_COUNT, Master.Code
FROM TableA
LEFT OUTER JOIN TableB ON TableA.RID = TableB.TableA_ID
LEFT OUTER JOIN Master ON TableA.RCodeID = Master.id
WHERE match(TableB.text) against( 'Term')
GROUP BY Master.Code
) V
ORDER BY ID_COUNT DESC

とすると、どうなるだろうか?


「説明のための簡略化で、取得列数を減らしているだけで、実際はもっと多いんです」と言う状況か
その場合でも、提示されたクエリで絞り込んだ結果セットとほかの実テーブルを改めて結合したらいいんじゃないのかな、と思った。



982NAME IS NULL:2009/09/08(火) 02:16:16 ID:???
Ooo3.1.1-Base使ってます。
original.csvファイル
111111,aaaa
222222,bbbb
 ・ 
 ・ 
 ・
の全レコードを作成済みテーブル(sub)にIDを先頭に追加した形でコピーしたいです。
ID | DATE | DATA
--+------+-----
1 | 111111 | aaaa
2 | 222222 | bbbb

 ・
 ・
単純にコピーなどでできたらいいんですが、レコード行数が限界を超えてしまったための策です。
お願いします。
983NAME IS NULL:2009/09/08(火) 02:26:03 ID:???
>>976
どこか一つのテーブルのcolumn_keyが必ずNULLでないのなら、
以下の様に書ける(table_aのcolumn_keyがNULLでないと仮定)

select
v.column_key,
sum(case when v. column_key_count = 2 then 1 else 0) as column_key_count2,
um(case when v. column_key_count = 3 then 1 else 0) as column_key_count3
from (
select
a.column_key,
1
+ (case when b.column_key is null then 0 else 1 end)
+ (case when c.column_key is null then 0 else 1 end) as column_key_count
from table_a a
left outer join table_b b a.column_key = b.column_key
left outer join table_c c a.column_key = c.column_key
) v
group by
v.column_key

full outer joinがつかえると、上の仮定なく取得出来るが、どうもMySQLには無いらしい
ちなみにfull outer joinだと、内側のクエリを、

select
coalesce(a.column_key, b.column_key, c.column_key) as column_key
(case when a.column_key is null then 0 else 1 end)
+ (case when b.column_key is null then 0 else 1 end)
+ (case when c.column_key is null then 0 else 1 end) as column_key_count
from table_a a
full outer join table_b b a.column_key = b.column_key
full outer join table_c c a.column_key = c.column_key

と変更する。

未確認なので、雰囲気だけ感じてくださいな
984NAME IS NULL
>>983の自己レス
外側間違ってた

select
v.column_key,
sum(case when v. column_key_count = 2 then 1 else 0 end) as column_key_count2,
um(case when v. column_key_count = 3 then 1 else 0 end) as column_key_count3
from (...) v
group by
v.column_key