5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

SQL質疑応答スレ 8問目

1 :NAME IS NULL:2009/03/05(木) 20:45:54 ID:???
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

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

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

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

前スレ:
SQL質疑応答スレ 7問目
http://pc11.2ch.net/test/read.cgi/db/1223525474/


2 :NAME IS NULL:2009/03/05(木) 20:46:43 ID:???
SQL言語リファレンス一覧
Oracle Database
http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-02/toc.htm
Microsoft SQL Server
http://msdn.microsoft.com/ja-jp/library/bb510741.aspx
IBM DB2 Database
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp (目次から参照情報→SQL)
PostgreSQL
http://www.postgresql.jp/document/pg833doc/html/sql.html
MySQL
http://dev.mysql.com/doc/refman/5.1/ja/sql-syntax.html


参考リンク
http://sql.main.jp/cont/sql/map.html
http://www.atmarkit.co.jp/fnetwork/rensai/sql01/sql1.html
http://oraclesqlpuzzle.hp.infoseek.co.jp/
http://www.techscore.com/tech/sql/

3 :NAME 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/


4 :NAME 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
;


5 :NAME 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
;


6 :NAME IS NULL:2009/03/05(木) 21:11:51 ID:???
>>1乙&>>2のリンク修正

SQL言語リファレンス一覧
Oracle Database
http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-03/toc.htm
Microsoft SQL Server
http://msdn.microsoft.com/ja-jp/library/bb510741.aspx
IBM DB2 Database
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp (目次から参照情報→SQL)
PostgreSQL
http://www.postgresql.jp/document/current/html/sql.html
MySQL
http://dev.mysql.com/doc/refman/5.1/ja/sql-syntax.html


参考リンク
http://sql.main.jp/cont/sql/map.html
http://www.atmarkit.co.jp/fnetwork/rensai/sql01/sql1.html
http://oraclesqlpuzzle.hp.infoseek.co.jp/
http://www.techscore.com/tech/sql/

7 :NAME IS NULL:2009/03/07(土) 00:30:17 ID:lFENR4eI
ちょっとSQLとは離れてしまうのですが、テーブルのなかにテーブルを作れる DBMS ってあるのでしょうか?

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

こんなかたちで、普通のデータとテーブルを混合して扱えるといいのですが、

8 :NAME IS NULL:2009/03/07(土) 00:48:02 ID:???
>>7
少なくともOracleではできるけど激しくお勧めしない
今すぐデータ構造を見直したほうがいい

9 :NAME IS NULL:2009/03/07(土) 00:51:03 ID:???
>>7
何故それをやらなければならないのか、それが問題だ。

10 :NAME IS NULL:2009/03/07(土) 02:33:50 ID:lFENR4eI
>>8 >>9

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

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

となると、1レコードあたり300カラム以上になってしまい、また委託先がバラバラなので外注マスタみたいなものを
作るのが困難なため、こんな方法にしようかと、、、なにかいい方法はないでしょうか

11 :NAME IS NULL:2009/03/07(土) 03:40:34 ID:???
>>10
一つ確認なのですが、300カラム以上と言うのは、

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

という計算で良いのでしょうか?


12 :NAME IS NULL:2009/03/07(土) 07:19:26 ID:???
>>10
RDBMS を勉強し直せ

13 :NAME 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
なにか根本的に間違っているのでしょうか、、

14 :NAME IS NULL:2009/03/07(土) 11:15:19 ID:???
>>13
根本的に間違ってるからまずリレーショナルデータモデルを勉強したほうがいい

15 :NAME IS NULL:2009/03/07(土) 11:40:31 ID:lFENR4eI
>>14
なんか根本的に間違ってる気がしてきた、、項目が多い部分は、外部のテーブルにしろってことですかね。

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

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

こんな形にしてプロジェクトコードで結合。この場合、正規化する必要の無いテーブルを分割しているのですが、それはありですか?

16 :NAME IS NULL:2009/03/07(土) 12:21:23 ID:???
主キーとか正規化とか知ってる割には... 釣りとしか思えん。

釣りじゃないと言うなら、>>12, >>14 が言ってるように本屋に
行ってデータベース関連の本買ってきて勉強した方がいい。

17 :NAME IS NULL:2009/03/07(土) 12:52:13 ID:???
釣りじゃないですよ。もう少しちゃんと勉強しないとまずそうですね。
スレ汚しみたいになってしまってすみませんでした。本買ってきます。

18 :NAME IS NULL:2009/03/07(土) 13:00:27 ID:???
なんて偉そうなw

19 :NAME IS NULL:2009/03/07(土) 14:15:18 ID:???
純粋にデータベース理論に基づく議論として、>>13のスキーマがダメで
>>15のようなスキーマの方がよい理由って何でしょうか。

20 :NAME IS NULL:2009/03/07(土) 14:24:28 ID:???
ここは SQL なスレであって、テーブル設計のスレではないことに
そろそろ気づこうな。

21 :NAME IS NULL:2009/03/07(土) 23:08:49 ID:lFENR4eI
本から調べてみましたが、正規化するする必要がないテーブルを分割するのは設計上ありえない、もしくは仕方の無い場合のみ
しかしカラム数が膨大になる場合でも分割するのは、EDI規約では分割しては "ダメ" とのこと、、、

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

どうでも良いけど、「リレーションをつかえば..」「そういう設計はない」「もう少し調べてろ」とか うちのアホ上司と
答えが同じで面白かったです。で、困ると「俺に(ここ)で聞くな」的なw 知らなければ知らないでいいですよ。無理しないでね。

22 :NAME IS NULL:2009/03/07(土) 23:13:25 ID:???
何をもって「正規化する必要がない」なのか、俺には全然理解できん。
普通に正規化する必要ありそうに見えるけどな。

23 :NAME IS NULL:2009/03/07(土) 23:16:39 ID:???
>>21
正規化について考えたのであれば>>10のデータに関して
関数従属性(FD)を見当したはずですが、どのようなFDを
列挙したか書いてもらえますか?

24 :NAME IS NULL:2009/03/07(土) 23:22:06 ID:???
ACCESSだけど、>>13と同じ構造でテーブル設計されてるDBを見たことがある。
もうなんていうか、え…っ?何を見たんだろう…?って感じ。
でもさすがに300カラムはなかった。255カラムだったw

>>19
人の入れ代わりが繰り返されたら、そのテーブル構造だとどうなるかをまず考えてみよう。
そうして、正規化について基礎から勉強しなおそう。


25 :NAME IS NULL:2009/03/07(土) 23:24:54 ID:???
スレ違いなのに、逆ギレを装いつつ煽ることで答えを引き出そうとするテクニックですね。
いい加減、スレ違いなお馬鹿さんにつきあうのはやめにしましょう。

26 :NAME IS NULL:2009/03/07(土) 23:29:09 ID:???
>>24
いや、なので純粋に「関係データベースモデル的に」ですよ。ネタです。
とりあえず部分従属も推移的従属も多値従属もないですよ?

27 :NAME IS NULL:2009/03/07(土) 23:37:48 ID:lFENR4eI
>>23
なんかスレ違いを続けてすみません。

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

データベース関連の本買ってきて勉強した方がいい。ですよw

28 :NAME IS NULL:2009/03/07(土) 23:43:51 ID:???
カタカナ言葉で逃げないで、ちゃんと読めって言われた本やマニュアル読みなよ。
自己満足で変な物作るなよ。

29 :NAME IS NULL:2009/03/07(土) 23:45:37 ID:???
>>27
失礼しました。関数従属性も見当しないで「正規化すると・・・」なんて
文句言う人も少なくないので一応ちゃんと見当したか確認したかった
のです。見当したという事で、了解しました。

もう一つ確認なのですが、各プロジェクトのスタッフの数は10人・20人・
30人で固定でしょうか。
欠員や人数割れは発生しませんか?あるいはこれらの人数は単に
上限を示すものでしょうか。

30 :NAME IS NULL:2009/03/08(日) 00:01:01 ID:???
データーベースってさ、
「作る前に」
いっしょうけんめい、考えないといけないよね。

31 :NAME IS NULL:2009/03/08(日) 00:03:27 ID:???
>>24
> ACCESSだけど、>>13と同じ構造でテーブル設計されてるDBを見たことがある。
> でもさすがに300カラムはなかった。255カラムだったw

Excel の概念から脱却できなかったんだろうな。
まあ、Excel 2003 まででよかったよ、Excel 2007 使いだと、カラム数 1,000
とか平気で作りそうだし。(w

32 :NAME IS NULL:2009/03/08(日) 00:06:45 ID:???
>>26
ヒント:第一正規形

33 :NAME IS NULL:2009/03/08(日) 00:16:05 ID:OlHguXyr
>>32
>>13のリレーションは第一正規形のようですが。

34 :7:2009/03/08(日) 00:19:08 ID:vyix2FVv
>>29
こちらそ失礼をすみません。スタッフの数は極端な話 0人(全てお任せで社名のみ)〜100人近くになる可能性もあります。

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

ただ想定している上限100名×5 = 500カラムはちょっと無理そうなので、テーブルのなかにテーブルがつくれるのがいいのかな?と考えました。

35 :NAME 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のアプローチでデータベースを作ると良いと思います。

36 :NAME IS NULL:2009/03/08(日) 00:29:41 ID:???
>>31
Oracleならありそうで怖いw
Accessは幸いなことに…いや全然幸いでも何でもないけど、1テーブル255カラムが最大。

>>26
>>13のテーブル構造で、それぞれのプロジェクトにかかるコストを算出することを考えてみて。
工程ごとの小計もそれに加えたりなんかすれば…、死ねるw
DB構築する意味ないじゃん。

37 :NAME IS NULL:2009/03/08(日) 00:40:45 ID:???
なんだ〜、さっぱり理解できない…
最後の1文だけ同意するw

38 :NAME IS NULL:2009/03/08(日) 01:02:50 ID:???
正規化できない暴威は結局,答えが欲しいんでしょ?
素直になれば良いのに。
「教えてください」って言えない子は,自分勝手に設計して
後で理解できれば本人のためにも良いと思う。
スレチってことも自覚してるようだし。
Access弄ってる気の利いた素人でもそんな設計しないよw

39 :7:2009/03/08(日) 01:24:03 ID:vyix2FVv
>>35
>失敗はリレーションの正規化以前の、データ設計にあります。
>元より異なるデータ構造

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

ベテランの方だと思うのですが、失礼すみませんでした。

40 :NAME 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のスキーマです。

41 :NAME IS NULL:2009/03/08(日) 02:10:38 ID:???
>>40
詳しい説明をどうもです。
でもカリー化とやらをググってたら脳ミソ逃避し始めた…w

42 :NAME 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のスキーマが出来ます。

ただこれらは「屁理屈」ですからね。理解としては楽しいですが
あまり世間的に役に立つとは思いません。

43 :NAME IS NULL:2009/03/08(日) 10:08:10 ID:???
俺の意見としては >>13 は「正規化できてない」だな。

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

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

マスタ化しづらいなら、マスタから値を引っ張るケース、その行に単一スタッフを
書き込むケース、なんて形に分けると思う。

44 :NAME IS NULL:2009/03/08(日) 10:38:07 ID:???
俺もそう思う。
難しい言葉はともかく、第一正規形は
「テーブル内テーブル」を排除したものでしょ?

45 :NAME IS NULL:2009/03/08(日) 14:46:17 ID:???
>>42
待った。
>>13を見ただけではそのような関数従属が存在するとは判断できないと
いう意味で、>>13が非正規形であると言い切れないというのは良い。
ただ、>>42のような関数従属の存在を前提とした場合、コッドの関係モデルが
一階述語論理に基づくものである以上、そのようなカリー化された関係を
スキーマに表現することはできない。
カリー化の操作そのものには問題はないのだが、「左辺の具体値を新たな
属性名として利用して」という部分で、元の関数従属を表現できなくなっている
ことに注意。

46 :NAME IS NULL:2009/03/08(日) 16:40:11 ID:???
>>45
その通りです。一連の操作で展開された関係従属の集合と元の関数従属は
同じものとして扱う事は出来ません。
なので>>13>>15のスキーマは「異なるデータ構造」、つまり異なる属性集合
と異なる関係従属性の集合を表現したものなります。

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

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

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

実際>>13のスキーマはちゃんと正規形なのです。なぜなら>>27にあるように
「作業Aスタッフ1の名前はプロジェクトコードにのみ関数従属する」他の属性
についても以下同文、というようにデータを設計したらです。
そのようなデータを表現する限りに置いて、このスキーマは正規形です。
ですのでツッコミの入れどころは正規化ではなく、データ設計のそのものと
なります。

47 :NAME IS NULL:2009/03/08(日) 16:43:09 ID:???
ありゃ、関数従属が全部関係従属になっている・・・Typoです orz

48 :スレタイも読めないぼんくらに言っても無駄か...:2009/03/08(日) 18:05:06 ID:???
君らが賢いのわかったから、どっかよそでやってくれないかな。

49 :NAME IS NULL:2009/03/08(日) 18:30:35 ID:???
やっぱりXMLデーターベースだよねー
あとから変更できるしー

50 :NAME IS NULL:2009/03/08(日) 19:10:34 ID:???
>>46
こっちにレスしました。

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

>>48
こういう話題振ると、叩き上げの上司がそういう反応したりしますねぇ。

51 :NAME IS NULL:2009/03/08(日) 19:12:48 ID:???
いい加減、煽るのやめろよハゲ

52 :NAME IS NULL:2009/03/08(日) 19:46:02 ID:???
注意されて逆切れするタイプなんだろ。
スルー推奨。

53 :NAME IS NULL:2009/03/08(日) 20:11:07 ID:???
>>49
XQueryとXPathが全社共通になったらね。

54 :NAME IS NULL:2009/03/08(日) 20:12:56 ID:???
>>53
そんなの待ってられないから、
とりあえず、現時点でシェアトップのものを
使いたいんだけど?

55 :NAME IS NULL:2009/03/08(日) 20:27:50 ID:???
よし ならば DB2 v9.1 pureXMLだ

夏前にはv9.5が出るよん

56 :NAME IS NULL:2009/03/08(日) 21:54:31 ID:???
>>53
それを言うなら問題はXQuery Update Facilityだと思うけど・・・
XQueryやXPathは世に言うXMLDBなら大概は使えると思う。

57 :NAME 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、設定
なのか・・・

どういう構造がいいんでしょうか?

58 :NAME 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)

・「設定」をテーブルで表現したとして、どういう検索をしたいのか

59 :NAME IS NULL:2009/03/09(月) 17:54:11 ID:???
設定値はユーザーが任意に入力できる正規表現の文字列なので、
多種多様な値が入ることになります。
検索はしないかもです。データベースでやる必要はないんでしょうか?
とりあえず後者のやり方でやってみます

60 :NAME IS NULL:2009/03/09(月) 18:11:32 ID:???
ユーザーIDで検索するだけってことだよね。
ところでユーザーIDも保持してるならIDを10倍して足す意味が無いような。

61 :NAME 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個まで増量!などした時など。

62 :NAME IS NULL:2009/03/09(月) 20:28:49 ID:???
なるほど。
{ユーザID, 正規表現}でPK制約しようと思いましたが、
フレームワークがCakePHPなんで
IDは制約として必要で複合キーもサポートされていないみたいです。
しょうがないのでやっぱり、ID=ユーザID*10+0にしてみようと思います
ありがとうございました。

63 :NAME IS NULL:2009/03/09(月) 21:05:21 ID:???
なんでわざわざ SQL のスレで聞くのか・・・

64 :NAME IS NULL:2009/03/09(月) 21:51:22 ID:???
タイトルに「質問」「質疑」って書いてあるスレ他にあまり無いし。
DB設計の方は「語る」スレらしいのでこっちに流れてくるのも
仕方がないのではないかと。

65 :NAME 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

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

auto_increment 列を使うのが一般的じゃない?


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

PKをIDにしても、べつにUNIQUE NOT NULLな制約は付けられるでしょ?

68 :NAME IS NULL:2009/03/09(月) 23:06:51 ID:???
>>62
複合キーを使えないというのであれば、普通にサロゲートキーに
しておいた方が良いと思う。
「ユーザID*10+x」なんてキーにするなんて、仕様に自ら爆弾を
仕込むようなものですぜ。

69 :NAME IS NULL:2009/03/09(月) 23:08:18 ID:???
SQLiteって、CHECK制約が使えないってひどくないですか。

データーの入る範囲を、1−100にしたい、とか思っても、
できないってことじゃないですか。

70 :NAME IS NULL:2009/03/09(月) 23:24:44 ID:???
>>69
MySQLの間違いじゃなくて?

71 :NAME IS NULL:2009/03/09(月) 23:30:57 ID:???
>>70
SQLiteのはなしだよ

72 :NAME IS NULL:2009/03/09(月) 23:31:52 ID:???
アプリ側で制約すればいいじゃん。

73 :NAME IS NULL:2009/03/09(月) 23:42:23 ID:???
>>66
ありがとう

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

もう少し自分で試してみます。

74 :NAME IS NULL:2009/03/09(月) 23:42:55 ID:???
>>71
う、う〜ん?

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

うっふん

75 :NAME IS NULL:2009/03/09(月) 23:50:15 ID:???
>>74
読んでる教科書が2005年発行のやつだったので
古かったようです。

76 :NAME IS NULL:2009/03/10(火) 10:13:25 ID:???
実際にやってみて困った話じゃないのかよ

77 :NAME IS NULL:2009/03/10(火) 21:31:56 ID:???
だって教科書読んでたら、
対応してない、って書いてあるんだもん

78 :NAME IS NULL:2009/03/10(火) 22:54:44 ID:???
でも他人様の成果物に対して「ひどい」なんて文句をここに
書き込む前にちょっとはクグろうや。
「sqlite check」で一瞬で見つかったよ。

79 :NAME IS NULL:2009/03/10(火) 23:17:37 ID:???
トリガーっていうの、
よくわかりません

80 :NAME IS NULL:2009/03/10(火) 23:21:03 ID:???
>>79
Insert とか Update とか Delete とかが発生したときに呼び出されるプロシージャ。

TableA のデータが削除されたタイミングで、TableB の関連データを削除する、
とかってときに使えるよ。

81 :NAME IS NULL:2009/03/11(水) 00:10:13 ID:???
ようはストアード・プロシージャの一種なのね。
違いがわからんかった。

82 :NAME IS NULL:2009/03/11(水) 00:21:19 ID:???
ユリウス暦ってのがよくわかりません

83 :NAME IS NULL:2009/03/11(水) 00:21:51 ID:???
スキーマとプラグマの違いがよくわかりません

84 :NAME IS NULL:2009/03/11(水) 00:22:03 ID:???
>>82
それは SQL に関係なさそうです。

85 :NAME IS NULL:2009/03/11(水) 00:23:58 ID:???
ランダムに1−5を生成して、
それをボタンが押されるごとに、
どんどん足していく、というプログラムなのですが、
SQL側でランダムに数字を生成して足す、という
構造に今、しているのですが、

「○を足しました」

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

それとも、前後の差分を取るしかない?

86 :NAME IS NULL:2009/03/11(水) 00:25:57 ID:???
>>84
だってユリウス暦を取得する、って関数があるんです。
昨日発見しました。

87 :NAME IS NULL:2009/03/11(水) 00:28:24 ID:???
>>85
SQL でどんな処理をしてるのか書こうな。

>>84
ユリウス歴が何かは Google とかで調べような。
SQL には直接関係ないから。

88 :NAME IS NULL:2009/03/11(水) 00:35:53 ID:???
>>79
もちっと厳密に言うと、active databaseという考え方が元になっていて、

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

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

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

しかしこれを実装するのであればDATE値から大安とか丑年とか
計算してくれる関数がないと不平等だよな。

89 :NAME IS NULL:2009/03/11(水) 00:39:57 ID:???
>>85
> ランダムに1−5を生成して、
> それをボタンが押されるごとに、
> どんどん足していく、

なんか、最近似たようなモンを見たような気がするが、なんかの課題なのか?

90 :NAME IS NULL:2009/03/11(水) 01:10:43 ID:???
SQLite3で、
あとからAUTOINCREMENT 指定するのは
不可能?

91 :NAME IS NULL:2009/03/11(水) 01:29:47 ID:???
>>89
どれ?

92 :NAME IS NULL:2009/03/11(水) 01:50:35 ID:???
前スレでの話しだな。> ランダム

で、その前スレから疑問に思ってたけど、乱数生成をSQL側でしようとするのが疑問だった。
最終的にはUPATE Table SET val = val + random().... 的な使われ方だけで
済むのならSQLで済ませてもいいけど、いろいろ制約(乱数の範囲やvalの最大値)があるみたいだし、
素直にPHPで生成させておけば、そんなに悩むものでも無かろう。

93 :NAME IS NULL:2009/03/11(水) 01:53:49 ID:???
>>92
それで生成させたランダム値を
PHP側で知りたいんですけど、無理ですか?

94 :NAME IS NULL:2009/03/11(水) 01:55:05 ID:???
ようはコンビニでおでんを買って、
「たれは、ごまだれにしますか?からしにしますか?それとも何もつけないようにしますか?」
って聞かれて
「ランダムでいいです」
って答えて、
「でも、ランダムに決定して、その結果は教えてね」
みたいな。

95 :NAME IS NULL:2009/03/11(水) 01:57:29 ID:???
>>93
できるだろ。テーブルに1件だけデータを入れておいて、Update のあと Select するとか。

96 :NAME IS NULL:2009/03/11(水) 09:12:08 ID:???
テンポラリーテーブルか。
うまいね。

97 :NAME IS NULL:2009/03/11(水) 19:24:23 ID:???
SQLite3の最新版で、
alterで、テーブルを作成したあとに、
autoincrementを付加することは可能なの?

98 :NAME IS NULL:2009/03/11(水) 20:48:51 ID:???
http://sqlzoo.net/

いいページ見つけた。
ボタンを押すとSQL文を生成してくれるっていう。

99 :NAME IS NULL:2009/03/11(水) 21:03:16 ID:???
見せる… 行ロックを無限に発生させてしまうSELECT文が…

100 :NAME IS NULL:2009/03/11(水) 23:37:10 ID:???
>>4に関連して「最新のものの次点のレコード」を抽出したい場合は
どうすればいいでしょうか。
DBはOracle10gです。

<出力イメージ>
1 | 2007-11-10 | ccc
3 | 2007-11-11 | eee

101 :NAME 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_としています。

102 :NAME 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


103 :NAME 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


104 :NAME 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するのが最速かと。

105 :NAME IS NULL:2009/03/17(火) 08:55:52 ID:HhqqMBkm
vistaに11gの30日番をインストールしました。
sqlplusがコマンドプロンプトと変わりません。
よく見慣れた十字架のお墓みたいなアイコンのsqlplusだけをインストール
できないでしょうか?

106 :NAME IS NULL:2009/03/17(火) 09:29:05 ID:???
GUI版のSQL*Plusは11gから廃止されました。

107 :NAME IS NULL:2009/03/17(火) 12:52:28 ID:HhqqMBkm
>>102
ありがとうございます。

108 :NAME 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はどのように記述すればよいでしょうか。?





109 :NAME 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)
;

110 :NAME 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

113 :NAME 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))
;
にすれば標準だと思うけど。

114 :NAME IS NULL:2009/03/18(水) 23:45:02 ID:???
Oracle10gにて
SQL中の文字列(WHEREの後ろとかLIKEの後ろ)にそのままでは使えない文字の全量、対応方法ってわかりますか?

115 :NAME IS NULL:2009/03/18(水) 23:49:07 ID:???
>>114
質問の意味が分からん

116 :NAME IS NULL:2009/03/18(水) 23:50:26 ID:???
予約語の一覧が欲しいのかな。
各RDBMSのマニュアル読んで、ユニークな列名を考えて下さい。

117 :NAME IS NULL:2009/03/18(水) 23:59:52 ID:???
>>114
質問の意図が、予約語と解釈する人もいれば、エスケープが必要な文字と
解釈する人もいそうな曖昧な質問の仕方だなw

118 :NAME IS NULL:2009/03/19(木) 00:55:19 ID:???
114です
すみません…

'%_(シングルコーテ、パーセント、アンダーバー)のようなエスケープが必要な文字を知りたかったのです。

119 :NAME 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条件はさらに%_も
エスケープが必要となるが、それを変更する方法も提供されているということか。
バインド変数を使えば、これらのしがらみからも幾分は開放される。

120 :NAME IS NULL:2009/03/19(木) 15:36:30 ID:???
>>108
このテーブルってid た

121 :NAME 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をじた、キー重複エラーが発生する。


122 :NAME IS NULL:2009/03/24(火) 15:04:34 ID:yR1qlEgs
ある条件でORDERBYした時の、あるレコードの前後のレコードを取得することって可能ですか?

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

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

なんかどれも効率悪そうなんですけど、もっといい方法ありますか?
MySQLです。

123 :NAME IS NULL:2009/03/24(火) 15:36:53 ID:???
あるレコードの前後つーのは、
あるレコードの前→あるレコードより小さい中での最大
あるレコードの後→あるレコードより大きい中での最小

124 :NAME IS NULL:2009/03/24(火) 15:54:42 ID:???
ORDERBY対象がユニークなカラムじゃない
のに特定レコードの前後を取りたいとかアレなの?
氏ぬの?

125 :NAME IS NULL:2009/03/24(火) 17:54:44 ID:???
>>122
具体例を挙げないと、何をしたいのかわからん人がほとんどだと思う(俺も含め)。
ソートした結果の10位前後のレコードを取り出したいというのなら
「じゃあ select * from table order by key limit 9, 3; でいいじゃん」
と誰もが答えるだろう。

126 :NAME IS NULL:2009/03/24(火) 18:32:38 ID:yR1qlEgs
>>123
ああ、そうか、そう考えれば簡単ですね。ありがとうございます。


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

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

まあ、そもそも、更新されたら並び順が変わるし、このインターフェイス自体が問題あるきもしますけど。

127 :122:2009/03/24(火) 18:42:55 ID:yR1qlEgs
>>125
具体的には126にちょっと書きましたが
記事の表示ページに更新日時順で次へ、前へというリンクを出したいんです。

で、そのページはダイレクトに主キーで記事を指定してくることもあるのでLIMIT 1 OFSSET〜っていうわけには行かない感じなんです


128 :125:2009/03/24(火) 19:06:53 ID:???
>>127
ページング処理をしたかったのね。
俺も業務上そのテの開発はよくやるけど、やっぱり limit x, y だよ。
記事を指定して、その記事が含まれるページ(例えば81〜90件目を表示)とかに
飛ぶようなリクエストが発生するシステムであれば、
(順位, 更新日時, 記事ID) を持つソート済みテーブルをあらかじめ作成しておく。
レコード数が多いなら記事IDにindex付与。
更新日時が可変で順位が変わる可能性があるのなら、その頻度に応じてソート済みテーブルを再構築する。

129 :NAME IS NULL:2009/03/24(火) 20:06:31 ID:???
じゃ123でいいじゃん

130 :NAME IS NULL:2009/03/26(木) 08:01:10 ID:???
テーブルX(a,b)と
テーブルY(b,c)で
列bを結合キーにした場合、
テーブルXに無いレコードをテーブルYから削除するには
どのようなSQL文を書けば良いでしょうか

131 :NAME IS NULL:2009/03/26(木) 08:05:03 ID:???
where not in select b from A
でいいんじゃないの?

132 :NAME IS NULL:2009/03/26(木) 08:05:42 ID:???
ごめんAじゃなくてXだった

133 :130:2009/03/26(木) 08:13:50 ID:???
>>131
ありがとうございます

結合は不慣れでして…
ちゃんと勉強しないといかんな
(´・ω・`)

134 :NAME IS NULL:2009/03/26(木) 08:26:15 ID:???
>>133
結合は慣れです。
経験を積めば楽に結合出来るようにもなります。
慣れるまではプロの手ほどきを受けるのも良いかもしれませんね。

135 :NAME IS NULL:2009/03/26(木) 08:29:49 ID:???
131で書いたのは結合じゃなくてサブクエリだけどね

136 :NAME IS NULL:2009/03/27(金) 02:32:29 ID:p8FYVGy/
質問です。

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

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

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

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


※ 住所をこのような形式で管理するのはおかしい!と感じる方もいらっしゃると思いますが、
これは問題をわかりやすくするため、このようにしています。
実際に住所を上記のような管理をしようとしているわけではないので、あらかじめご了承ください。


137 :NAME IS NULL:2009/03/27(金) 03:02:29 ID:???
>>136
恐らく、あなたが欲しいであろう回答をもらうための
前提条件が十分に説明されていない。
name in ('蒲田', '羽田一丁目', '羽田二丁目')
で満たされてしまうからだ。

138 :NAME IS NULL:2009/03/27(金) 03:09:42 ID:p8FYVGy/
>>137
説明が足りず、すいません。

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




139 :NAME 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使っております(後だしすいません。。)


141 :NAME IS NULL:2009/03/27(金) 04:04:34 ID:???
>>140
これ、難しいけど問題としては面白いな。
解けそうで、解けないというか、一番最後の世代というところが難しいわ。


142 :139:2009/03/27(金) 04:34:57 ID:???
>>140
そういうことなら、スマンが俺なら一つのSQLで済ますのはサジを投げる。
ストアドかホストアプリ側で列挙が完了するまでループ。
想定するシーンによっては、ホストアプリ側でn分木を再構築して
探索にはSQLに頼らない処理も考える。
いずれの方法も、循環参照の危険があるならそれも考慮しないと無限ループにハマるがな。

143 :139:2009/03/27(金) 04:47:26 ID:???
>>140
ふと思ったが、もしかしてディレクトリツリーの再帰削除みたいなことをしたいのか?
それならトリガで子ノード(一世代だけでよい)のDELETE書くだけで済むけど。

144 :NAME IS NULL:2009/03/27(金) 21:43:25 ID:???
>>143
MySQLってトリガのネストとか再帰とか可能なのか?
可能だとしても、階層に限界はあるだろうから、あまりにもネストが深いと失敗するかもな


145 :NAME IS NULL:2009/03/27(金) 23:11:51 ID:???
MYSQLはOLAP使えないの?

146 :NAME IS NULL:2009/03/28(土) 06:47:54 ID:???
どの程度の事をやりたいか判らないけどMYSQLのSELECT文には
WITH ROLLUP修飾子なるものが階層別の集計はやってくれる。

これ以上を求めるならMondrian辺りを突っ込んでMDXでクエリを
書いた方が幸せになれると思う。

147 :NAME IS NULL:2009/03/28(土) 07:07:21 ID:???
whereでヒットしたレコードの指定件目を
SQL文だけで取得したいのですが、
どうすれば良いですか><

148 :NAME IS NULL:2009/03/28(土) 08:02:24 ID:???
>>147
LIMIT 〜 OFFSET 〜が使えるDBMSならそれで
ROW_NUMBER()が使えるDBMSならそれで

149 :NAME IS NULL:2009/03/28(土) 08:46:18 ID:???
countでいいじゃん

150 :NAME IS NULL:2009/03/28(土) 09:19:08 ID:???
指定件目だぞ
なんでcountだよ

151 :147:2009/03/28(土) 10:20:03 ID:???
>>148
ありがとうございます
sqliteですが、使えるか確認してみます><

152 :NAME IS NULL:2009/03/28(土) 18:41:16 ID:???
>>147
orderを指定しないselectの、行が返される順番は保障されない
ということは覚えておいた方が良いかもしれない

153 :NAME IS NULL:2009/03/28(土) 23:07:57 ID:???
>136

パッと見たかんじ、最大何階層になるかだけ解れば可能なように見える(実際SQL叩いてないけどw)。
最大階層数が不明なら階層数調べるためにループさせる必要があると思うのでストアドっぽい気がする。


154 :NAME IS NULL:2009/03/28(土) 23:13:21 ID:???
>147
「ORDER BY」、「ROWNUM」


155 :147:2009/03/29(日) 05:03:08 ID:???
LIMITとORDERで出来ましたヾ(^▽^)ノ
教えて下さった方々、どうもありがとうございました

156 :NAME IS NULL:2009/03/29(日) 19:51:33 ID:???
礼にはおよばんよ。
またいつでも聞きにきなさい。

157 :NAME IS NULL:2009/03/31(火) 11:55:58 ID:???
データベースダイアグラム(リレーションシップ)っていままで使用せずに来ましたが、
これって使うのが一般的ですか?

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

どうなんでしょうか。


158 :NAME IS NULL:2009/03/31(火) 13:21:31 ID:???
データベースダイアグラムってMS SQL?

159 :NAME IS NULL:2009/03/31(火) 13:39:17 ID:???
そうです。MS SQLです。
ACCESSでもリレーションシップは使っていませんでした。。

160 :NAME IS NULL:2009/03/31(火) 15:12:25 ID:???
必要なきゃ使わなくていい。

ここは、SQL のスレであって、SQL Server のスレではないことに
気をつけような。

161 :NAME IS NULL:2009/03/31(火) 15:48:17 ID:???
要は外部キーみたいなものだろうから、普通使うだろ。

162 :NAME IS NULL:2009/03/31(火) 18:06:28 ID:???
みんな、サンクス。
すれ違みたいなので、そっちへ行くわ。。



163 :NAME IS NULL:2009/03/31(火) 22:56:36 ID:???
開発中はリレーション張って開発するけど
本番はインサート性能落ちるからリレーション張らないな
Webだけの常識かもしれないけど

164 :NAME IS NULL:2009/03/31(火) 23:11:28 ID:???
そうなんだ!?
情報サンクス〜^^

165 :NAME IS NULL:2009/04/01(水) 05:33:13 ID:???
>>163
本番で外すような制約を開発時につけてるのか?
俺は開発時はリレーションに制約付けない。データの作成とか変更とかやりにくくなるから

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

どうしても性能の問題で制約外すことはあるかもしれないが、
Webだけの常識ってのは違うとおもうぞ

166 :NAME IS NULL:2009/04/01(水) 08:03:45 ID:???
Webシステムは伝統的にMySQLを使う事が多くて、
それにはMyISAMってのがあってだな、
設計時には勿論、外部キーを考慮してデータ設計するんだけども、
実際には云々以下略

167 :NAME IS NULL:2009/04/01(水) 10:04:18 ID:???
>>166
> Webシステムは伝統的にMySQLを使う事が多くて、

プゲラw

お前さんのところの伝統を語られてもな・・・

168 :NAME IS NULL:2009/04/01(水) 11:20:19 ID:???
まぁ実際問題Webサイトの大多数はMySQLだろうけどね

169 :NAME IS NULL:2009/04/01(水) 11:33:32 ID:???
まぁ、スレ違いだな

170 :NAME IS NULL:2009/04/01(水) 19:02:50 ID:???
クイズを出すPHPサンプルを弄っているのですが
問題を、AUTO_INCREMENTでIDを増やしつつ追加して
後で一部の問題を削除すると、空のIDでエラーになります。
つめて整理する方法&AUTO_INCREMENTを最後尾から
再スタートする方法はあるのでしょうか?

171 :NAME IS NULL:2009/04/01(水) 19:08:19 ID:???
エスパーだが1〜最大IDまでのランダムなIDで出題してるの?
もしそうならORDER BY RAND()とか

172 :NAME IS NULL:2009/04/01(水) 19:41:38 ID:???
そうです。
$id = rand(1, $count[0]);
としているのでハズレを引いていると思います。
ORDER BY RAND()調べてみます。
サンクス

173 :NAME IS NULL:2009/04/02(木) 06:44:19 ID:???
>>170
>質問するときはDBMS名を必ず付記してください。

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

自動採番号の設定値変える方法もDBによるんじゃね

174 :NAME IS NULL:2009/04/02(木) 08:51:36 ID:???
DBMS?

175 :NAME IS NULL:2009/04/02(木) 09:07:21 ID:???
でーたーべーすまねーじめんとしすてむ
ようは、つかってるDBの種類かけと
いろいろあるだろ、ORACLEとかMySQLとかACCESSとか桐とかファイルメーカーとか


176 :NAME IS NULL:2009/04/02(木) 09:14:32 ID:???
だからそれDBじゃなくてDBMS

177 :NAME IS NULL:2009/04/02(木) 09:32:08 ID:???
この場合のDBはDBMSの意味で使ってる
DBMSという用語が理解できるなら文脈でわかると思うが
DBMSとDBの区別がついてない人にとっては、DB=DBMSだからな

DBとDBMSという用語を明確に使い分ける必要はあんまりないんじゃない

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

スキーマとインスタンス、リレーションとテーブルとかと同様に
「似ているようで全然異なる、区別してもらわないと困る」類の
言葉だと思うよ>DBとDBMS

179 :NAME IS NULL:2009/04/02(木) 16:03:47 ID:???
明確に使い分ける方がいいって意見はまあ納得できるんだが
会話は相手に伝わらないことには意味がないからな

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

DBという言葉は割と一般的に使われるが、DBMSという言葉は一般的ではないと思うんだ
そして一般にDBという場合、その多くがDBMSのことだったりすんだよな
俺は今のDBという言葉はDBMSを含んだ広い概念の言葉になってると思ってる

180 :NAME IS NULL:2009/04/02(木) 16:12:44 ID:???
一般にDBという場合はドラゴンボールだろ
この板出来たときから居るけど、最初の1年くらいは
ドラゴンボールのスレが沢山あったんだぜ

181 :NAME IS NULL:2009/04/02(木) 19:49:22 ID:???
実際の会話じゃないんだから
DBMSって言われて知らなかったら調べるだろ

相手をばかにしてるだけ

182 :NAME IS NULL:2009/04/02(木) 19:59:22 ID:???
スルーで良いだろ
わざわざ相手にする必要なし

183 :NAME IS NULL:2009/04/02(木) 20:25:20 ID:???
2003年に立ったドラゴンボールスレがまだ残ってるわけだが

184 :NAME IS NULL:2009/04/02(木) 20:42:00 ID:???
>一般にDBという場合はドラゴンボールだろ
一般の友人のブログで「DBが〜…」とか書いてあって、「え!?なんでRDBMS知ってんだ!!」と驚いて本文を読んだらウボォー('A`)

185 :NAME IS NULL:2009/04/02(木) 22:39:10 ID:???
>>179
お前がDBMSをDBと書くことによって相手に伝わってないじゃん
174で突っ込みもらってすら173のおかしさに気づけない時点で理解できてないことが見え見え

186 :NAME IS NULL:2009/04/03(金) 12:07:39 ID:???
そうだな。DBMSがわかるやつが、あの文で通じないとはたしかに理解できてなかった
あと、おもったより、>今のDBという言葉はDBMSを含んだ広い概念の言葉になってると思ってる
が支持されてないようなので、今後は考えを改めることにするわ

いいかげんスレ違いなのでこの話題は俺はここまでにする

187 :NAME 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"以外の全ての内容】

188 :NAME IS NULL:2009/04/04(土) 23:52:43 ID:???
サブクエリ

189 :NAME 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
みたく書くしかないかな

190 :187:2009/04/05(日) 00:34:23 ID:???
>>189
ありがとうございます。とても助かりました。
標準SQLですので、後者を使わせていただきます。

191 :NAME IS NULL:2009/04/05(日) 00:44:22 ID:???
その解だとID毎に全部書かなきゃならんのだが・・

192 :NAME 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

193 :NAME 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;


194 :NAME IS NULL:2009/04/05(日) 10:18:33 ID:???
おまいら家のPCにDB環境いくつある?

195 :NAME IS NULL:2009/04/05(日) 11:04:04 ID:???
Oracle Express EditionとDB2 Express-C

196 :NAME IS NULL:2009/04/05(日) 11:16:04 ID:???
何故そこにMS SQLの無料エディションが無い。

197 :NAME IS NULL:2009/04/05(日) 11:26:19 ID:???
・会社で使ってないから
・Linuxに乗らないから

198 :NAME IS NULL:2009/04/05(日) 11:30:37 ID:???

    ∧__∧
    ( ・ω・)   Windows以外はいやDOS
    ハ∨/^ヽ
   ノ::[三ノ :.、
   i)、_;|*く;  ノ
     |!: ::.".T~
     ハ、___|
"""~""""""~"""~"""~"

199 :NAME IS NULL:2009/04/05(日) 14:50:39 ID:???
>194

おれっくらいの達人になると脳内DBだぜ、
脳内DBは10行3列までしか格納できないのがちょっと不便。

200 :NAME IS NULL:2009/04/05(日) 15:19:07 ID:???
九九も入らないなw

201 :NAME IS NULL:2009/04/05(日) 16:03:03 ID:???
九九のDB作るには複合インデックスも必要だしね。
ににんがし〜

202 :NAME IS NULL:2009/04/05(日) 16:38:35 ID:???
>>197
スレチだがDB2は日本では普及してるの?
SQLServerの元になったRDBだよね?

203 :NAME IS NULL:2009/04/05(日) 16:40:19 ID:???
SQLServerの元はSybaseですがな。

204 :NAME IS NULL:2009/04/05(日) 16:50:18 ID:???
DB2はIBM関係の仕事してたらまず間違いなく使うことがある
逆にIBMと関係ない仕事してたらまず間違いなく使わない
HiRDBと日立、Symfowareと富士通みたいなもんだ

205 :NAME IS NULL:2009/04/05(日) 16:59:57 ID:???
そんなもんと一緒にすんなって怒られそうだな

206 :NAME IS NULL:2009/04/05(日) 17:59:00 ID:???
>HiRDB
日立系の人から「使ってる?」と聞かれたことがあるけど、「知りません」って答えたら「そうでしょうね」と納得していたのが忘れられない。

207 :NAME IS NULL:2009/04/05(日) 19:11:36 ID:???
うちは、日立の子会社だけど基幹は Oracle だし、
俺自身も使ったことないし。

208 :NAME IS NULL:2009/04/05(日) 20:10:37 ID:???
富士通も日立も普通にオラクルだよw
有名で実績あるからオラクルのほうが入れやすいんだと思う
少々高くても金はあるところにはあるし。

209 :NAME IS NULL:2009/04/05(日) 23:54:48 ID:???
しかしIBMはそういう場合でもDB2を入れてくる会社なんだぜ

210 :なまえ:2009/04/06(月) 00:20:55 ID:???
SQLの基礎はIBMの研究所で確立されたと聞いたことがあるぞ
そうなると、DB2はもっとも由緒あるRDBMSといえるんじゃないかな

ま、由緒があるから機能や性能が優れてるとは限らんがw

211 :NAME IS NULL:2009/04/06(月) 01:42:25 ID:???
>210
由緒はある、だが、パクって磨いて売りまくったのはオラクル。

212 :NAME IS NULL:2009/04/06(月) 22:39:19 ID:???
よろしくお願いします。
初めてaccess触ってるもんでさっぱりです・・・

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


例)

ID data 起算日 終了日
--------------------------
001 A 20080101 20080110 ←10日分出力したい
001 B 20080201 20080220

213 :NAME IS NULL:2009/04/06(月) 22:42:13 ID:???
(´・ω・`)…

214 :NAME IS NULL:2009/04/06(月) 23:03:48 ID:???
>212
そのテーブルの日付範囲を条件にして他のテーブルから日付範囲分のレコードを取ってきたいってことか?

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

でOK。

解説は↓↓↓↓↓がする

215 :NAME IS NULL:2009/04/06(月) 23:35:28 ID:???
他のテーブル指定してねーじゃん

216 :NAME IS NULL:2009/04/06(月) 23:42:53 ID:???
>>214
抽出元は、このテーブルです
1行目の起算日から終了日までだと、日数が10日あるので10行表示するようなイメージです

217 :NAME IS NULL:2009/04/06(月) 23:45:34 ID:???
limitでいいじゃん

218 :NAME IS NULL:2009/04/06(月) 23:57:18 ID:???
>>216
20080101
20080102
.
.
20080110
ってことか? 標準的なSQLでは無理。

219 :NAME IS NULL:2009/04/06(月) 23:59:52 ID:???
まず、日本語で説明できるようになろうな。

220 :NAME IS NULL:2009/04/07(火) 00:03:51 ID:???
>>218
やっぱ、ダメか・・・
ありがとうございました。他の方法を考えてみます

221 :NAME IS NULL:2009/04/07(火) 00:21:15 ID:???
上司に説明してもらった方が解決しそう。

222 :NAME IS NULL:2009/04/07(火) 11:42:38 ID:???
変数に代入して+1してけばいいんじゃないの?

223 :NAME IS NULL:2009/04/07(火) 12:42:53 ID:???
BETWEENとかそういう話じゃなくてか

224 :NAME IS NULL:2009/04/07(火) 12:47:57 ID:???
RDBMSによってはできるな。
accessはわからんが

225 :NAME IS NULL:2009/04/08(水) 05:06:40 ID:???
テーブルをカラム A (ユニーク) でソートした時、A の値が 'HOGE' の行の
出現インデックスを取得するような SQL は書けますか?
先頭からループでブン回して出現位置を見つけるしかないんでしょうか?

Apache の Derby です。

226 :NAME IS NULL:2009/04/08(水) 05:39:49 ID:???
>>225
'HOGE' が何行目にあるか? ってことかな?
ApacheのDerbyは使ったことないが、
SELECT count(*) FROM Table WHERE A <= 'HOGE';
でいけるんじゃね?

227 :NAME 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でインデックスとゆう用語は勘違いされるからむ

229 :NAME IS NULL:2009/04/08(水) 23:30:53 ID:???
ランクが知りたいんじゃないの?

230 :NAME IS NULL:2009/04/09(木) 11:33:54 ID:???
・oracle11g
・あろテーブルで、複数のカラムで一つのIDを持っているんですが、
 そのIDの重複の有無を調べるSQLを教えてください。
 型は全てnumberです。

231 :230:2009/04/09(木) 12:13:58 ID:???
勘違いしててすぐ解決しました。

232 :NAME IS NULL:2009/04/12(日) 23:57:56 ID:???
文字化けが直らない。
疲れ果てて質問も出来ない。
いじょう

233 :NAME IS NULL:2009/04/13(月) 00:06:52 ID:???
どのみちこのスレで文字化けの質問なんかしてもスレ違いだ
いじょう

234 :NAME IS NULL:2009/04/13(月) 00:36:36 ID:???
DB2は迷ったらUTF8、他のDBもおすすめの日本語文字コードがあります。

235 :NAME IS NULL:2009/04/13(月) 22:53:53 ID:z55NoKLw
達人の俺になんか問題を振ってくれ

age

236 :NAME IS NULL:2009/04/13(月) 23:02:01 ID:???
逆に今時どのDBでもUTF8だろ
Accessとかならともかく

237 :NAME IS NULL:2009/04/13(月) 23:27:03 ID:???
Accessは手軽にアプリケーションが作れるので気に入った。

238 :NAME IS NULL:2009/04/13(月) 23:45:35 ID:???
JIS 第一なら概ねあいうえお順だから JIS 順ソートが仕様になってる所は
UTF-8 使えないんじゃないの。
今時の DB は UTF-8 でも JIS 順ソート指定とかできるんか知らんが。

239 :NAME IS NULL:2009/04/13(月) 23:47:36 ID:???
UTF-8でSQLに渡してPHPから呼んで表に入れたら化けた。
SQLに渡したリストを表示するPHPは化けない。
化けてない方はブラウザもUTF-8で表示してる。
化けてる方はブラウザはEUC-JPで表示しててUTF-8に変更すると
SQL関係ない文字が化ける。
表作成のコードは一緒なのに。
もう嫌。

240 :NAME IS NULL:2009/04/13(月) 23:52:44 ID:???
なんだよ SQL って・・・

241 :NAME IS NULL:2009/04/13(月) 23:57:04 ID:???
IBMの研究所の偉い人が考えた言語

242 :NAME IS NULL:2009/04/14(火) 00:41:47 ID:???
仮にMySQLならset names スクリプトの文字コード やっちゃえよ

243 :239:2009/04/14(火) 14:12:12 ID:???
PHPファイル自体をUTF8で保存したら文字化け直った。

244 :NAME IS NULL:2009/04/14(火) 14:46:54 ID:???
要するに文字コード変換一切せずに突っ込んでたって事じゃないか

245 :NAME IS NULL:2009/04/14(火) 16:03:35 ID:???
   ∧∧
  ヽ(・ω・)/ ズコー
 \(\ ノ
、ハ,、  ̄
 ̄"

246 :NAME IS NULL:2009/04/14(火) 20:21:29 ID:???
何にせよスレ違い。二度と来んなよー

247 :NAME IS NULL:2009/04/14(火) 21:11:16 ID:???
where aaa<>'5'

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

nullは'5'ではありませんので取ってくれよ、と思っています。


248 :NAME IS NULL:2009/04/14(火) 21:16:21 ID:???
>>247
DBにおけるNULLの扱いを勉強しましょう。

249 :NAME IS NULL:2009/04/14(火) 21:19:34 ID:???
>>247
null はどう評価しても null。つまり、true ではないから。

250 :NAME IS NULL:2009/04/14(火) 21:24:18 ID:???
>249
あんがと。

もうひとつ質問

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

aaa is null

aaa =''

は同じですか?

251 :NAME IS NULL:2009/04/14(火) 21:28:02 ID:???
>>250


252 :NAME IS NULL:2009/04/14(火) 21:33:09 ID:???
>>250
同じ扱いのDBMSもあったような気がする・・・Oracleだったかな?

253 :NAME IS NULL:2009/04/14(火) 21:34:12 ID:???
INSERT INTO ('')
INSERT INTO (NULL)

両者は同じになるのですが、どう理解しればいいでしょうか?

254 :NAME IS NULL:2009/04/14(火) 21:37:32 ID:???
>>250
DB による

255 :NAME IS NULL:2009/04/14(火) 22:35:24 ID:???
>>250
各RDBMSで挙動が異なる。
SQLの解説書によく出てくるよ。

256 :NAME IS NULL:2009/04/14(火) 23:24:22 ID:???
>>253
syntax error

257 :NAME IS NULL:2009/04/14(火) 23:26:04 ID:???
>256
なるほど。
どおりで同じわけだ。

258 :NAME IS NULL:2009/04/14(火) 23:37:17 ID:???
>>253
とりあえず、ここ読んでらっしゃ〜い
ttp://www.geocities.jp/mickindex/database/db_3vl.html

259 :NAME IS NULL:2009/04/14(火) 23:47:13 ID:???
よくある質問1の日付が未来まである場合のテーブルで、
今日未満の最新レコードを抽出する事は可能ですか?

260 :NAME IS NULL:2009/04/14(火) 23:50:22 ID:???
>>259
はい

261 :NAME IS NULL:2009/04/15(水) 00:05:41 ID:???
DATE型の大小関係で、「今日」という日付を使って
今日 <= MIN(DATE_column)

すべての日付の最小値をとり、今日を含む今日よりも新しい日付を抽出する。

262 :NAME IS NULL:2009/04/15(水) 00:55:28 ID:???
between句について質問です。(初心者です)
code between '123456' and '123459' で範囲指定した検索を行うと
検索結果に code 1234 も含まれます。 なぜでしょうか?
また、数値型に変換して cast句を使用したのですが、code に全角数字が
含まれる為、SQLエラーとなりうまくいきません。
何かよい方法は無いでしょうか?

263 :NAME IS NULL:2009/04/15(水) 00:59:43 ID:???
全角半角混在とは、、、
しょうがないから半角に統一するストアドファンクション作ろう

264 :NAME IS NULL:2009/04/15(水) 01:08:06 ID:???
>>263
ありがとうございます。
ストアドファンクションって何ですか?ってレベルなんですけど
調べてみます。
ちなみに、code には 「-」 も含まれます。。。。

265 :NAME IS NULL:2009/04/15(水) 01:22:27 ID:???
>>262
>>1

まあ code 1234 が '123456'より大きく'123459'より小さいと判断されてるのだろう
文字列の比較ルールは処理系や文字コードによるのでこれ以上はなんともいえない


266 :NAME IS NULL:2009/04/15(水) 01:35:00 ID:???
全角が入るって・・・エンドユーザの入力をそのままSQLに渡してるのか?
SQLインジェクションとか、別のとこで心配になってきたぞ。
ストアドで解決するよりも、ホストアプリ側でバリデーションすべきだと思う。

267 :266:2009/04/15(水) 01:42:32 ID:???
・・・と書いてから気づいたが、既存のレコードが全角なのね、勘違いしてた。
まあ、既に入っちまったもんは仕方ないか。
>>262 の使ってるDBが何か知らんが、「照合順序」がキーワードになるんじゃないかな。

268 :NAME IS NULL:2009/04/15(水) 02:22:41 ID:???
使っているDBはSQLSERBER2005です。照合順序をJapanese_binに設定しても同様にエラーがでます。。。

269 :NAME IS NULL:2009/04/15(水) 02:47:18 ID:???
>>268
全角半角を区別したくないんなら、Japanese_CI じゃないのか?

270 :NAME IS NULL:2009/04/15(水) 07:43:08 ID:???
質問です。

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

よろしくお願いします。

271 :NAME IS NULL:2009/04/15(水) 13:50:48 ID:???
本来のもの以外は全く使えないって正月番組の英語禁止ゴルフかよ

272 :NAME IS NULL:2009/04/15(水) 15:12:05 ID:???
SQL Serverで
'1234' between '123456' and '123459' が真になるような
照合順序なんて無いと思うので、何かがおかしい
DBCC CHECKTABLEとかって2005でも実行できるのかな?


273 :NAME IS NULL:2009/04/15(水) 19:14:41 ID:???
>>270
Oracleだとalter session set flagger=fullとかやるとチェックできる。
他のDBMSでも似たような機能はあるんじゃない?(知らんけど)

274 :NAME IS NULL:2009/04/15(水) 20:26:48 ID:???
>>270
SQL92の良いリファレンスを買って手元に置く方が良いよ。
プロ野球養成ギプスじゃあるまいし、癖を直すにしても頭で
理解して直さないと意味がないでしょう。

275 :NAME IS NULL:2009/04/15(水) 20:36:27 ID:???
でもちょっとチューニングしようと思ったら SQL92 じゃどうしようもならんよね。

276 :NAME IS NULL:2009/04/15(水) 20:45:50 ID:???
BNFで充分だろ
ttp://savage.net.au/SQL/sql-92.bnf.html
まあ、BNFじゃ構文しか分からんが

277 :270:2009/04/15(水) 23:33:11 ID:???
ご意見ありがとうございます。
参考にします。

278 :NAME IS NULL:2009/04/16(木) 08:24:06 ID:???
質問です。
COLUMN Aの値がa1のところをa2に変えたいと思っています。
ただし制約があってCOLUMN AとCOLUMN Bでユニークなインデクスを作っているので
COLUMN Bの値がかぶらないようにチェックしないといけません。
COLUMN Bがかぶらない行だけを変える方法、あるいはCOLUMN Bがかぶる行を削除する方法を
教えてください。

279 :NAME 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

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

よろしくお願いします。

280 :NAME IS NULL:2009/04/16(木) 14:10:38 ID:???
そのサブクエリ自体が間違っているような・・・
ipと日付が同じでvalueが異なる行があった場合は
どうするのだろうか。

281 :NAME IS NULL:2009/04/16(木) 14:19:44 ID:???
>>279
select ip, date(created), avg(value) from test group by ip, date(created)
これで事足りるんじゃないの?

282 :279: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

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

いろいろ間違ってるかもしれません;

283 :279:2009/04/16(木) 14:24:53 ID:???
>>281
またまた説明が足りませんでした・・・
同じipで同じ日付を重複として取り除いたものから、
valueの平均をbidごとに集計したかったのです・・・

284 :NAME IS NULL:2009/04/16(木) 14:51:18 ID:???
とりあえずそのサブクエリは文法エラーで評価出来ないと
言うことは意識しているかな。GROUP BYを使った場合は
無頓着に*は使えないよ。

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

最後に、やっぱりサブクエリ使わないと難しいと思う。
使えない理由がDBMSの仕様であるなら、DBMSの名前と
バージョンを書くべし。

285 :NAME IS NULL:2009/04/16(木) 20:02:54 ID:???
サブクエリ使えないなら一時テーブル使えば?


286 :NAME IS NULL:2009/04/16(木) 21:02:09 ID:???
達人の俺(まいど脳内DBの俺)が教えてやろう

>278
そーゆうとき、まずUPDATEするまえにDECODE関数を使って'a1'を'a2'に変えた表を作る
その表と元の無編集の表をキーで付き合わせればいいんだよ。
ポイントはdecode、not exists、from句に元の無編集の表と編集した表だ。
最終的にはDML一発でやりたい事ができるぞ。少なくとも俺の脳内では。


287 :NAME IS NULL:2009/04/16(木) 21:07:33 ID:???
>279
達人の俺がパッと見た感じではごく普通の難易度に見えるが
俺の脳内DBは3列10行までしか格納できないのでパス。


288 :NAME IS NULL:2009/04/16(木) 21:11:01 ID:???
aid|bid|value|ip|created

bid|ip|created

なら教えてあげてもいい。

289 :NAME IS NULL:2009/04/16(木) 21:22:17 ID:???
達人の脳内 DB はヒープどれくらい割り当ててるんですか?

290 :NAME IS NULL:2009/04/16(木) 21:35:05 ID:???
俺っくらいの達人になると

ひーぷ()笑

だ。決してヒープという用語を知らないわけではないぞ。

291 :NAME IS NULL:2009/04/17(金) 01:43:03 ID:???
良く解りませんがヒップへのアクセス権はguest可です

292 :278:2009/04/17(金) 02:44:23 ID:???
達人様ありがとうございました。
decodeが使えなかったのでcaseを使って実現しました。
結局様々な事情で実装は別の方法を取ったのですが
勉強になりました。

293 :NAME IS NULL:2009/04/17(金) 03:29:36 ID:???
公開したらヒップに SQL Injection 喰らいました。

294 :NAME IS NULL:2009/04/17(金) 03:43:47 ID:???
アクセス権はつけてるけどINSERT権限はつけてないから無問題

295 :DBの達人:2009/04/17(金) 05:56:38 ID:???
おはよう!

296 :NAME IS NULL:2009/04/17(金) 08:26:10 ID:uJNeHSTZ
DBからデータを取り出すときに、
今週のものだけを取り出すにはどのようにすればよいのでしょうか?
7日以内ではなく、「今週」のものなのですが。

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

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

初歩的なことかもしれませんが、どうかお願いします。

297 :NAME 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)

298 :297:2009/04/17(金) 10:07:54 ID:???
見逃してた。下の質問だけど、更新日時が今日より3日以内って意味かな?
WHERE date_column BETWEEN CAST(NOW()-INTERVAL'3 days' AS DATE) AND CAST(NOW() AS DATE);

299 :297: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);

300 :296:2009/04/17(金) 15:48:09 ID:???
>>297-299

ありがとうございます!
試してみます。

301 :NAME IS NULL:2009/04/17(金) 19:44:40 ID:???
普通date_truncとか類似の関数で週単位の切り捨てもできるだろ

302 :達人:2009/04/17(金) 23:06:00 ID:???
俺が出るまでもないな。

303 :NAME IS NULL:2009/04/18(土) 02:23:43 ID:???
いまだに達人と聞くと、シューティングを思い出してしまう

304 :NAME 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 個人情報
というのを社員テーブルに追加した方がいいですか?


305 :NAME IS NULL:2009/04/18(土) 05:34:25 ID:???
社員番号がkeyなので社員テーブルを参照するのがいい。
つまり前者の制約でいいと思う。
でも、支店番号は社員テーブルにあったほうが良くないか?

306 :NAME IS NULL:2009/04/18(土) 05:47:55 ID:???
一つのファクトは同じテーブルに収めろよ

307 :NAME IS NULL:2009/04/18(土) 06:17:36 ID:???
>>304
そのテーブルの関係が1-0か0-1かによって決まる。
どっちかわかっていないなら付けられない。

308 :NAME IS NULL:2009/04/18(土) 20:02:40 ID:???
1つのテーブルに纏めるべきだとは思うけど、
参照制限をかけたいがためにわざと別テーブルにしてる・・・とかか?

309 :NAME IS NULL:2009/04/18(土) 22:14:51 ID:???
オッス達人だ。

>304
ある社員の

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

どっちがイイのよ?

310 :NAME IS NULL:2009/04/18(土) 22:35:53 ID:???
なんか変なのが居ついちゃったな

311 :NAME IS NULL:2009/04/19(日) 02:00:42 ID:???
つか、それSQLの話じゃないし、設計の話はスレ違いだ

312 :NAME IS NULL:2009/04/19(日) 05:12:30 ID:gQJBptjI
テーブルのカラム名でDATE(もちろん意味は日付です)というのを使いたいんですが、DATEというデータ型とかぶってしまいます。
プロの皆さん方は、日付という意味のカラム名はどうされてますか?


313 :NAME IS NULL:2009/04/19(日) 05:38:03 ID:???
前になんか付ける。更新日ならUPD_DATEとか。
つかそれもこのスレじゃないな。

314 :NAME IS NULL:2009/04/19(日) 05:53:22 ID:gQJBptjI
ついでに後1個だけ。
カラム名は、大文字も小文字も区別されないと思っておいたほうがいいですよね?


315 :NAME IS NULL:2009/04/19(日) 19:59:55 ID:???
dbmsによる


316 :NAME IS NULL:2009/04/20(月) 00:55:55 ID:???
>>314
大文字か小文字だけを使うように設計するべき。

317 :NAME IS NULL:2009/04/20(月) 01:41:21 ID:???
Oracleなら全部大文字、MySQLやPostgreSQLは小文字って感じの規約が多いかな。
一応理由があって、Oracleは内部の情報としてカラム名やテーブル名を
大文字で管理してるから、大文字で最初から書いた方が効率が良くて、
逆にMySQLとかPostgreSQLは小文字で管理してるから逆になる。
ただどっちにしろSELECTとかINSERTみたいなコマンド部分は
大文字で書くのが一般的。
ただ、厳密な意味で大文字小文字を区別するってDBMSはあんまり無いと思う。

318 :NAME 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

319 :NAME IS NULL:2009/04/20(月) 04:46:24 ID:???
アだとジャガイモが在庫切れで非表示にしたい料理の他に
ジャガイモを元々使わない料理も出てこなくなる

320 :NAME IS NULL:2009/04/20(月) 05:55:14 ID:???
技術系の質問スレって「そんなDB使う奴がバカ」「そんなテーブル設計する奴がバカ」
みたいな、何の解決にもならない根本否定するだけのスレをよく見掛けるけど、ここは
それがあまりない。おまいら「DB屋は今そこにあるDBを何とかしなきゃいけない」って
よく分かってるプロだなーといつも感心する。

321 :NAME IS NULL:2009/04/20(月) 06:08:56 ID:???
ひんと: スルー力

322 :318:2009/04/20(月) 10:47:49 ID:???
問題文3行目の「使用する食材全てについて在庫が〜」というのを見逃してました。
しっかり問題文を読まねば・・・・・・
解説ありがとうございました。

323 :NAME IS NULL:2009/04/20(月) 10:53:59 ID:???
>>317
""でくくると大文字小文字を区別するけど、くくらないとすべて小文字扱いになるよ、PostgreSQLは
他のは知らないけど、似たようなもんじゃないのかなあ。

324 :NAME IS NULL:2009/04/20(月) 12:46:39 ID:???
>>321
何度見ても「するーか」と読んでしまう私のSELECT文

325 :NAME IS NULL:2009/04/20(月) 13:43:10 ID:???
ユンカース

326 :NAME IS NULL:2009/04/20(月) 18:26:07 ID:???
スツーカ

327 :NAME IS NULL:2009/04/20(月) 18:31:38 ID:???
暴力二男

328 :NAME 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」でオッケー牧場。

329 :NAME IS NULL:2009/04/20(月) 21:58:19 ID:???
意味の無い返答はやめていただきたい。

330 :NAME 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なのでしょうか?

よろしくご教示お願い致します。


331 :NAME IS NULL:2009/04/21(火) 02:46:51 ID:???
>>330
http://dev.mysql.com/doc/refman/5.1/ja/case-statement.html

332 :NAME IS NULL:2009/04/21(火) 02:51:13 ID:???
いや単に前者がnull+1でnullになってるからだろ

333 :>>330:2009/04/21(火) 03:39:55 ID:6SQGommS
>>331
>.332
本当にありがとうございました。


334 :sql:2009/04/21(火) 05:28:21 ID:???
select distinct col1, col2, col3 from tablename;
とやると全行表示されるがこの件数だけを取得したい場合は一体どうかけばいいですか?


335 :NAME IS NULL:2009/04/21(火) 05:39:28 ID:???
標準ではないが DB によっては limit 20 とか fetch first 20 rows only とか
追加で書けたりする。DB の SQL リファレンス参照。

336 :NAME IS NULL:2009/04/21(火) 06:12:41 ID:???
select count(*) from tablename group by col1, col2, col3;
じゃないの?

337 :336:2009/04/21(火) 06:20:06 ID:???
寝ぼけてるな俺・・・
select count(*) from (select distinct col1, col2, col3 from tablename);

338 :NAME IS NULL:2009/04/21(火) 06:33:26 ID:???
あ欲しいのは件数か。「この件数」→「特定の件数」と勝手に脳内補完してしまった、失礼。

339 :sql:2009/04/21(火) 06:43:13 ID:???
>>337
oracleでは動くのですが、MySQLでは動作しません。なんか違うんでしょうか?
ERROR 1248 (42000): Every derived table must have its own alias

340 :NAME IS NULL:2009/04/21(火) 07:08:01 ID:???
>>339
エラーメッセージの通りじゃないの?(知らんけど。)
select count(*) from (select distinct col1, col2, col3 from tablename) a;

341 :sql:2009/04/21(火) 07:32:37 ID:???
>>340
出来たー!!有り難うございました

342 :NAME IS NULL:2009/04/21(火) 12:35:25 ID:???
MySQLには「SELECTしたものを、n件まで表示する」というのがあって便利だった。


343 :NAME IS NULL:2009/04/21(火) 12:52:45 ID:???
何でもう過去形なんだよw

344 :NAME IS NULL:2009/04/21(火) 14:07:14 ID:???
それ SELECT TOP n とはどう違うの?

345 :NAME IS NULL:2009/04/21(火) 14:10:13 ID:???
limit x となら完全に同じ。
さらに、limit x, y で開始行まで指定することもできて便利・・・だった

346 :NAME IS NULL:2009/04/21(火) 19:08:36 ID:???
>>343
商用でMySQLという案件が無かったから。
自宅で試す程度で、あまり自信が無くてね。

347 :NAME IS NULL:2009/04/21(火) 20:36:56 ID:???
>>343
そりゃ、ORACLEさんに買われて、お先真っ暗ですから

348 :NAME IS NULL:2009/04/21(火) 20:39:16 ID:???
>>346
> 商用でMySQLという案件が無かったから。

OracleのSun買収でこのあたりどうなるかね?
共にSQLを拡張して互換性を取るような動きになると、ありがたいんだけども。

349 :NAME IS NULL:2009/04/21(火) 21:23:55 ID:???
IBM「ちょwwwwwwwwおまwwwwwwwSQL作ったの俺たちのとこの博士だしw」

350 :NAME IS NULL:2009/04/21(火) 21:26:34 ID:???
>>342
逆にそれできないDBMSって何?

351 :NAME IS NULL:2009/04/21(火) 21:28:21 ID:???
>>350
Derby

352 :達人:2009/04/21(火) 21:47:59 ID:???
グルーピングは体で覚えるんだ
ロールアップまで使いこなせるようになるとGood
お偉いさん達は集計、小計、合計、率、比率、が気になってしょうがない生き物だから

353 :NAME IS NULL:2009/04/22(水) 07:05:44 ID:???
>>352
特に前年比がね〜
めんどうなんだよ!
頭の体操になるけどね


354 :NAME IS NULL:2009/04/22(水) 07:28:21 ID:???
orderみたいに、
そのままカラム名に指定するとエラーになってしまうカラム名を知りたいのですが、
どこかまとめてあるところご存じないでしょうか?

ここで質問していいんでしょうかね;

355 :NAME IS NULL:2009/04/22(水) 07:31:56 ID:???
マニュアルどぞー

356 :NAME 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
みたいな事できたらキモイでしょ


357 :354:2009/04/22(水) 07:39:40 ID:???
>>355
すみません・・・
マニュアルのどこらへんに書いてあるんでしょうか?

>>356
orderとかselectはまだわかるのですが、
keyとかでもエラーになったので・・・
ちなみにMySQLです。

358 :NAME IS NULL:2009/04/22(水) 08:21:23 ID:???
>>354
「SQL 予約語」でググる。

359 :NAME IS NULL:2009/04/22(水) 11:52:01 ID:???
>>357
どこに書いてあるかも聞かないと分からないとは・・・・(驚愕)

360 :NAME IS NULL:2009/04/22(水) 12:36:03 ID:???
自分が聞きたいことが何なのかが分からないことはよくある。

361 :NAME IS NULL:2009/04/22(水) 12:44:10 ID:???
予約語、という言葉を知らないと探しにくいかもなあ

362 :NAME IS NULL:2009/04/22(水) 17:33:23 ID:???
そんなことより僕と踊りませんか

363 :NAME IS NULL:2009/04/22(水) 19:53:06 ID:???
予約語でも”で括ると使えちゃったりするかも

364 :NAME IS NULL:2009/04/22(水) 20:54:11 ID:???
``じゃなくてか

365 :NAME IS NULL:2009/04/22(水) 21:20:42 ID:???
(''ω'')ふひひ さーせん

366 :NAME IS NULL:2009/04/22(水) 22:45:19 ID:???
いいから舐めろ

367 :NAME IS NULL:2009/04/23(木) 07:11:30 ID:???
どのていど消費されるかわからない主キー(オートインクリメント)のデータ型を
とりあえず全部BIGINTにしておくというのは、
なにかデメリットはありますか?

ほかにもLONGTEXTなども、多めに取っておくと何か不都合があるのでしょうか?

368 :NAME IS NULL:2009/04/23(木) 08:24:59 ID:???
>>367
MySQLだよね?
BIGINTのデメリットは消費データ量が4bytesから8bytesになること
LONGTEXTはMEDUIMTEXTにくらべてカラムヘッダが2bytesから4bytesになる

まあ2bytesとか4bytesをケチケチしなくていいと思う

369 :NAME 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

370 :NAME IS NULL:2009/04/23(木) 12:21:51 ID:???
>>369
joinの左外部結合(右外部結合)

該当する行にはデータが、該当しない行にはNULLが入る。
「---」というデータが作りたいなら、置換してください。

371 :369: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などにできないのでしょうか?

372 :NAME IS NULL:2009/04/23(木) 12:57:13 ID:???
- --- --- yyyだけ見ると1 a bbb yyyなのか1 a ccc yyyなのか
わからないからねぇ。
>>369の結果テーブルは順序を持っている事になるから、結構
難しいと思う。

373 :NAME IS NULL:2009/04/23(木) 15:32:34 ID:???
うーんお手上げです。
1回限りのデータなら、Excel使って手でデータ作った方が早いと思います。

374 :NAME 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でできないこともないだろうけど、俺ならホストアプリ側で制御かな。
ホストアプリのメモリで扱いきれないデータ量なら、表示用の別テーブルを作成する。

375 :NAME IS NULL:2009/04/23(木) 20:32:18 ID:???
>369

達人の出番だなw

376 :NAME IS NULL:2009/04/23(木) 21:15:37 ID:???
>>369
row_number()が使えるなら
1じゃなかったらnull、的な感じでいけると思う

377 :NAME IS NULL:2009/04/23(木) 21:20:22 ID:???
row_numberでできるけどSQLでやることじゃないよなw

378 :NAME 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


380 :NAME 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

382 :NAME IS NULL:2009/04/23(木) 22:20:29 ID:???
Oracle厨房の心のよりどころDUALw

383 :NAME IS NULL:2009/04/23(木) 22:22:56 ID:???
買収されたから、MySQLもDUALが強要されるように改悪されるかもしれんな。

384 :NAME IS NULL:2009/04/23(木) 22:27:24 ID:???
SCOTT, TIGER が入る日も近いな。

385 :NAME IS NULL:2009/04/23(木) 22:36:56 ID:???
まぁ、別にいいんじゃない?困る人は少ないと思うし

386 :NAME 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。センスいい。

388 :NAME IS NULL:2009/04/23(木) 23:17:54 ID:???
しかし、本当にSQLに向いてない仕様だなw

389 :NAME IS NULL:2009/04/23(木) 23:48:28 ID:???
達人の
”ひとつ前の行のレコードと比較する”
ってテクはSQLでやれる事の可能性が広がったわ
ってかホントにできんの?

390 :NAME IS NULL:2009/04/24(金) 00:17:55 ID:???
>>389
サブクエリに任意に連番を振ることが可能なら、可能だとは思う
思うが、今回の質問のようなものは俺ならやらない
グループインジケーションはクライアントアプリの仕事だ
ちゃんとしたレポートツールとかなら、そのぐらいの機能は大抵あるしな

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

partitionは使ったことない(というか使えるDBMS使ってないw)からよくわからん

391 :NAME IS NULL:2009/04/24(金) 00:28:05 ID:???
>>389
やりたい事がそれであればlag関数でスッキリ実現可能。

ただ>>369をSQLで実現しようとすべきでは無いってのは自分も同意

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

テーブルの中にSQLを格納してあってSQLでSQL文を取り出すシステムとかもあるんだぜ
(データディクショナリとかそーゆーのじゃないくて)

393 :NAME 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ではどのようにやるのが常套手段なんでしょうか…

394 :NAME IS NULL:2009/04/24(金) 01:55:52 ID:???
副問い合わせの結果をwhileやforeaceで回せばいいのでは

395 :NAME IS NULL:2009/04/24(金) 02:02:51 ID:???
>>394
どもです…ほんとに簡易sqlって感じなんですねぇorz

396 :NAME IS NULL:2009/04/24(金) 04:04:15 ID:???
>>395
version5.xでサブクエリ周りに機能追加なかったけ?

397 :NAME IS NULL:2009/04/24(金) 13:04:25 ID:???
MySQL(InnoDB)をperl-DBIで使ってます。

複数テーブルにわたる更新の場合はオートコミットを切ってトランザクション下で処理するんですが、
これはテーブルロックがかかってる状態ですよね?
ほかのユーザーは該当テーブルについてリードはできるが更新はできない状態なんですよね?
しかし、トランザクション中でもテーブルに書き込みできてるんですが、これはテーブルロックじゃなくて、行ロックを勝手にしてくれてるって事で良いんでしょうか?


398 :NAME IS NULL:2009/04/24(金) 16:35:56 ID:???
InnoDBは行ロックだよ

399 :NAME IS NULL:2009/04/25(土) 06:30:53 ID:???
>>395 >>396
サブクエリのDELETEはversion4.1からサポートしてますよ。

400 :NAME 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個近くになります。
両方をやると、データの冗長性があまりにもひどい気がします。

銘柄ごとでも日にちごとでも検索しまくるのですが、こういう場合どういう
形のテーブルにしておくのがよいでしょうか?


401 :NAME IS NULL:2009/04/28(火) 03:03:27 ID:???
>>400
カラムの意味と関連するテーブルのスキーマも見ないとわからん
あとテーブル設計に関してはスレチじゃないか?

402 :401:2009/04/28(火) 03:05:34 ID:???
こっちで聞いたほうがいいと思う
http://pc11.2ch.net/test/read.cgi/db/1223458453

403 :NAME IS NULL:2009/04/28(火) 03:12:20 ID:aHnBfSXl
すいません、そっちで聞いてみます。


404 :NAME IS NULL:2009/05/09(土) 12:43:28 ID:JoxlLn6y
DELETE * FROM WHERE NAME LIKE "%ii%";
みたいなことをやりたいのですが、DELETEにはLIKEは使えないようなので、
ほかにやり方がないかと思っています。
どうかやり方がないか教えてください。


405 :NAME IS NULL:2009/05/09(土) 12:49:33 ID:???
使えるだろ・・・。どこの DB だよ?

406 :NAME IS NULL:2009/05/09(土) 15:20:12 ID:???
>DELETE * FROM WHERE NAME LIKE "%ii%";
そもそもSQL文が間違ってないか?
DELETE文は「DELETE FROM (テーブル名) WHERE (評価式)」だぞ

407 :NAME IS NULL:2009/05/09(土) 17:24:17 ID:???
DELETE * って DELETE id,nameとかできたら便利だなw

408 :NAME IS NULL:2009/05/09(土) 19:10:13 ID:???
*もいらなく無いっけ?

409 :NAME IS NULL:2009/05/10(日) 16:37:38 ID:???
DELETEする前に、まずSELECT文としてきちんと評価されているかを確認するのが鉄則。
DELETEしたくない行を消したことが何度あったことか_| ̄|○

410 :NAME IS NULL:2009/05/10(日) 16:39:31 ID:???
まあSELECTで表示させてから、SELECT * をDELETEに差し替えるわな

411 :NAME IS NULL:2009/05/10(日) 17:25:38 ID:???
updateにwhere付け忘れた

あああああああああああああ


412 :NAME IS NULL:2009/05/10(日) 17:28:19 ID:???
(*´Д`)⊃ROLLBACK

413 :NAME IS NULL:2009/05/10(日) 18:04:04 ID:???
AUTO_COMMIT がえし!

414 :NAME IS NULL:2009/05/11(月) 09:55:08 ID:???
AccessではDELETE文に*つける。

415 :NAME IS NULL:2009/05/11(月) 10:20:32 ID:???
SQL SERVERの共通テーブル式でノードを辿る再帰クエリーを作成しているのですが、
ルートがループしているところがあります。
ループしている部分のデータの重複を避けたいのですが方法はありますでしょうか?
UNIONやEXCEPTを使用しようと思ったのですがダメでした。

416 :NAME IS NULL:2009/05/11(月) 13:22:01 ID:???
Accessは削除クエリ作ると裏で勝手にDELETE *のSQL文が作られるけど
SQLを手打ちするなら*なしでも普通に通るよ。

417 :NAME 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')
のどれがいちばん効率がいいのかということを、自分で実験して調べるのもいいですけど、先人の知恵を使って勉強したいです。
なにかお勧めの本などを紹介してください。


418 :NAME IS NULL:2009/05/11(月) 20:18:59 ID:???
あなたの言う効率とは?

419 :NAME IS NULL:2009/05/11(月) 20:43:39 ID:???
単純に実在するテーブルで時間計測してみるとかでいいんじゃない?
RDBMSごとの得意・不得意よりも、稼働しているDBの構成に大きく依存する。

しかも正解が他で通用するとも限らない。

420 :NAME IS NULL:2009/05/11(月) 21:01:36 ID:???
普遍的に通用するセオリーみたいなのってほとんどないからねぇ
どこでも通用するものだけに搾ったら本一冊も書けないんじゃない?

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

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

結合(JOIN)するときはテーブルの行数が、少ない行数同士、片方が多い、両方多い等によっても
結合方法などの実行プランが変わるから、実データでいろいろやった方がいい。

422 :NAME IS NULL:2009/05/11(月) 23:14:39 ID:???
DB2では人間が書いたSQL文が、RDBMSで自動的にどう解釈されているかが分かるログがあるよ。
単なるJOINであっても、内部的に挙動が異なる事があるとか、意外と考えさせられた。

今の自分は、自動化できる部分は全部自動化でいいと思ってる。

423 :NAME IS NULL:2009/05/11(月) 23:36:15 ID:???
ってか統計とってチューニングしながら実装しろよ

424 :NAME IS NULL:2009/05/11(月) 23:40:28 ID:???
よろしく、メガドック

425 :417:2009/05/12(火) 00:24:43 ID:???
みなさん、いろいろありがとうございます。
結局、これといった資料はないというのが実情なんですね。

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

ほしかったのはまさにこういうことが載っている本です。
explain でいろいろ調べたりするする前に、こういった先人の知識をあらかじめ知っておいた方がいいだろうと思ったのですが。
残念です。


426 :NAME IS NULL:2009/05/12(火) 00:26:52 ID:???
そのへん知りたかったら
Oracleコンサル雇うしかないかもね
飯の種だからね

427 :NAME IS NULL:2009/05/12(火) 01:25:05 ID:???
>>417
かなり昔の本なら、プログラマのためのSQL って本があったんだが
いかんせん古い

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

というか、スレ違いだな、そういうスレなかったか?w

428 :NAME IS NULL:2009/05/12(火) 03:44:41 ID:???
>>417
最適化のノウハウの背後にある理屈を理解したいのであれば、英語
ず大丈夫ならRaghu Ramakrishnanの教科書がおすすめ。
オプティマイザも含めてデータベースに関わる理論を広く薄く網羅
した本なので、一冊持っておくとデータベースのある部分について
理屈を理解したくなった時にとっかかりとして大変便利なはずです。

429 :NAME IS NULL:2009/05/13(水) 07:18:50 ID:R4pv+GIi
最近SQLの勉強を始めた者です。
VIEWって何のためにあるのかわかりません。結局いくつかのテーブルから自分の見たいカラムを
取ってきてJOINしているだけ(だからSELECTで同じことができるんじゃないか)という感じがするのですが、
VIEWの存在意義って何ですか?どういうケースで使うべきでしょうか?


430 :NAME IS NULL:2009/05/13(水) 09:52:33 ID:???
俺的には、ワンクッションおけるってのが大きい。

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

後で変更の必要があり、Table D と E から View_C を作ることに
なっても、アプリの変更はいらないから。

431 :NAME IS NULL:2009/05/13(水) 20:54:09 ID:???
VIEWしか見れないユーザーであっても、テーブルの特定の行をいくらでも見れる。
(UPDATEやINSERTは不可)

これが大きな利点であると思います。

432 :NAME IS NULL:2009/05/13(水) 21:12:28 ID:???
前スレより転載(VIEWの利点・欠点)

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

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

欠点:
・あとからロジックを追うのが面倒(な場合がある)
・あとからパフォーマンスチューニングするのが面倒(な場合がある)

433 :NAME IS NULL:2009/05/13(水) 21:22:02 ID:raTYNme4
質問させてください。
複合インデックスを作成する際のキーの順番って関係ありますか?
またその場合はカーディナリティの高い順にするべきでしょうか?

よろしくお願いします


434 :NAME IS NULL:2009/05/13(水) 21:40:28 ID:???
>>432
利点の上2つは労力全然減ってないように思うけど
VIEWのSQL考えるかソースに書くとき考えるかの違いだけであって

435 :NAME IS NULL:2009/05/13(水) 22:00:33 ID:???
>>433
カーディナリが高い順が一般的だが、
それがパフォーマンスに影響するかどうかはDBMSによるかな。
なかにはOrcaleのCompress索引のように第1キーのカーディナリが
極端に低い場合専用の索引があったりします。

436 :433:2009/05/13(水) 22:50:51 ID:raTYNme4
>>435
ありがとうございます。
もう1つよろしいですか?
order byで使用する項目も基本的にはカーディナリティ順で良いのでしょうか?
datetime型を想定しています。

すいません。書き忘れてました。
DBMS:MySQL5
です。

437 :NAME IS NULL:2009/05/13(水) 23:28:06 ID:R4pv+GIi
SELECT * FROM A,B WHERE 条件;

SELECT * FROM A INNER JOIN B ON 条件;
って同じですか?


438 :NAME IS NULL:2009/05/13(水) 23:29:57 ID:???
違います。

439 :NAME IS NULL:2009/05/13(水) 23:39:24 ID:R4pv+GIi
ありがとうございます。
どっちのクエリも、AとBの積を求めて、そこから条件を満たすレコードだけを
残すから同じ結果になりませんか?


440 :NAME IS NULL:2009/05/14(木) 20:25:28 ID:???
>>438
where条件で外部結合した場合、評価や結合順序で結果が変わるってのは聞いたことがあるんだが
内部結合でも同様のことが起こりえる?

結果の問題じゃなくて内部の動作の問題だっていうなら、
オプティマイザ次第な所があると思うんだ

441 :NAME IS NULL:2009/05/14(木) 21:13:41 ID:???
>>437の最初のSQLの「条件」と後のSQLの「条件」が同じなら
そもそも前者は結合してない

442 :NAME IS NULL:2009/05/14(木) 21:38:19 ID:???
「条件」は同じって前提でしょ?(A.ID=B.IDとかで。)
前者は結合してないってどういう意味???

443 :441:2009/05/14(木) 21:45:27 ID:???
ああ間違えた。忘れてくれ。

444 :NAME IS NULL:2009/05/14(木) 22:20:28 ID:???
結論: >>437は、「条件」が内部結合条件であるとき、
・結果は同じ
・実行速度は違うかもしれんし同じかもしれん(オプティマイザ次第)

445 :440:2009/05/14(木) 22:22:07 ID:???
>>441,443
条件式の内容が書かれてないから、必ずしも結合に関する条件を
書いてあるというわけじゃないかもしれないがな
>441は直積は結合じゃないって言いたかったんじゃないかと思ったが

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

ただ、実際はオプティマイズ入るから直積とったようなワークなんぞつくらんだろうし、
内部結合においては同じ条件式なら同じ結果になる気がするんだが...ならない例があるかな?

446 :NAME IS NULL:2009/05/14(木) 22:38:43 ID:???
初心者が読んだらいいようなサイトと本を教えてください。

447 :NAME IS NULL:2009/05/14(木) 22:40:51 ID:???
ここかな
http://washitake.com/jp/

448 :NAME IS NULL:2009/05/14(木) 23:19:03 ID:???
>>438の反応は、
結果は同じでも、そもそもそこに書いてあるSQL文は「違います」
というネタ的回答だと流してたわ。

449 :NAME IS NULL:2009/05/15(金) 02:51:17 ID:???
SQL文が違うんだからDBMSによっては
実行プランが異なる可能性もあるし、
実行プランが同一でもその作成過程が異なる、とかの
厳密な意味での「違います」だととったな、俺は。
あと、質問の内容からすると初心者っぽいから、
「結果が同じだからって、短絡的に同じだと思うなよ」と諌めたかったんでは。

450 :NAME IS NULL:2009/05/15(金) 09:56:31 ID:8Je7scRL
sqlStr = "select * from t_member where member_id = ○○";
↓OR
telephone1 = ○○";

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



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

でいいのかな??

452 :NAME IS NULL:2009/05/15(金) 12:34:47 ID:???
アプリ側の実装の問題では?

453 :NAME IS NULL:2009/05/15(金) 13:45:43 ID:???
アプリが何かで答えは変わるな

454 :NAME IS NULL:2009/05/15(金) 14:05:47 ID:8Je7scRL
javaでアプリを作っています。
DBはMYSQL5.0でnetbeansを使用してます。

455 :NAME IS NULL:2009/05/16(土) 13:46:01 ID:???
http://sstkn.blog87.fc2.com/

456 :NAME IS NULL:2009/05/18(月) 16:27:42 ID:???
((レンタルテーブル))
レンタルID PRIMARY KEY,
インベントリID FOREIGN KEY

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

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

上記のようにレンタルテーブルはインベントリテーブルを、インベントリテーブルは映画テーブルをリファレンスしている場合に、
最も人気のある(レンタル数の多い)映画名を抜き出したいです。どのようなサブクエリを書けばいいでしょうか?

457 :456:2009/05/18(月) 18:31:02 ID:???
すみません
上記の問題については出来ました。取り消します

458 :NAME IS NULL:2009/05/20(水) 11:27:51 ID:???
TSUTAYAの中の人だったら嫌だなw 

459 :NAME IS NULL:2009/05/20(水) 12:39:11 ID:???
実際ML見てるとこれ業務そのものじゃないかなぁって質問あるし
あながち無いとは言えん

460 :NAME IS NULL:2009/05/21(木) 01:19:22 ID:216X3HC3
左外結合 右外結合 ってそれぞれ何と読むんですか?
左外部結合、右外部結合のことみたいですが、買った教科書には上記のように記述されていました

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

よろしくお願いします

461 :NAME IS NULL:2009/05/21(木) 01:22:27 ID:???
sage忘れました すみません

462 :NAME IS NULL:2009/05/21(木) 01:29:06 ID:???
ダメだゆるさん

463 :NAME IS NULL:2009/05/21(木) 01:37:14 ID:???
使いどころがわかりやすいよう、業務に即した例を挙げると、
勇者テーブル
・勇者ID
・勇者名

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

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

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

外部結合であれば、戦士であっても名前だけは出てくる。

464 :NAME IS NULL:2009/05/21(木) 01:38:21 ID:???
ありがちな業務だな。

465 :NAME IS NULL:2009/05/21(木) 01:42:06 ID:???
どんなシステムでもその2テーブルは外せないよな

466 :NAME IS NULL:2009/05/21(木) 02:18:54 ID:???
>>460
ひだりがいぶけつごう、みぎがいぶけつごう

467 :NAME IS NULL:2009/05/21(木) 19:16:46 ID:???
>>460
そんなしょうもない教科書は捨てて他のを買った方がいい

468 :NAME IS NULL:2009/05/21(木) 21:24:04 ID:???
ちょっと今1週間習ってて不安があるので質問です
oracleでSQLを勉強してるんですが
いまいち覚えられてない・・・

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

シルバーの本を借りたんだがやったことではあるんだが応用?見たいな感じで
さっぱりすぎてへこんだ

469 :NAME IS NULL:2009/05/21(木) 23:12:24 ID:???
いろいろ遊んでればそのうちに覚える

470 :NAME IS NULL:2009/05/21(木) 23:22:25 ID:???
仕事でやってれば自然と覚えるよ。

471 :NAME 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 すると秒単位で時間がかかります。
インデックスを使用させるにはどうしたらよいでしょうか?


472 :471:2009/05/22(金) 02:11:25 ID:???
>>471 の explain 結果のテーブル名が生のまま出ていましたね。
teditlog は見なかったことにして、txxx と読み替えてください。

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

といった感じですが、インデックスが使用されない原因になっていそうでしょうか。


473 :471: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)) みたいにしないといけないでしょうか。


474 :NAME IS NULL:2009/05/22(金) 04:08:54 ID:???
>>471
8系だと型が完全一致しなくてもインデックス使うみたいだよ

475 :NAME IS NULL:2009/05/22(金) 13:48:07 ID:BGl6oKa6
>>468
シルバーでSQLだと9i?
状況が許せば10gの方がいいと思うけど。
自分的には「現場で使うSQL」(だっけ?)がお勧め

最初うちは、考える+本を見るの繰り返しになるのは
しょうがないんじゃないかな
基礎体力つけないと、なかなか応用力はつかん気がする

476 :NAME 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をうまく使うのかな?と思って試したのですが、思い通りの結果が出ませんでした。

477 :NAME IS NULL:2009/05/22(金) 22:06:20 ID:???
group by groupID
having count(userID) = 1

478 :NAME IS NULL:2009/05/22(金) 22:17:18 ID:???
ばっちりです!
userIDとgroupIDの両方をGROUP BYしていたので
COUNTでうまく数えられなかったようです。助かりました−

479 :NAME 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が入っているものを取り出したいです。


480 :NAME IS NULL:2009/05/23(土) 07:31:25 ID:???
where data1 = 'a' or data2 = 'a' or data3 = 'a'

481 :NAME IS NULL:2009/05/23(土) 08:38:40 ID:???
>>479
SELECT * FROM TableName WHERE 'a' IN (data1,data2,data3);

482 :NAME IS NULL:2009/05/23(土) 11:10:48 ID:???
例を出すなら、希望の検索結果(この場合keyの一覧)も書かないと伝わりにくいかもよ

483 :NAME 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 の前に指定した表、次に後に指定した表 で出力される

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

お願いします

484 :NAME IS NULL:2009/05/24(日) 01:19:35 ID:???
順番気にするなら*使わないからわからん

485 :NAME IS NULL:2009/05/24(日) 01:47:43 ID:???
実装依存入ってくるんじゃないのかなぁ。

ともあれコマンドラインから手打ちする場合はともかく、
プログラムにクエリ埋め込むときは絶対に*使わないから
>>484と以下同文。

486 :NAME IS NULL:2009/05/24(日) 02:00:34 ID:???
>>483
SQLでは、テーブル定義の列の順番は基本的に意味を持たないってのが原則
必要な場合は列リストを書いて指定する

俺の持ってる本ではその順番で出力されるようなことは書いてあるが、
それが定義された動作なのか実装に依存するのかは不明
>>484が言うように、順番を指定したいなら*ではなく列リストを書くべき


487 :NAME IS NULL:2009/05/24(日) 02:01:20 ID:???
>>483に対する答えとしては同意だけど、

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

なんで「絶対」? たいていの言語にはカラム名を配列などの添字で
扱えるから、場合によっちゃ * は十分ありだと思うけど。

488 :NAME 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お願いします
バージョンアップを考えたいと思います

489 :NAME 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標準により対応しているので。

490 :NAME IS NULL:2009/05/24(日) 02:34:45 ID:???
>>489
勉強用に使ってます
ポスグレですか 使ったことがないのでイマイチとっかかりにくいです^^;

わざわざURLありがとうございます 見てみます

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

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

まあ、プログラマ的立場からいえば、プログラム作らす前にDB設計終えとけとw


492 :NAME IS NULL:2009/05/24(日) 09:26:16 ID:p08hoVjs
>>490
本とセットなら、SQL鯖かOracle+現場で使うSQLがいいと思う

PostgresベースのSQL勉強用の本、あまりいいのがない気がする
#MySQLも同じ・・・・
#単なるお勉強しました じゃなくてその後の業務でも使えそうな本ね

493 :NAME IS NULL:2009/05/24(日) 16:48:38 ID:???
最初にSQL鯖やOracleなんて覚えたら環境依存激しすぎて
ああOracleだったらできるのにこれだからフリーのRDBMSはと愚痴る人間になっちゃうぞ

494 :NAME IS NULL:2009/05/24(日) 16:56:26 ID:???
そんなん何で始めても一緒。本人の資質次第だよ。
Postgresとかで始めても、やっぱり「Oracleは環境依存が激しすぎて」なんて
愚痴るようになる人だっているわけだし。

495 :NAME IS NULL:2009/05/24(日) 17:14:34 ID:???
う〜ん、もめていますが、>>489で書いたのは
>あと目的がシステム開発じゃなくてSQLの勉強なのであれば

と限定した上で、

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

と書いたのですが。最大公約数としての標準SQLを学ぶので
あればMySQLよりPostgresがベターと言うだけの話であって、
システム開発にまつわる個別の実装の方言の問題はとりあえず
保留、で良いのではないでしょうか。
(参考書の書き方の問題もありますが。実践なんちゃら系の本は
標準と方言をちゃんと区別してないことが多いですし)

496 :NAME IS NULL:2009/05/24(日) 17:26:53 ID:???
現場で使うSQLがそもそも標準SQLじゃなくてOracle/SQLServer依存なんだから駄目だろ

497 :NAME IS NULL:2009/05/24(日) 17:32:34 ID:???
いや、だから現場で使うとは誰も言っていないじゃないですか。

498 :NAME IS NULL:2009/05/24(日) 17:34:21 ID:???
どうでもいいスレ違いはやめにして、次の質問どうぞー

499 :NAME IS NULL:2009/05/24(日) 18:29:24 ID:p08hoVjs
8.4からCTEも使えるし、そう違うとは思えないんだが>管理系は別
細かい部分の差異の読み替えは、慣れだしね
どんな時にどうすればいいのか、の考え方の方が重要でしょ?

500 :NAME IS NULL:2009/05/24(日) 18:51:00 ID:???
>>497
"現場で使うSQL"っていう書籍名

501 :NAME IS NULL:2009/05/24(日) 22:05:42 ID:???
こういう場面で一度も話題に上らないDB2( ´・ω・)カワイソス

502 :NAME IS NULL:2009/05/24(日) 23:45:23 ID:???
Sybaseより見ないからなぁDB2

503 :NAME IS NULL:2009/05/24(日) 23:47:34 ID:???
次期バージョンでは、PL/SQL が使えるらしいぞ

504 :NAME IS NULL:2009/05/25(月) 00:05:18 ID:???
うん。IBM社内的にもv9.xからv10.xになればいいじゃん、という声があったほど大きく変わった。
なのに「v9.7」

505 :NAME IS NULL:2009/05/25(月) 01:18:03 ID:???
PL/SQL使うならOracleでいいじゃんみたいな

506 :NAME IS NULL:2009/05/25(月) 07:43:45 ID:+IuRrIp9
Oracleからの移行狙いなんだろうね
商用のpostgresにも、そういうのなかったっけ?

>>504
DLして試してみたいかも>後一ヶ月くらいか
Express9.5 CentOS に入れて放置だわw

507 :NAME IS NULL:2009/05/25(月) 07:48:40 ID:???
ミドルウエアやERPがDB2に対応してくれないとそんなに移行しないだろ
PL/SQLさえ動けばいいわけじゃないんだし

508 :NAME IS NULL:2009/05/25(月) 12:50:32 ID:???
また皆さん痛いところをつく(ノД`)

509 :NAME IS NULL:2009/05/25(月) 13:09:28 ID:+IuRrIp9
その通りなのだが、試してみたくね?
SQL鯖メインだから、かんけーねーといえばそれまでなんだが
現行ではまず使うことないんだけど>DB2

510 :NAME IS NULL:2009/05/25(月) 19:42:08 ID:???
distinctで、かぶり無しで抽出したレコードを空白やカンマ区切りで結合するのは、
どのようにコードをかけばいいでしょうか?


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

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

上では
果物
野菜

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

と1レコードで出したいです。


511 :NAME IS NULL:2009/05/25(月) 20:01:00 ID:???
SQLでは列の数が可変な問合せはできない
ストアド使えばできなくもないけど
アプリでやったほうがいいかと

512 :510:2009/05/25(月) 20:06:02 ID:???
>>511
すいません、
もしややこしいこと書いていればすいません。

上では
果物
野菜

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

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

1レコード2フィールドではないのですが、
前者ならできますでしょうか?

513 :NAME IS NULL:2009/05/25(月) 21:12:46 ID:???
ごちゃごちゃ言っても回答は同じ

514 :510:2009/05/25(月) 21:21:43 ID:???
>>513
・・・orz

515 :NAME IS NULL:2009/05/26(火) 11:42:13 ID:???
煽りじゃなくて、少し入門書を読んだ方が良いね。
今のままじゃ、違和感ばかりたまって、いくらやっても向上しないよ。

516 :NAME IS NULL:2009/05/26(火) 20:37:27 ID:???
>>510
MySQLならGROUP_CONCAT
あとは知らん。

517 :NAME IS NULL:2009/05/30(土) 15:41:24 ID:???
昔Oracleでなんかの上位10個を検索して横に並べるってSQL見たことあるなぁ
どんなんしてたっけなぁ
やっぱプロシージャだったかな

518 :NAME IS NULL:2009/05/31(日) 10:03:59 ID:???
数固定ならSQLだけで何とかならんこともない

519 :NAME IS NULL:2009/05/31(日) 14:49:09 ID:???
LIMIT 1 OFFSET 0
LIMIT 1 OFFSET 1

いやなんでもない

520 :NAME 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文からデータベースをスプレッドシートに表示するにはどういった構文に
すべきでしょうか?


521 :NAME IS NULL:2009/06/01(月) 00:13:36 ID:???
スレ違い
VB スレでも行け

522 :NAME IS NULL:2009/06/01(月) 00:15:27 ID:3TUTRBRK
わかりました。すみませんでした。

523 :NAME IS NULL:2009/06/01(月) 03:06:14 ID:???
SELECT FROM * ふいたwww

524 :NAME IS NULL:2009/06/01(月) 17:45:49 ID:???


525 :NAME IS NULL:2009/06/01(月) 19:00:30 ID:???
辞めちゃった人間の作ったJETデータベースエンジンのMDBを引き継がされて
テーブル名が*とかフィールド名がFROMとかSQLがSELECT [FROM] FROM [*]とかいう
ウンコDBを書き換える仕事はもうイヤだお・・・

526 :NAME IS NULL:2009/06/02(火) 06:28:03 ID:???
FROM SELECT *

527 :NAME IS NULL:2009/06/02(火) 21:07:07 ID:???
博士が泣いておられます

528 :NAME 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]
こういうのは?

529 :NAME IS NULL:2009/06/02(火) 23:15:09 ID:???
なんのナゾナゾだよw

530 :NAME 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とします)

よろしくお願いします。


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

日付操作関数を調べてね。

532 :NAME IS NULL:2009/06/03(水) 22:58:06 ID:???
普通に DATE > '2009-06-00'
又は DATA >= '2009-06-01'
でいいんじゃ?


533 :NAME IS NULL:2009/06/03(水) 23:02:21 ID:???
ヒント:trunc関数で月単位の切り捨てもできる

534 :530:2009/06/03(水) 23:56:43 ID:???
>>531
>>532
>>533
ご回答ありがとうございます。

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

これで永眠できます。

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

SELECT*INTO 1○○ FROM 2○○
1を2に挿入するってことなのですか?
それとも2を1に挿入なのでしょうか?
いまいちわからないので教えてください。初歩的で申し訳ないです

536 :NAME IS NULL:2009/06/04(木) 20:04:55 ID:???
SELECT じゃなくて INSERT じゃねえの?
それともDBMS固有SQL?

537 :NAME IS NULL:2009/06/04(木) 21:09:22 ID:???
>>536
んー固有かどうかはわかないです。
他人の作ったACCESSのVBAコードだったんで・・・

538 :NAME IS NULL:2009/06/04(木) 21:17:57 ID:???
やってみればいいじゃん。

539 :NAME IS NULL:2009/06/04(木) 21:29:39 ID:???
SQL ServerとJetな。
INTO句で指定したテーブル名のテーブルがCREATEされるよ。
FROMがレコード抽出元テーブルの指定。


540 :NAME IS NULL:2009/06/04(木) 21:32:54 ID:???
え マジでこんな書き方許されるの?

541 :NAME IS NULL:2009/06/04(木) 21:39:28 ID:???
マイクロソフトだもん。

542 :NAME IS NULL:2009/06/04(木) 21:41:00 ID:???
SELECT INTO は PostgreSQLにもあるよ。

543 :NAME IS NULL:2009/06/04(木) 21:48:53 ID:???
用途は全く違うがSELECT INTO はoracleにもある

544 :NAME IS NULL:2009/06/04(木) 21:54:09 ID:???
Oracleのはいくらなんでも別物だろう。

545 :NAME IS NULL:2009/06/04(木) 21:57:34 ID:???
PostgreSQLはSELECT INTOよりもCREATE TABLE ASが推奨されてなかったっけ?

546 :NAME IS NULL:2009/06/04(木) 21:58:41 ID:???
Oracleで意味的に同じものは
CREATE TABLE AS SELECT

547 :NAME IS NULL:2009/06/04(木) 22:04:22 ID:???
>>545
これか?
ttp://www.postgresql.jp/document/pg732doc/reference/sql-selectinto.html

548 :NAME IS NULL:2009/06/04(木) 22:23:13 ID:???
>>545
マニュアルにはそう書いてあるけど、>>539と使い方は一緒だね。

549 :NAME IS NULL:2009/06/05(金) 00:45:46 ID:???
どなたか教えてください。
テーブルに
ステータス、登録日、ID、…
といった情報をもつレコードがあるとき

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

ということを一つのSQL文でやりたいのですが、やり方が全くわかりません
助けてください…

550 :NAME IS NULL:2009/06/05(金) 01:18:06 ID:???
order by field(ステータス, 90, 30, 20), 登録日
とかでいいんでなくて?

551 :NAME IS NULL:2009/06/05(金) 07:50:28 ID:???
おお、ステータスはこうやるのですか
ただ、これって、1レコードになるのでしょうか

ちょいと試してみます。出来なかったらまた伺います。。。
イッテキマス

552 :NAME 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文」です。よろしくお願いします。

553 :NAME IS NULL:2009/06/05(金) 17:37:02 ID:???
>>552
逆にすればいいんじゃね。

SELECT name FROM X WHERE 'キーワード' LIKE '%'||name||'%';

554 :552:2009/06/05(金) 18:13:38 ID:5dMjVb/r
ああああああああああああああああああ。
>>553
こんなことできたんですね。ありがとうございます。
(MySQLでは「||」はムリなのでしょうか。
'%'||name||'%'のかわりにconcat('%', name, '%')でイケました。)

555 :NAME IS NULL:2009/06/05(金) 21:04:27 ID:???
テーブル名をワイルドカード指定することは可能でしょうか?
例えば、A0,A1というテーブル名のテーブルがあった場合、
SELECT * FROM A*;
のように、テーブル名をワイルドカード指定して、A0,A1の内容を参照したいのですが。


556 :NAME IS NULL:2009/06/05(金) 21:21:22 ID:???
>>555
無理。

557 :NAME IS NULL:2009/06/05(金) 21:23:01 ID:???
出来たとしてどんな結果を期待してるんだろうな。
UNIONか?

558 :sage: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 を使わないで、上記の条件をどのように記述したらよいのでしょうか

559 :NAME IS NULL:2009/06/05(金) 21:29:42 ID:???
DB設計がとてつもなく汚い悪寒w

560 :NAME IS NULL:2009/06/05(金) 21:33:35 ID:???
スレ違いだな。COBOL スレでも行け。

561 :NAME 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 = なにか)
とかするしかないんじゃね?

562 :NAME IS NULL:2009/06/05(金) 21:34:54 ID:???
PRO*COBOLは知らんけど
CASE col_1
WHEN 1 THEN
みたいに書けんの?

563 :NAME IS NULL:2009/06/05(金) 23:41:07 ID:???
>>558
まずはそのSQLがSQL*Plusとかで通るかどうか試すべき

564 :sage:2009/06/06(土) 14:08:20 ID:4vB1BD0o
>>559
DBリンクを使って、他業者のDBのテーブルを判断なので
確かにDB設計が汚いです @@;

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

>>563
SQL*PLUSでは、実行でき、ちゃんと望みどおりの検索結果が返ってきます

565 :NAME IS NULL:2009/06/07(日) 03:52:32 ID:BvTw+nDU
HEXの形式で入っている文字列を普通の文字に変換したいのですが
  例) '31323334' →’1234’

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



566 :NAME IS NULL:2009/06/07(日) 09:48:22 ID:H5yYzBMm
>>564
decode は?

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

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

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



568 :NAME 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で囲うか。

569 :NAME 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つしか選択されないので注意

570 :NAME 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を使っています。
お願いします。

571 :NAME IS NULL:2009/06/07(日) 14:07:44 ID:s0waBkcv
揚げ

572 :NAME 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;

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


573 :NAME IS NULL:2009/06/07(日) 15:55:45 ID:???
>>565
昔やったときは文字単位でばらしてCHR()でがんばったなぁ。
なんでこんな基本的な機能がないんだろうって文句言いながら。
今ならあるのかな?

574 :NAME IS NULL:2009/06/07(日) 16:12:31 ID:???
>>567
はじめからDBいえよカス

575 :NAME 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件ある&ググッてもこういう書き方をしてる例が見つからない
すみませんがお願いします。

576 :NAME IS NULL:2009/06/07(日) 18:43:23 ID:???
MATCHってWHERE句なくても動くんだ?

577 :575: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('権力 者');


578 :NAME IS NULL:2009/06/07(日) 19:07:37 ID:???
>>575
FULL TEXTインデックスの説明
ttp://dev.mysql.com/doc/refman/4.1/ja/fulltext-search.html
ttp://www.tatamilab.jp/rnd/archives/000389.html

579 :NAME IS NULL:2009/06/07(日) 19:09:18 ID:???
'の位置を確認してみれ

580 :575: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');

ありがとうございました!

581 :580:2009/06/07(日) 19:27:03 ID:dWbdg2sE
くひっ。また間違えた・・・正しくは
SELECT * FROM some_table WHERE MATCH(some_column) AGAINST('+"赤ちゃん" +"権力 者"' in boolean mode);
です。

582 :NAME IS NULL:2009/06/07(日) 22:05:51 ID:???
まず落ち着こうよ。
読みやすい文章を書くのも大事なことです。

583 :NAME IS NULL:2009/06/10(水) 22:45:16 ID:zpAa6Yna
sqlserver 2000 を使っています。
varchar型の文字列に含まれる改行コードの数を出したいのですが、
何かいい方法はありませんか?
教えてください。

584 :NAME IS NULL:2009/06/10(水) 22:53:11 ID:???
動く環境無いんで想像だけど
replace(文字列,'\r\n','')

文字列
のlengthの差で出るかな。

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

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

改行コードで分割して配列に詰め込むような関数を使う(自作する)とかね

586 :NAME IS NULL:2009/06/10(水) 23:31:44 ID:zpAa6Yna
>>584
select replace(len(文字列,char(10),'')) - len(文字列) from テーブル で
取得できました!
今日1日中考えていたのでちょっと感動です。
ぐっすり眠れます。
ありがとうございます。


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

もっと柔軟に考えなきゃいけませんね。
ありがとうございました。


587 :585:2009/06/10(水) 23:35:59 ID:zpAa6Yna
くひっ。僕も間違えた・・・正しくは
select len(文字列) - replace(len(文字列,char(10),'')) from テーブル
です。

588 :NAME IS NULL:2009/06/11(木) 01:47:19 ID:???
>>587
落ち着けw
それでもおかしいだろ。

589 :NAME IS NULL:2009/06/11(木) 22:39:02 ID:/TZVY2cm
SQL Serverを使用しています。
例えばselect * from INFORMATION_SCHEMA.COLUMNS
のような内容をを特定の行だけ縦に表示するにはどう書いたらいいでしょうか?

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

みたいな感じです


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

AP側でどうにかしろ

591 :NAME IS NULL:2009/06/13(土) 07:40:51 ID:???
だいたいSQLに「表示」なんて概念は・・・・

592 :NAME IS NULL:2009/06/13(土) 14:52:14 ID:???
>>589
select * from INFORMATION_SCHEMAしてアプリ側で調整

593 :NAME 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 しています。

594 :NAME IS NULL:2009/06/15(月) 18:21:40 ID:???
where ID = 2 が要るだろ普通

595 :NAME IS NULL:2009/06/15(月) 18:34:52 ID:???
>>594
早速ありがとうございます。
VALUES() の後では文法エラーになってしまって(悩中)
WHERE 文の記述ヶ所教えていただけませんか?

596 :NAME IS NULL:2009/06/15(月) 18:56:42 ID:???
INSERT OR REPLACE も UPSERT(だったかな)もよくは知らないのだけど、
IDがプライマリーキーじゃないと拙いような気がする。
SQLは >>593のままでも通りそうだけど。

597 :NAME IS NULL:2009/06/15(月) 18:59:05 ID:???
INSERT OR REPLACEなんていう気持ち悪い構文はSQLiteか?
UPDATE文を使え

598 :NAME IS NULL:2009/06/15(月) 19:03:22 ID:???
>>596
あああ、PRIMARY KEY ・・
ありがとうございます。ID INTEGER PRIMARY KEY で置換しました。

599 :589:2009/06/16(火) 16:30:36 ID:???
遅くなったけどありがとう。
自前で処理することにします。

600 :NAME 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.製品名



601 :NAME IS NULL:2009/06/17(水) 07:43:42 ID:???
AND A.KEY3=(+)T.KEY3
がいるんじゃなかろか

602 :NAME 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


603 :600:2009/06/17(水) 20:43:10 ID:???
>>601、602
返信が遅くなって申し訳ない。
今環境がなく試せないのですが
後日試してみます。ありがとうございます。助かります。

604 :NAME 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だけは、なんとか調べて基本的な事だけは若干理解できる程度です。)


以上、どうかよろしくお願いします。

605 :604: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

他にも質問に不備等があれば補足しますので、どうかよろしくお願いします。

606 :NAME IS NULL:2009/06/20(土) 08:52:26 ID:???
>>604
標準SQLでは複数テーブルからのDELETEはできない。
どうしてもやりたければ参照整合性制約やトリガーを使うけど
まあDELETE文2回でいいんじゃね?

607 :604:2009/06/21(日) 01:52:54 ID:???
>>606
レスありがとうございます。
できれば、そのトリガー(もしくは参照整合性制約)というものを使って同時に削除したいです。
よろしければ、>>604のクエリにトリガーという方法を加えたクエリを書いていただけますでしょうか?

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

お時間のある時で構いませんので、お手数ですが再度レスをいただけると助かります。
どうかよろしくお願いします。

608 :NAME 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



609 :NAME IS NULL:2009/06/21(日) 02:21:48 ID:???
被るところだったw
>>608のDELETE文はFROMがいるんじゃね
DELETE FROM moz_...

610 :604: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

バックアップ取ってから試してみたいと思いますが、よろしければ再度レスをいただければ幸いです。
何度もすみませんが、よろしくお願いします。

611 :604: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/%'))

間違い等ありましたら、指摘していただけますでしょうか。
何度もレスをしてスレを伸ばしてしまってすみませんが、よろしくお願いします。

612 :NAME 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;

が走る。
これがトリガね。

613 :NAME IS NULL:2009/06/22(月) 07:19:19 ID:???
http://333.ooo.amigasa.jp/


614 :604:2009/06/23(火) 00:49:07 ID:???
返事が遅れてすみません。

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

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

回答・アドバイス等いただいた方々に大変感謝しています。
この度は色々とどうもありがとうございました。

615 :NAME IS NULL:2009/06/23(火) 16:46:57 ID:???
テーブルが作成されているかを確認する標準的な方法はあるでしょうか。
mysqlならCREATE DATABASE IF NOT EXISTSでいけるのですが。

616 :NAME IS NULL:2009/06/23(火) 22:02:19 ID:Lck5HQZ4
テーブル一覧のプロパティのファイルグループ名を
クエリで取得することって出来ますか?

617 :NAME IS NULL:2009/06/23(火) 22:05:06 ID:???
スレ違い。

618 :NAME 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」が答え

619 :NAME 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


620 :NAME IS NULL:2009/06/25(木) 12:44:02 ID:???
SQLって統一規格じゃないんですか?
独自SQLのようなものがあるんですか?

621 :NAME IS NULL:2009/06/25(木) 12:48:35 ID:???
ある程度の機能と用件を満たせば準拠。
プログラミング言語と比べるとSQLは独自色が強い。

622 :NAME IS NULL:2009/06/25(木) 22:29:16 ID:???
統一規格はあるけど、方言に頼るところも多い。
文字列変換や時刻関数等はほとんど方言だな。
oracleの外部結合の方言はひどいw

623 :NAME IS NULL:2009/06/25(木) 23:23:34 ID:???
オラクルの外部結合って、SQL92が出てくる前からあったんじゃなかったけ。
各ベンダーの独自拡張があって、その後の標準化だから、
互換性のために方言として残るのは仕方ないだろう。

624 :NAME IS NULL:2009/06/25(木) 23:24:48 ID:???
DB2 に truncate 相当の機能が無いのには驚いた。
良い悪いって話じゃないけど。

625 :NAME 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

626 :NAME IS NULL:2009/06/28(日) 02:18:02 ID:???
>>625
id = 1で検索してるから、idにインデックス付けてみたら?
で、実行計画取ってみて、インデックスの有無で変化があるか確認してみて

627 :NAME IS NULL:2009/06/28(日) 04:28:48 ID:???
IDの意味解って付けてんのかよ

628 :NAME IS NULL:2009/06/28(日) 13:31:46 ID:tWKLIY9h
もちろん、IDはプライマリキーです。

とかね。

629 :NAME IS NULL:2009/06/28(日) 14:38:30 ID:???
あるあるw

630 :625:2009/06/28(日) 18:03:08 ID:???
問題をわかりやすくするため単純にしたつもりだったのですが
横着してテンプレのものを流用したため、逆に誤解を招く書き方になったようですいません。
ほかで聞くことにします。失礼しました

631 :NAME IS NULL:2009/06/28(日) 18:38:29 ID:???
Y!知枝袋にでも逝っておいで

632 :NAME IS NULL:2009/06/28(日) 22:12:36 ID:???
つか、そこまで単純にしてしまって、
速度に差が出るほどバリエーションのある書き方できると思ってたのか?

633 :NAME IS NULL:2009/06/28(日) 22:45:55 ID:???
相変わらず厳しいやつらだ

634 :NAME IS NULL:2009/06/29(月) 00:57:01 ID:???
SQL Serverでストアドつくろうとしてるけど、
アプリからストアドに渡す引数がいっぱいあるんだけど普通?

これってアプリでやるべきじゃねぇのか。
アプリにするかストアドにするかの基準を教えてくれ。

635 :NAME IS NULL:2009/06/29(月) 00:59:57 ID:???
ここはSQL文を語るスレ

636 :NAME IS NULL:2009/06/29(月) 01:04:31 ID:???
引数がいくつでもスピード重視ならストアドにするんじゃない?
まあ、スレチ。

637 :NAME 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をどうやってつなぎ合わせるのか見当もつきません。
ヒントだけでも構いませんのでご教示願います。

638 :NAME IS NULL:2009/06/29(月) 12:20:27 ID:???
create table 商品番号 (〜〜〜)
insert into 商品番号 select 商品番号, 分類番号, 〜〜〜 from 〜〜 natural join 〜〜 natural join 〜〜
的な感じでいいんんじゃないの?postgres知らんけど

639 :NAME 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と一致しないものを抽出という条件を追加したいのですが
どういう風にすればいいでしょうか?


640 :NAME 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で既に存在する表の作成云々というエラーになってしまいますし、
表の趣旨も全く意味をなさないものになってしまいます。

どこをどのように修正すればよいのでしょうか?
宜しくお願い致します。

641 :NAME IS NULL:2009/06/29(月) 17:00:39 ID:???
VIEW作るんじゃいかんの?

642 :NAME IS NULL:2009/06/29(月) 20:37:15 ID:???
>>640
最後の natural join が余計。
つか、キーワードが分かったら自分でマニュアル読んでみれ。

643 :NAME IS NULL:2009/06/29(月) 21:25:23 ID:???
>>640
恒常的に見るのであれば、
craete view 商品情報(・・・・)
select 〜

644 :NAME IS NULL:2009/06/30(火) 16:11:55 ID:???
実体作りたいって言ってんだろカス

645 :NAME IS NULL:2009/06/30(火) 16:39:18 ID:???
結合したいっていう話しか出てないだろ
人の話はちゃんと読め

646 :NAME IS NULL:2009/07/01(水) 03:12:25 ID:???
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが
>一つの表集合として結合(4個目の表として存在させる)したいのですが

647 :NAME IS NULL:2009/07/01(水) 06:52:40 ID:???
>>646
うん。だからviewでいいよね。

648 :NAME IS NULL:2009/07/01(水) 10:48:26 ID:???
元質問者はVIEWの存在を知っているのかどうかが知りたいところではある

649 :NAME IS NULL:2009/07/01(水) 10:57:35 ID:???
ある時点のスナップショットをとりたい=>ワークテーブル
複数テーブルの結合結果を表として扱いたい=>VIEW
どちらをやりたいのかによるな


650 :NAME IS NULL:2009/07/01(水) 11:16:04 ID:???
>>647
よくない。SQL初心者?

651 :NAME IS NULL:2009/07/01(水) 12:08:55 ID:???
>>650
横からすみませんが、「ちゃんと読め」とか「よくない」とか文句だけ言うよりは、
自分で回答を示せば良くないですか?

652 :NAME IS NULL:2009/07/01(水) 12:35:29 ID:???
>>639
動作未確認だけど、WHERE句で条件付けるのはダメ?
WHERE NOT EXISTS(
SELECT *
FROM {table_d} ddd
WHERE ddd.mail = aaa.mail
)


653 :639:2009/07/01(水) 14:03:32 ID:???
>>652
行けました、NOT EXISTSという使い方があったんですね
前任者の書いたSQLに処理を追加する作業だったんですが安請け合いして後悔し始めたところです
dくすでした

654 :NAME IS NULL:2009/07/01(水) 18:05:32 ID:???
細かい話だけどNOT EXISTS ならSELECT 1 とかすべき

655 :NAME IS NULL:2009/07/01(水) 18:12:21 ID:???
細かい話だけど最近のRDBMSならSELECT *で十分最適化されるよ

656 :NAME IS NULL:2009/07/01(水) 21:55:46 ID:???
むしろ*のほうがいい

657 :NAME IS NULL:2009/07/02(木) 16:10:37 ID:???
で、どっちが正解?

658 :NAME IS NULL:2009/07/02(木) 17:13:52 ID:???
>>657
昔は定数の方が速かった。今は * の方が速い時もある。

659 :NAME IS NULL:2009/07/03(金) 11:43:01 ID:???
なるほど

660 :NAME IS NULL:2009/07/03(金) 18:05:06 ID:???
教えてくだせー
>>4で、例えば最新の3件を抽出するにはどうしたらいいですか?

661 :NAME IS NULL:2009/07/03(金) 18:10:02 ID:???
top n とかrow_number()とかrownumとか。
DBMSの種類によって書き方が違う。

662 :660:2009/07/03(金) 22:18:56 ID:???
>>661
ありがとう
ちょっとやってみます

663 :NAME IS NULL:2009/07/06(月) 21:30:55 ID:???
MSDEのData更新に困っております
AccessプロジェクトよりCSVファイルをインポートして
DataBase作成しているのですが、インポート先のCSVファイルは
常に更新されています
AccessプロジェクトのData更新の為、インポートを行うと
重複したDataになります・・・・
重複しないクエリもしくはVBEはないでしょうか?



664 :NAME IS NULL:2009/07/06(月) 22:18:16 ID:???
まず「インポート」の意味から勉強してこようぜ
話はそれからだ。

665 :NAME IS NULL:2009/07/07(火) 06:37:53 ID:???
importの前にdeleteすればOKだね
はい 次

666 :NAME IS NULL:2009/07/07(火) 09:46:04 ID:???
>>663
MSDEどこいった?

667 :NAME IS NULL:2009/07/07(火) 17:00:45 ID:???
−データベース桐からの挑戦−
「販売管理とか会計システムとかのSQLの例書いてみろよ」
だそうです。
ttp://pc11.2ch.net/test/read.cgi/db/1057318214/699


668 :663:2009/07/07(火) 20:04:57 ID:???
申し訳御座いませんマルチしておりました
反省しております
>>665さん
AccessプロジェクトのDataをdeleteしましたができませんでした
別のやり方があるのでしょうか・・・
MDBの様にリンクできればよいのですが

669 :NAME IS NULL:2009/07/08(水) 09:44:54 ID:???
>>668
あっちのスレでもいっぱい返事もらってるのに
並行で進めるのはやめれ

670 :NAME IS NULL:2009/07/08(水) 17:28:50 ID:???
>>669
質問の内容はどうでもいいことばかり。
だれかれに構って欲しいのさ。
あちこちに書くのは、2chに張り付いてるからだろ。
とにかくかまって欲しいんだよ。

671 :NAME IS NULL:2009/07/09(木) 14:22:20 ID:I1RDXwu9
postgresSQLを使っているのですが、以下の問題がわかりません。
以下の順序で列を表示するビュー定義を考え実行する
支払金額、明細

672 :NAME IS NULL:2009/07/09(木) 14:57:50 ID:???
>>671
宿題は自分で解く。
順序の指定は ORDER BY

673 :NAME 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' 付近に不適切な構文があります。

一番りこうな書き方は何ですか。

674 :NAME IS NULL:2009/07/09(木) 15:58:07 ID:H2IBJWq1
>>673
どういう文脈で使いたいのかいまいち分からないけど
TSQL内で使うならIF
SQL分だけで使うならcoalesceでよくない?

675 :NAME IS NULL:2009/07/09(木) 15:59:19 ID:???
利口ってか、早いのは実行計画とってみないとわからん

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

あとはUNION使って
SELECT ..., 1 as FlagUriage WHERE ...
UNION
SELECT ..., 0 as FlagUriage WHERE not ...
とか

676 :NAME 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
で動かないかな?

677 :NAME 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

678 :NAME 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)

679 :NAME IS NULL:2009/07/15(水) 14:46:18 ID:???
このSQLはあまり性能がよくないので気をつけてね

680 :NAME 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

681 :NAME 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を書いたんですが...
正直もっと簡単にならないものでしょうか?



682 :NAME IS NULL:2009/07/16(木) 22:19:25 ID:???
>>681
>>511

683 :NAME IS NULL:2009/07/16(木) 22:36:42 ID:???
このスレはまとめサイトがあったほうがいいかもわからんね

684 :NAME IS NULL:2009/07/17(金) 01:14:50 ID:???
>681
レスthx
そおですか...
一応maxが20の可変長なんで、自分の書いたSQLを20まで書けば実現できるんですが...

ストアドかアプリサイドで、ですね。
アプリサイドは通信料増えるのを嫌って最後の手段で考えてました。
ちょっと検討してみます。(´・ω・`)

685 :NAME IS NULL:2009/07/17(金) 01:15:36 ID:???
>682だった。(´Д`;)

686 :NAME 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を業務で使っているの?


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

xeは業務で使ってますよ。
本ちゃん環境は10gらしいですが...

688 :NAME IS NULL:2009/07/17(金) 18:56:24 ID:???
>687
なるほど開発で使っているのか。
ちょうど俺も試しに使ってみようとしていたところなんだ。
ありがと。


689 :NAME 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'),
),
);

690 :NAME 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;


691 :NAME IS NULL:2009/07/19(日) 20:53:54 ID:???
>>689
SELECT * FROM table
WHERE `date` >= DATE_SUB(CURDATE() , INTERVAL 3 DAY)

で、どうでしょう?

692 :NAME IS NULL:2009/07/19(日) 21:06:22 ID:???
データの無い日をどう数えるかによるね

693 :689:2009/07/19(日) 22:37:34 ID:???
>>690-692
すみません、MySQLではなくSQLite(Ver.2)でした。
SQL文を実行してみましたがno such functionやsyntax errorでした。

694 :NAME 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で動くかどうかしらね。

695 :NAME IS NULL:2009/07/20(月) 00:49:08 ID:???
Oracle 10g で質問です。

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

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

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

方法をご存知の方がいらっしゃいましたら、教えて下さい。
よろしくお願いします。


696 :NAME IS NULL:2009/07/20(月) 17:42:45 ID:???
Oracleをなめまくる

697 :NAME IS NULL:2009/07/21(火) 01:21:08 ID:???
>>695
どうも最終的にどんな結果が欲しいのか良くわからん。
簡単でいいからやりたいことをSQLで例示してくれないか。

698 :NAME 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を期待するしかないのか?

699 :NAME IS NULL:2009/07/21(火) 07:36:44 ID:???
本来はそこもオプテイマイザが適切に判断するはずなんだが、それが
実際には意図した実行計画になっていなかったから明示的にHINTで
指定したいのだと読んだが?
答は俺も知らん。

700 :NAME IS NULL:2009/07/21(火) 22:22:00 ID:???
ますますわからん

701 :695:2009/07/23(木) 02:11:26 ID:???
695です。言葉足らずですみません。
言いたかったことはほぼ>>698さん、>>699さんに書いてもらった内容でした。

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

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




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

一時テーブルへの待避コストを多く見積もるようにどこかにパラメータはない?
てか、Oracleスレで聞いた方がいいかも。

703 :NAME 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は除外したいのです(そうしないと重複はあり得ないため)。

なにか良い方法はありますか?

704 :NAME IS NULL:2009/07/26(日) 01:05:23 ID:???
>>703
日本語でおk
ハッシュ値がユニークなのに、ほか二つの値が同じレコードをまとめたいなんて、一体どっちのハッシュ値をもってくればいいんだ?

705 :703:2009/07/26(日) 01:13:40 ID:???
>>704
あ、そういえばそうですね。
重複したname,sizeをリストから除去したいです。

ハッシュは最初に現れる値でも最後に現れる値でもどちらでも良いですが、重複をのぞく方法は他にあるのでしょうか?

706 :NAME 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);
で、いいのか?
汚いな...

707 :NAME IS NULL:2009/07/26(日) 02:49:31 ID:???
>>705
select distinct on (name, size) hash, name, size from table_name;
おやすみ。

708 :NAME IS NULL:2009/07/26(日) 03:29:26 ID:???
>>707
それポスグレだろ。

select hash,name,size from table_name group by name,size
でいける。他だと動かないみたいだけど。

709 :NAME IS NULL:2009/07/26(日) 03:52:42 ID:???
それ動くのかよw
むちゃくちゃだな

710 :NAME IS NULL:2009/07/28(火) 17:45:01 ID:???
SQLserver2005の処理で一つ教えてください。
2つの同じ項目のビューがあり、それを一つのビューにマージしようと思っています。
ただある項目が重複した場合は重複データを破棄したいのですが
UNIONだとキー以外の項目が違っていたら別データ扱いですし、
UNION ALLでは問答無用で入ってしまいます。
重複キーを指定してマージすることはできるのでしょうか?

711 :NAME IS NULL:2009/07/28(火) 19:08:16 ID:???
>>710
なんかデジャヴだな
キーが同じでキー以外の項目が違う場合はどのデータを残すん?

712 :NAME 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)

とか?

713 :NAME 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)

で行けると思う。ためしてないけど

714 :NAME IS NULL:2009/07/28(火) 22:41:46 ID:???
>>713
両方破棄すんの?

715 :NAME IS NULL:2009/07/28(火) 23:22:27 ID:???
重複コードを破棄しちゃいかんだろ。
1つ残すととらえるのが自然だと思う。

716 :NAME IS NULL:2009/07/28(火) 23:29:32 ID:???
そう読むのが自然な気はするけどどっちを残せばいいのかわからん。
キー以外のカラムも同じならどっちでもいいんだろうけどそうでは無いんだよね?

717 :NAME IS NULL:2009/07/28(火) 23:55:26 ID:???
結局>>711に戻るわけだな

718 :NAME IS NULL:2009/07/29(水) 00:30:06 ID:???
そうね。>>713は先走ったかも

719 :NAME IS NULL:2009/07/29(水) 05:52:21 ID:???
>>714,715
どちらかのテーブルのデータ残すなら>>712で行けるんじゃないか
両方消すなら>>713
それ以外なら>>710の説明不足

やりたいことをちゃんと説明できないのは
自分自身も何をどうしたいのかはっきり分かってないって事だろうな

720 :NAME 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のデータをセット。

721 :NAME IS NULL:2009/07/29(水) 16:24:08 ID:???
>>720
先月との比較を曜日で合わせてる?
日付対応のルールが明確でないと色々厳しいと思うけど。

722 :NAME 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.日付);

実用的な速度が得られるかどうかしらんよ。

723 :NAME IS NULL:2009/07/29(水) 16:37:49 ID:???
07/01とか06/01のデータが無い場合が厄介だな

724 :722: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' の値次第)になる。

725 :NAME IS NULL:2009/07/29(水) 19:27:46 ID:JrJvF1CD
一つのSQL文内に、同じSELECT文が何度も出てくる場合、
あらかじめSELECTした結果に別名をつけておいて、
それを使い回すことってできますか?

726 :NAME IS NULL:2009/07/29(水) 20:05:07 ID:???
>>725
WITH句をサポートするDBMSならそれで
なければVIEWで

727 :NAME IS NULL:2009/07/29(水) 20:18:59 ID:???
一時テーブルかなー

728 :725:2009/07/29(水) 22:29:26 ID:???
ありがとうございます。
一文中では無理な感じでしょうか。
SELECTしか使えない環境なので、一文でなんとかしたかったのです。
PostgreSQLなのですが、DBMSはよく分かりません。


729 :NAME IS NULL:2009/07/29(水) 22:32:00 ID:???
SELECTしか使えない環境・・・? Accessか何かか?

730 :NAME IS NULL:2009/07/29(水) 22:53:12 ID:???
そこでSQLインジェクションですよ

731 :NAME IS NULL:2009/07/30(木) 00:03:16 ID:???
内容によってはなんかできるかもしれないけど、それだけだとちょっと難しいよね

732 :NAME IS NULL:2009/07/30(木) 01:38:14 ID:???
>>728
PostgreSQLは最新の8.4からWITH句をサポート

733 :NAME 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することはできるのでしょうか。どうかよろしくお願いします。

734 :NAME 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;

735 :nanasi: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。

736 :NAME IS NULL:2009/07/30(木) 11:05:29 ID:72K2TDMo
ほんと基本的な質問ですみませんが、テーブル定義書において、タイプ記述方法を調べたいのです。
CHAR,NUMERIC,DECIMALなどを書く方法もありますが、それ以外の方法(特に今回知りたいのは0,S,A,Oと書く方法)について、
教えていただけないでしょうか。
サイトの紹介でも結構です、よろしくお願いいたします。

737 :NAME 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を選ぶ、
という処理のスマートな書き方を教えてください。

738 :NAME 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
とか?
実際に確認してないけれども。

739 :NAME IS NULL:2009/07/30(木) 16:28:37 ID:???
>>738
なるほど!その手がありましたか。
参考になりました。ありがとうございます。

740 :NAME IS NULL:2009/07/30(木) 18:21:49 ID:???
MySQLで、ある数値がカンマ区切りで数値の入っているフィールド
nums(text型)に含まれるかを判断するWHERE文を書きたいのですが、
どう書いたら良いでしょうか。
ANDで絞り込み条件として使いたいのですが、思いつきません。

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

SELECT * FROM test WHERE 128 IN(nums);

どうか知恵をお貸しください。

741 :NAME IS NULL:2009/07/30(木) 18:46:34 ID:???
>>740
SELECT * FROM test WHERE nums REGEXP concat('(^|,','128','(,|$)');
かな? 自信なし。

742 :NAME IS NULL:2009/07/30(木) 18:48:26 ID:???
書き込んでから気づいた。直書きならわざわざconcatで連結する必要ないな。
nums REGEXP '(^|,)128(,|$)';

743 :NAME IS NULL:2009/07/30(木) 20:57:26 ID:EY3peTrf
postgreSQLで、
日付の差分を値の補正に使いたいのですが、
日付の差分を値に掛けると XXXX day みたいな日数表示になってしまいます。
この日数型を整数にするにはどうすればいいでしょうか。

744 :NAME IS NULL:2009/07/30(木) 21:21:46 ID:???
>>743
EXTRACT(DAY FROM INTERVAL型)

745 :743: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)))
これに月の日数と閏年の判定をいれれば、ゴリ押しでとれなくもないですが。。。

746 :743:2009/07/30(木) 21:31:47 ID:???
>>744
extract(day FROM (日付1-日付2)) で日数とれました。
ありがとう。

747 :740:2009/07/30(木) 21:36:55 ID:???
>>741-742
早速のレス有難うございます。
レスが遅くなり申し訳ありません。

ただいま確認したところ、期待通りに動きました。
大変助かりました。有難うございました。

748 :NAME 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となる。

抽出するクエリを教えて下さい。お願い致します。

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

どうせなら、

長さ | 幅 | 加工賃

ってテーブル構造にしとけばいいのに。

750 :NAME 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 幅ランク=俺の尻の穴に貴方の野太いアー

752 :NAME IS NULL:2009/08/01(土) 08:35:58 ID:???
>>751じゃランクを細分化したくなったとき困るだろ

素直に>>749
 select min(加工賃)
 from TableName
 where 長さ >= 注文された長さ
 and 幅 >= 注文された幅
で初めてか?力抜けよ

753 :NAME 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

754 :725: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を効率化することってできないでしょうか?

755 :NAME IS NULL:2009/08/01(土) 12:41:15 ID:???
得点にインデックスが張ってあれば
SELECT MAX(得点) FROM 得点テーブル
の部分はフルテーブルスキャンにはならないだろ

756 :725:2009/08/01(土) 12:47:46 ID:iuklVi8s
まあそうなんですが、上のは簡単化した例えです。

実際は得点テーブルってテーブルは無くて、
得点テーブルの部分にはさらに副問い合わせが入ります。
こういう場合に、2回SELECTをしないで済む方法があれば教えて下さい。

757 :NAME 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.得点
とか?
こっちのほうが遅そうだけど

758 :725:2009/08/01(土) 13:14:36 ID:???
SELECT2回しなけりゃいいって問題じゃねえw
効率化したいんです。

759 :NAME IS NULL:2009/08/01(土) 13:21:18 ID:???
そりゃ情報小出しにしてりゃそうなるわな

760 :NAME IS NULL:2009/08/01(土) 13:21:20 ID:???
無い。
トリガを使って出入りを監視すれば。

761 :725:2009/08/01(土) 13:24:39 ID:???
『得点テーブル』は副問い合わせ結果なんだけど、
その副問い合わせが、中でさらに8回くらい副問い合わせしていて重い。
だから、2回同じことをやらずに済む方法があれば知りたいのです。
ちなみに、WITHは使えません。

762 :725:2009/08/01(土) 13:29:40 ID:???
>>760
どうもありがとう。
他のところでチューニングしてみます。

763 :NAME IS NULL:2009/08/01(土) 18:09:52 ID:???
SQLを見直すか、インデックスを見直すか、テーブルを再設計するか。
悩ましいね。

764 :NAME IS NULL:2009/08/01(土) 21:36:16 ID:qL1wMwr+
先輩方、質問させてください。
例えばこんなテーブルがあったとします。

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


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

質問2
Aのようなプライマリーな列は何と言うのですか?

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

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

ちなみに氏名じゃ一意性に欠けるから普通は候補キーにならない。

766 :764:2009/08/01(土) 22:00:55 ID:qL1wMwr+
>>765
なるほど。ありがとうございます。
カラム(列)
ロウ(行)
フィールド(属性)
レコード(タプル)ってことですよね?

質問2の答えは候補キーですか。英語でなんて言うんだろ?Candidate keyでいいのかな。

767 :NAME IS NULL:2009/08/02(日) 01:29:40 ID:???
氏名を候補キーにするのは通常しないって。
同姓の人なんていくらでもいるでしょ。
プライマリキーになれるのは、Nullじゃなく一意なカラムだけですよ。

768 :NAME IS NULL:2009/08/02(日) 01:54:48 ID:???
候補キーになるかどうか判断するんであって、「候補キーにする」もんじゃないね。

769 :764:2009/08/02(日) 03:54:10 ID:???
>>767
すみません。
都道府県や数値を書くべきでした。
ただの例なので一切つっこまれないと高を括っていましたが、甘かったです。
2chを舐めすぎていました。反省します。

770 :NAME IS NULL:2009/08/02(日) 14:41:21 ID:???
ちょっと舐めるくらいにしておけ

771 :NAME IS NULL:2009/08/02(日) 16:11:30 ID:???
例がおかしかったらつっこまれるのは2chに限った話じゃない

772 :NAME IS NULL:2009/08/02(日) 16:25:25 ID:???
ただまぁ、質問の前提情報が不足してるってのも、そこを勝手に判断して
思い込みで回答したり突っ込み入れたりするのも同じ穴の狢なんだよな。
>>764がもし全国の苗字毎の平均身長、体重の集計データとかだったら
何もおかしなことはない。

773 :NAME IS NULL:2009/08/02(日) 16:45:06 ID:???
そんな特殊例なんて無視するのが当然だろ。
何言ってんの?w
そんなデータ誰が欲しがるんだよ。
頭おかしいとしか思えないw

774 :NAME IS NULL:2009/08/02(日) 17:29:51 ID:???
そりゃ、>>772は単なる例だから。
ただ、分析や設計をする立場の人間なら、

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

というように、書いてもいないことを思い込みで勝手に判断するのは
戒めるべきだってこと。

775 :NAME IS NULL:2009/08/02(日) 23:07:01 ID:???
違うだろ。
わけのわからない要求があがってきたら、それを客と話し合って相談する。
>>772みたいに勝手に想像をふくらませて「ありえないことないな」と判断するほうが危険だろ。
新入社員か?

776 :NAME IS NULL:2009/08/03(月) 00:04:48 ID:???
勝手に判断するなって書いてんのに、なんで「ありえないことないな」と判断したことになるんだよw

777 :NAME IS NULL:2009/08/03(月) 00:27:09 ID:???
>>773
ワインバーグは「奇跡はどこにでも存在する」と書いているが、同じような意味で
現実の案件はみんな特殊例と言ってもいいかもね。

778 :NAME IS NULL:2009/08/03(月) 02:13:02 ID:???
まあまあ。
きっとジンバブエのフリー家計簿ソフトが今も正しく動くのかについて考えないか

779 :NAME IS NULL:2009/08/03(月) 02:14:10 ID:???
いろいろ書いてる途中でKITTがのこってしまいました。

780 :710:2009/08/04(火) 17:14:06 ID:???
>>711-719
せっかくレスいただいたのにレス返していなくてすいません。
言いたかった事はAとBというビューをマージし、Cというビューを作ろうと思ったのですが
AとBで重複しているレコードがあり、それは片方だけCに持って行きたかったんです。
ただAとBで若干内容が違っている項目があるので、それは無視して
主キーのみで重複チェックをかけたかったのですが、その方法がわかりませんでした。
とりあえず教えていただいた式をよく見て試してみたいと思います。
本当に遅くなってしまいましたがありがとうございました。

781 :NAME IS NULL:2009/08/04(火) 17:16:55 ID:???
>>780
うん、それはみんな分かってる。
その上で、重複したときにどっち捨てるのかが分からなかったんだよ。

782 :NAME IS NULL:2009/08/04(火) 17:23:22 ID:???
自分ならビューをマージせず元テーブルをマージするが

783 :710:2009/08/04(火) 18:48:56 ID:???
早速サンプルを参考に試したら無事できました!
アドバイスありがとうございました。

>>781
すいませんホント言葉足らずで・・・。
どっちが残ってもいいかと思っていたので書いてませんでした。
>>782
確かに本当は余計なものは作りたくなかったのですが
特別な処理のINPUT用にビューが欲しくて別途作ろうとしていました。

784 :NAME IS NULL:2009/08/04(火) 19:53:10 ID:???
ただ単なる重複キーだけを知りたかったら

select
distinct 主キー
from tableA

union

select
distinct 主キー
from tableB

でいいじゃん・・・。
本当に他のデータがどうでもいいならね。

785 :NAME IS NULL:2009/08/04(火) 19:56:58 ID:???
それは何もかも違う

786 :NAME 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だけ取り出すにはどうすればよかですか

787 :NAME IS NULL:2009/08/04(火) 20:08:35 ID:???
DISTINCTしたのをCOUNTして3件のヤツとか

788 :NAME IS NULL:2009/08/04(火) 20:27:20 ID:???
groupするんじゃなくて?

789 :NAME IS NULL:2009/08/04(火) 20:44:09 ID:???
いやもちろんGROUPしてCOUNTだけど
先にDISTINCTしとかないとAABとかでも3件だしな。
そういうケースがあるかは知らんけど。

790 :NAME 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);

791 :NAME 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
                  )
         )
;

792 :790: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);

793 :NAME IS NULL:2009/08/04(火) 21:16:37 ID:???
existsもjoinも汚いんだよな。
もう少しなんとかなりそうなんだが。

794 :790: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;

795 :790:2009/08/04(火) 21:24:47 ID:???
あ、id=1でDも持っている可能性があるから、ABC"しか"じゃなくてABCを持っているなら
HAVING countDISTINCT hoge) >= 3;
ですね。

796 :NAME IS NULL:2009/08/04(火) 21:25:55 ID:???
WHERE hoge in ('A','B','C') と書いてるのに?

797 :790: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
)
)
;
で動く。

798 :NAME IS NULL:2009/08/04(火) 21:31:46 ID:???
SQLパズルにヒント乗ってそうだが参照するのが死ぬほどめんどくさい。

799 :738:2009/08/04(火) 22:15:16 ID:???
ABCのどれかが欠けてるやつ以外という逆説手法でいけるのか。
質問主じゃないけど参考になった。

800 :NAME IS NULL:2009/08/04(火) 22:24:36 ID:???
逆説は考えてみたけどNOT A OR NOT B OR NOT Cじゃできなくて諦めたが、NOT EXISTSが正解だったんだな。
>>797にthx。

801 :NAME IS NULL:2009/08/04(火) 22:47:53 ID:JCPNsOCy
何が知りたいかと言えば、シルバーでダイタイ平均いくらかかりますか?
あとゴールドは?

802 :NAME 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
かな?

803 :786:2009/08/04(火) 23:03:33 ID:???
おお、予想以上の反響でびっくり
みなさんありがとう
hogeの指定は動的なんですわ
やっぱりwhere一発とかじゃ簡単にできないか
明日になっちゃうけど教わったやつ試してみる

804 :NAME IS NULL:2009/08/04(火) 23:06:35 ID:???
>>791はSQLServer2008でも動かないんだが。

805 :NAME 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)がユニークならこれで行けるっぽ

806 :NAME IS NULL:2009/08/05(水) 04:33:07 ID:RB7uuMhx
PostgreSQL8.1 です。
シーケンスを含むDB を pg_restore したのですが、そのシーケンスに対する curval の取得が失敗します。
一度 nextval 等で値を取得すれば curval も取得できるようになるのですが、こういうものでしょうか?
CREATE SEQUENCE したばかりのシーケンスの curval が取得できないのと同じような感じです。


807 :NAME IS NULL:2009/08/05(水) 07:08:18 ID:???
>>805
検索の度にテーブル作り直すの?

808 :NAME IS NULL:2009/08/05(水) 09:31:08 ID:???
怪盗1412号を怪盗KIDと読むくらい無理があるな

809 :NAME IS NULL:2009/08/05(水) 12:15:15 ID:???
>>807
作り直すの意味するところが掴みかねるが
条件に対応するレコードをセットするわけで、テーブルそのものを作り直す必要はないが
たとえば条件がA,B,Cなら、条件テーブルにA,B,Cの3レコードセットしとく



810 :NAME IS NULL:2009/08/05(水) 12:34:14 ID:???
SELECT文を発行するたびにそれをやるのはなぁ。

811 :NAME IS NULL:2009/08/05(水) 13:00:14 ID:???
>>806
そういうもの。

812 :NAME IS NULL:2009/08/05(水) 13:00:51 ID:???
じゃあ条件に合わせて毎回SQL作り直すか?

813 :NAME IS NULL:2009/08/05(水) 15:03:36 ID:???
普通にSQL動的に作った方が楽じゃね?

814 :NAME IS NULL:2009/08/05(水) 16:25:58 ID:???
条件の個数が固定なら動的SQLでもいいかもしれん
条件の個数が変わるなら動的SQLのが大変じゃないかな

まあ、状況次第だな

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

816 :NAME IS NULL:2009/08/08(土) 01:19:33 ID:???
Oracle 10g で質問です。

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

ご指導をお願い致します

817 :NAME IS NULL:2009/08/08(土) 02:57:48 ID:???
1000件ずつにきちんと分けれたらいけるだろ。
テーブルの構成を書かないならこれ以上はアドバイスできない。

818 :NAME IS NULL:2009/08/08(土) 13:29:50 ID:???
ROWNUM

819 :NAME IS NULL:2009/08/08(土) 15:53:09 ID:ZMe9F3VY
SQLITEでテーブルに入ってる列の名前を表示させるSQL文を教えてください

820 :NAME IS NULL:2009/08/08(土) 16:19:47 ID:???
.help にヒントがあるようにおもう >> 819

821 :NAME IS NULL:2009/08/08(土) 20:32:43 ID:???
>>817-818
説明不足スミマセン

ROWNUMで解決しました

ありがとうございました

822 :NAME 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で出来るのでしょうか?

823 :NAME IS NULL:2009/08/09(日) 18:58:03 ID:???
3列固定なら簡単にできる。
動的なら難しい。


824 :NAME IS NULL:2009/08/09(日) 19:03:26 ID:???
>>823
> 3列固定なら簡単にできる。
> 動的なら難しい。
>

レスどうもです
列は固定です

825 :NAME 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



826 :NAME 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
みたいな取得をしたいんだったらテーブルの作りを変えるのも考慮してみては

827 :NAME IS NULL:2009/08/10(月) 08:17:00 ID:???
>>826
ありがとうございます

テーブルの構造を作り変えることも検討したいと思います

828 :827: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 に間違いはないと思うのですが
何が悪いのか教えていただけないでしょうか

829 :NAME IS NULL:2009/08/10(月) 22:39:04 ID:???
>>828
3つのサブクエリの最後、
and t1(カンマ)data2 = 'あ'
になってる。

830 :NAME IS NULL:2009/08/10(月) 22:39:15 ID:???
どっちも t1?

831 :NAME 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のいずれかが複数件の結果を返してしまっているということ。


832 :NAME IS NULL:2009/08/10(月) 22:51:47 ID:???
構文エラーにならないんだねえ。
where句のカンマ演算子ってどういう扱い?

833 :827: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 に書いたとおり全てのデータがひとつのテーブル内に記述されてるんです

834 :NAME 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

835 :NAME 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;

836 :835: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

837 :NAME IS NULL:2009/08/10(月) 23:02:23 ID:???
ちゃんと実行してから書け

838 :827:2009/08/10(月) 23:08:43 ID:???
みなさん ありがとうございました!
できました

感謝します
勉強しないといけないです・・・ orz

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

%08%や____08__などやってみてもだめでした。

840 :NAME IS NULL:2009/08/11(火) 15:40:23 ID:???
どのDBMSでも月を取得できる関数が何かしら用意されてるはず

841 :NAME IS NULL:2009/08/11(火) 15:41:43 ID:???
もし無ければ文字列に変換して比較

842 :839:2009/08/11(火) 16:00:33 ID:???
ありがとうございます。

843 :NAME 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にしたいのですが、どうすればいいのでしょうか


844 :NAME 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');

845 :843:2009/08/11(火) 20:40:19 ID:???
>>844
ありがとうです!

846 :703:2009/08/12(水) 12:36:16 ID:???
>>708
今更ですが、無事動きました。
この記述はSQLiteオンリーなのでしょうか?

847 :NAME IS NULL:2009/08/12(水) 12:40:13 ID:???
Select句にhashがあんのにGroupBy句にないから普通ならエラーだな。

848 :NAME IS NULL:2009/08/12(水) 13:28:49 ID:???
「ありがとうございました」と言え

849 :NAME IS NULL:2009/08/12(水) 14:18:21 ID:???
あー、あざーす

850 :NAME 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パターンのみのデータを抽出したいのですが
可能でしょうか?


851 :NAME IS NULL:2009/08/12(水) 17:38:53 ID:???
優先順位とか関係ないなら、in ('test1', 'test2', 'test3') で、TOP 1。

PostgreSQL で使えるか知らんけど。

852 :NAME IS NULL:2009/08/12(水) 17:44:55 ID:???
rder by memo = 'test3', memo='test2', memo='test1' limit 1

とか、、苦しいか

853 :NAME 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 とか。

854 :NAME 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

相当おかしい感じがするのは気のせいと思っている

855 :NAME IS NULL:2009/08/13(木) 12:20:18 ID:???
気のせいじゃないよ。

856 :NAME IS NULL:2009/08/14(金) 04:10:04 ID:???
Oracle10gで
○○都○○市〜〜
○○○県○○市〜〜
のように住所が入っているaddress列から
都道府県名だけを抽出したい場合
どんな文を書けばいいんでしょうか

857 :NAME IS NULL:2009/08/14(金) 04:40:48 ID:???
それはSQLの仕事じゃ無いような・・・

858 :NAME IS NULL:2009/08/14(金) 04:51:58 ID:???
REGEXP_SUBSTRでもつかえば?

859 :NAME IS NULL:2009/08/14(金) 04:54:03 ID:???
簡単なのは正規表現を使って、
REGEXP_REPLACE(address,'^(...*?(都|道|府|県)).*$','\1')
かなあ・・・パフォーマンス悪いだろうなあ

860 :NAME IS NULL:2009/08/14(金) 04:59:27 ID:???
頻繁に発生するなら都道府県マスタ作って前方一致で結合して…とかがいいかも

861 :NAME IS NULL:2009/08/14(金) 05:10:08 ID:???
>>859
それだと京都府が...
PostgreSQL用だけど、要は正規表現で関数は書き直して。
SELECT substring(address , '^(.*?(東京都|道|府|県))') FROM Table;

>>860
前方一致で1行ごとに47都道府県と比較するのと正規表現とどちらが速いだろうな。

862 :NAME IS NULL:2009/08/14(金) 05:13:05 ID:???
'京都府'はいけるように作ったぞ
全部の都道府県をテストしたわけじゃないが


863 :NAME IS NULL:2009/08/14(金) 05:27:42 ID:???
>>862
スマソ ...*? 頭の..を見逃していた。

864 :NAME IS NULL:2009/08/14(金) 05:45:19 ID:???
抽出はREGEXP_SUBSTRを使えばいいのか・・・
勉強になるわあw

865 :NAME IS NULL:2009/08/14(金) 14:39:48 ID:???
というか都道府県なんて50も無いんだから手で抽出(というか記述?)した方が早くね?

866 :NAME IS NULL:2009/08/14(金) 14:43:10 ID:???
>都道府県なんて50も無い
それは856の抽出結果が50しかないということを意味する訳ではないし
何度もやるかもしれない

867 :NAME IS NULL:2009/08/14(金) 15:12:58 ID:???
都道府県とは書いてあるが、市区町村まで分けようとしてるんじゃないの?

868 :NAME IS NULL:2009/08/14(金) 23:59:57 ID:TqQmlfGr
カラム
a char (4) not null
b decimal(4) not null
がある場合、
条件句で
'2000' < a

2000 < b
はどちらが速いでしょうか?
(データとインデックスは同じ)

869 :NAME IS NULL:2009/08/15(土) 00:23:04 ID:???
後者の方が速いでしょ。

870 :NAME IS NULL:2009/08/15(土) 01:12:06 ID:???
aにインデックスがある
bにインデックスがある
の2つを比べるなら一緒でしょ

871 :NAME IS NULL:2009/08/15(土) 15:55:43 ID:c8dfsvTH

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

 次の衆院選は

   めざせ投票率72%!

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

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



872 :NAME IS NULL:2009/08/17(月) 14:38:36 ID:???
72.1%じゃあかんの

873 :NAME 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件ずつ抽出したいのですが?



874 :NAME IS NULL:2009/08/19(水) 21:09:19 ID:???
key1 は group by で求めるとして、key2 はどういう基準なの?

875 :NAME IS NULL:2009/08/19(水) 21:23:27 ID:???
key2、dateはkey1に紐づくデータで特に指定はないです


876 :NAME IS NULL:2009/08/19(水) 21:30:34 ID:???
そんじゃ、>>4 でいいだろ。


877 :NAME IS NULL:2009/08/19(水) 22:21:00 ID:???
すみません。すっかり忘れてました。
ありがとうございます。

878 :NAME IS NULL:2009/08/19(水) 22:24:40 ID:???
>>873
PostgreSQLならDISTINCT ONで

SELECT DISTINCT ON (key1) * FROM Table;
普通ORDER BYと組み合わせるがな。

879 :NAME 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);

〜以外というのができれば良いのですが・・・


880 :NAME IS NULL:2009/08/21(金) 01:39:09 ID:???
ポスグレさわったことないけどNOT EXISTS

881 :NAME IS NULL:2009/08/21(金) 01:45:55 ID:xrxomkXj
>>880
おぉ、こんな便利なものが。やってみます!


882 :NAME 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);

上で行けました!

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

http://www.tarikin.net/


884 :NAME IS NULL:2009/08/21(金) 11:18:57 ID:???
PostgreSQLにはNOT INもNOT EXISTSもあるよ
NOT INでパフォーマンスが問題になったらNOT EXISTSに置き換えるのが手っ取り早い

885 :NAME IS NULL:2009/08/21(金) 19:54:25 ID:???
DB初心者です。すごく初歩的な質問かもしれませんがよろしくお願いします。

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

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



886 :NAME IS NULL:2009/08/21(金) 20:02:11 ID:???
replaceで'日目'を''に、とか。

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

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

ありがとうございます!


888 :NAME IS NULL:2009/08/21(金) 20:51:18 ID:???
どういう使い方してるかわからんからアレだけど
一般的にはテーブルに「日目」を付けない状態で格納する。

889 :NAME IS NULL:2009/08/21(金) 21:16:48 ID:???
金額に「円」つけて格納してたりして

890 :NAME IS NULL:2009/08/21(金) 21:34:13 ID:???
格納は別の人がやってるor既存データ
とかなんでないの?
よくあること。

891 :885:2009/08/21(金) 23:23:50 ID:???
>890

おっしゃるとおりです。
別のアプリケーションでデータをテーブルへ格納するので、
そこからビューを作って特定の列どうしを計算したりするつもりでした。

892 :NAME IS NULL:2009/08/22(土) 00:17:21 ID:???
テーブルの中身をさっさと修正した方が今後の為に良いように思うけどなぁ


893 :NAME 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だけとなります

894 :NAME 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
;
とか?

895 :893:2009/08/23(日) 16:03:22 ID:???
>>894
うまく行きました
本当にありがとうございます

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

現在A,B,C各々にインデックスは張っています
さらに高速化が望めるインデックスの張り方ってありますでしょうか?

896 :NAME IS NULL:2009/08/23(日) 16:07:38 ID:???
>>893
cbで指定したときはA=2ではなくてA=1じゃないのか?

897 :NAME IS NULL:2009/08/23(日) 16:10:47 ID:???
俺なら

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

ってテーブルにする。

898 :NAME IS NULL:2009/08/23(日) 16:11:51 ID:???
もうカラムCを横に繋げて持っちゃえよ

899 :NAME IS NULL:2009/08/23(日) 16:12:50 ID:???
ああスマンかぶった

900 :NAME IS NULL:2009/08/23(日) 16:17:58 ID:???
>>895
create index IndexName on TableName (C, B, A);
かな?
やってみんとわからんが

901 :NAME IS NULL:2009/08/23(日) 16:23:22 ID:???
>>894の例だとCの値の数だけSQL作らないといけないな。
動的SQLでもいいが。

902 :NAME IS NULL:2009/08/23(日) 16:32:31 ID:???
>>896-901
いろいろ議論ありがとうございます.

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

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

>>900
インデックスはってみます

903 :NAME IS NULL:2009/08/23(日) 16:35:46 ID:???
時間がかかるとか、不都合な部分を自分以外に原因を持って行くのは楽だよなあ

904 :NAME 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'

906 :NAME IS NULL:2009/08/23(日) 22:34:38 ID:???
そんなテーブルどうやってメンテするんだよ
まあもともとのテーブルも似たようなもんだが

907 :NAME IS NULL:2009/08/23(日) 22:51:16 ID:???
列名はA、B、Cとかじゃないんだろうけど、
もうちょっと相関性のあるデータの入れ方を力説した方が良かったんじゃないかな〜

908 :NAME IS NULL:2009/08/24(月) 07:10:01 ID:TouBA/nc
SQLiteを使っています。(質問としてはSQL一般です)

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

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

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

DB初心者のため、的外れな質問かもしれません。
より適切なスレッドがあれば誘導してください。
よろしくお願いいたします。

909 :NAME IS NULL:2009/08/24(月) 07:33:00 ID:???
インデックスと言っているのは外部キーの事だよね?
Accessで連鎖更新・削除が出来た気がする。
つかここはSQL文のスレだからツールとかはスレ違い。

910 :908:2009/08/24(月) 08:08:48 ID:???
>インデックスと言っているのは外部キーの事だよね?
はい。SQL用語のインデックスのことではないです。
(SQL用語に"インデックス"があるのを今調べて知りました)
紛らわしくてすみません。

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

>Accessで連鎖更新・削除が出来た気がする。
考えていたことに近いです。
>つかここはSQL文のスレだからツールとかはスレ違い。
やはりツールに依存する機能なんですね。すみません。

911 :NAME 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 や <、>を使って出来るのは判るのですが。



912 :NAME IS NULL:2009/08/24(月) 09:11:12 ID:???
>>839-843あたり

913 :NAME IS NULL:2009/08/24(月) 09:15:15 ID:???
>>912
thxです

914 :NAME 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です。よろしくお願いします。

915 :NAME IS NULL:2009/08/24(月) 21:42:44 ID:???
適当に書いたから、動かないかもしれん

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



916 :NAME IS NULL:2009/08/24(月) 21:44:37 ID:???
row_numberが1のものを更新する

917 :NAME IS NULL:2009/08/24(月) 21:48:22 ID:???
>>914
in句を使って絡めてみた。

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

どうすか?

918 :914:2009/08/24(月) 21:57:31 ID:???
>>915
>>917
早速試してみましたところ、いずれの方法でも求める結果が得られました!
みなさんありがとうございました。

919 :916:2009/08/24(月) 21:58:57 ID:???
シカトかよ

920 :NAME IS NULL:2009/08/24(月) 22:00:18 ID:???



ぷっ





921 :NAME IS NULL:2009/08/24(月) 22:24:03 ID:???
row_numberって、where句に直接使えるんだっけか?
select句にしか使えないんだったら、maxの方が簡単だべ。
個人的には相関サブクエリを薦めるけども。

922 :NAME 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に変換しているのでしょうか?
よろしくお願いします。


923 :NAME IS NULL:2009/08/26(水) 01:26:25 ID:???
>>922
CASE文の結果(出力)をNUMERIC(38,8)にキャストですね。
キャスト演算子"::"はPostgreSQLの方言だと思っていたけど、
他にも使えるのかな?

924 :NAME IS NULL:2009/08/26(水) 01:29:38 ID:K0v/cQev
ありがとうございます。PostgreSQL派生のDBからの質問でした。
オラクルではできない書き方なのですね。

925 :NAME IS NULL:2009/08/26(水) 03:52:24 ID:K0v/cQev
すいません、もうひとつだけ。
SELECT 'my name'::"NAME";
とやると、
my name
と表示されるのですが、これはいったいなにをやっているのでしょうか?


926 :NAME 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/
でどぞー。

927 :NAME 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



928 :NAME IS NULL:2009/08/26(水) 11:35:59 ID:???
最初のテーブルとほとんど変わってないように見えるけど。
NULLも出したいということ?

929 :NAME 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(品名,)

930 :NAME 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 品名
;

931 :930:2009/08/26(水) 19:05:45 ID:???
てか>>5そのままだた

932 :NAME IS NULL:2009/08/26(水) 19:21:07 ID:???
ほんとだw

933 :NAME IS NULL:2009/08/26(水) 19:31:18 ID:???
つか文法間違えてない?w
日付もTO_DATEがいりそうな

934 :NAME IS NULL:2009/08/26(水) 19:48:54 ID:???
            /)
           ///)
          /,.=゙''"/
   /     i f ,.r='"-‐'つ____   こまけぇこたぁいいんだよ!!
  /      /   _,.-‐'~/⌒  ⌒\
    /   ,i   ,二ニ⊃( ●). (●)\
   /    ノ    il゙フ::::::⌒(__人__)⌒::::: \
      ,イ「ト、  ,!,!|     |r┬-|     |
     / iトヾヽ_/ィ"\      `ー'´     /

935 :NAME 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  |
    ・
    ・
    ・



936 :NAME IS NULL:2009/08/26(水) 23:27:46 ID:???
>>934
TRUNCATE

937 :NAME 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;


938 :NAME 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);

お門違いの回答ならすいませぬ。

939 :NAME IS NULL:2009/08/27(木) 02:04:55 ID:???
pやqが?直後に来るとは限らないし、=以後は&か文末が現れるまででしょ。
正規表現で書くなら engineテーブルのidをIDと書くけど。
[\?&]ID=([^&$]*?)
かな。MySQLの文字列連結だとconcat('[\?&]' , id , '([^&$]*?)') な具合だろうけど、
MySQLがどこまで正規表現に対応しているのかしらね。
実際はホスト言語側でURLテーブルに挿入する時点で処理(search分離)しておくべきでしょうね。

940 :NAME IS NULL:2009/08/27(木) 06:17:03 ID:0vbJ9O4e
>>937-939
>pやqが?直後に来るとは限らないし、目的の項目(例えばq=aaa)以後は&か文末が現れるまででしょ。
おっしゃる通りです。説明不足ですみませんでした。

昨夜まで「あれ?これ無理なんじゃない?」と思ってたんですが
皆様のご提示内容を参考にすると出来そうな感じになってきました。
ありがとうございます!
今日一日空き時間使って悩んでみます!


941 :939:2009/08/27(木) 06:34:02 ID:???
正規表現間違えていたので、一応訂正しておく。
× [\?&]ID=([^&$]*?)
○ [\?&]ID=([^&$]*)
○ [\?&]ID=(.*?)(&|$)
こんな感じかな。テストしていないけど。

942 :927:2009/08/27(木) 15:22:35 ID:???
>929,930

ありがと、解決しました。

943 :935: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   |   |


944 :935: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つの列に複数種類の値を設定できないですもんね。

いや、そのあたりは何とかなりそうな気がする。

947 :935: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); で一行しか返らないという条件付きな。

949 :935: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つにする方法をご存じないでしょうか。

953 :NAME 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( 文字列 , ' +', ' ')

954 :NAME IS NULL:2009/08/30(日) 20:18:25 ID:???
訂正
×regexp_replace( 文字列 , ' +', ' ')
○regexp_replace( 文字列 , ' +', ' ' ,'g')

955 :935:2009/08/30(日) 20:45:51 ID:IiFjmKoL
>>954
なるほど!
やっと内容が把握できました。確かにこれならイケます。
でもこれ、Mysql(実行環境がmysql5.0なんです)で実行できるんだろうか(汗)
mysqlで出来る出来ないは置いといて、超勉強になりました!


956 :935:2009/08/30(日) 20:46:45 ID:IiFjmKoL
アンカミス><
>>953でした。

957 :NAME IS NULL:2009/08/30(日) 21:01:02 ID:???
>>953
回答ありがとうございます。
DBはMysqlです。


958 :NAME IS NULL:2009/08/30(日) 23:35:41 ID:???
>>950
mysqlの正規表現は>>945が言ってる通りMySQLの正規表現で部分抽出や置換が出来ない。
プログラムで対処するしかない。

959 :NAME IS NULL:2009/08/30(日) 23:37:43 ID:???
再帰的にREPLACEする関数を作ればいいんじゃないの

960 :NAME 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(ここが固定)で投入したいのです。
方法がありましたら教えてください。

961 :NAME IS NULL:2009/09/03(木) 16:50:39 ID:???
23:59:59 足せばいいんでないの??

962 :NAME 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");

ありがとうございます。

963 :NAME IS NULL:2009/09/03(木) 20:41:36 ID:x4DugVd9
t

964 :NAME 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

で、更新しようとしたのですが、更新すべき件数を認識してくれますが、
データは反映されません。
初歩的な質問な気がしますが、ヒントだけでもお願いします。


965 :NAME IS NULL:2009/09/03(木) 20:50:26 ID:???
SQL を勉強してから来い

966 :NAME IS NULL:2009/09/04(金) 13:46:31 ID:???
Oracle10gを使用しています。
MERGE文で、
WHEN MATCHED AND TBL_1.CD_A <> TBL_2.TCD_A THEN
....
という感じで指定したいのですけど、
Oracleではどのように指定するのでしょうか?><


967 :NAME 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
...

という感じじゃね

968 :NAME IS NULL:2009/09/04(金) 14:50:20 ID:???
>>967
ご回答ありがとうございます。
いろいろ勘違いしてたみたいです。

969 :NAME IS NULL:2009/09/05(土) 18:22:57 ID:GS7w5l+v
access 2000使ってます

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

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

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

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

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



970 :NAME IS NULL:2009/09/05(土) 18:44:59 ID:???
select * from tbl1, tbl2
where tbl1.id1 + tbl1.id2 = tbl2.id3

971 :NAME IS NULL:2009/09/05(土) 19:18:19 ID:???
こんな簡単に出来たんすか・・
すいません、ありがとうございました

972 :NAME 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)を作成しましたが改善されません.

どなたかご助力いただけませんでしょうか

973 :NAME IS NULL:2009/09/07(月) 00:22:35 ID:???
MYSQLてフルテキストインデックスて無いんだっけ?

974 :972:2009/09/07(月) 00:38:04 ID:???
>973

標準のMySQLには英文のものしかありません.
ですので
http://qwik.jp/tritonn/
こちらの全文検索エンジンを導入しています.

975 :972: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が有効に使われるようになったようです.

うまくいったのはいいのですが,
なぜうまくいくのか理由がわからないので,
次回のためにもどなたか解説いただけませんでしょうか.

976 :NAME 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です。
宜しくお願いします。

977 :NAME IS NULL:2009/09/08(火) 01:35:13 ID:LRxN+yRN
すみません。
コピペミスです。

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

大変失礼しました。


978 :NAME 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);

単純にだとこうかなぁ。

979 :NAME IS NULL:2009/09/08(火) 01:44:06 ID:???
>>976
(1)と(2)のそれぞれのSQLが知りたいのか?
それとも(1)と(2)同時にとりたいのか?
前者の(1)なら普通にJOINすればいいだけなんだから、(1)がわからないのはあり得ないか?
なら後者? でもどういう出力が欲しいのかわからないので、出力サンプル出してみ。

980 :NAME IS NULL:2009/09/08(火) 01:45:03 ID:???
ああ、(1)はJOINでよかったかorz

981 :NAME 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

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


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





982 :NAME 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

 ・
 ・
単純にコピーなどでできたらいいんですが、レコード行数が限界を超えてしまったための策です。
お願いします。

983 :NAME 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

と変更する。

未確認なので、雰囲気だけ感じてくださいな


984 :NAME IS NULL:2009/09/08(火) 02:30:46 ID:???
>>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

277 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)