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

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

SQL質疑応答スレ Part 2

1 :NAME IS NULL:04/12/15 21:19:15 ID:???
■関連スレ

Oracle 総合 Session2
http://pc5.2ch.net/test/read.cgi/db/1091508494/

MS SQL Server 総合スレ2
http://pc5.2ch.net/test/read.cgi/db/1093012583/

【まだまだ】Microsoft Access クエリ2【使える】
http://pc5.2ch.net/test/read.cgi/db/1089161114/

PostgreSQL & pgsql-jp ML 3テーブル目
http://pc5.2ch.net/test/read.cgi/db/1079771059/

MySQL 総合 Part3
http://pc5.2ch.net/test/read.cgi/db/1096838301/

IBM DB2 スレ
http://pc5.2ch.net/test/read.cgi/db/1057170768/

諸君、私はSybaseが大好きだ【ASE】
http://pc5.2ch.net/test/read.cgi/db/1080536260/


2 :NAME IS NULL:04/12/15 21:42:40 ID:???
早速ですが質問です。
サーバーAとサーバーBに同じレイアウトのテーブルがあって、
サーバーAのデータをサーバーBにインサートしたいのですが、上手いやり方はないでしょうか?

3 :NAME IS NULL:04/12/16 00:30:24 ID:???
>2
 どんな DBMS でも、データのバルクアウト・バルクインをするツールくらいあるだろ。
 サーバAからバルクアウトして、サーバBにファイルを持っていって、バルクインする
だけですむじゃないか。

 レプリケーションならまた別だが。

4 :NAME IS NULL:04/12/16 01:08:05 ID:euThd3sb
>>2
ACCESSで言うところのリンクテーブルをBに作って、Aのテーブルを参照できるようにしたらええよ

5 :NAME IS NULL:04/12/16 13:37:41 ID:???
999 名前:NAME IS NULL[sage] 投稿日:04/12/16 11:56:17 ID:???
1000ならE.F.コッド復活


1000 名前:NAME IS NULL[sage] 投稿日:04/12/16 11:56:37 ID:???
1000ならE.F.コッド復活しない


1001 名前:1001[] 投稿日:Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。


6 :NAME IS NULL:04/12/16 16:18:35 ID:x7wdOupz
すいません。
テーブルのカラムにUNIQUE指定を追加したり削除する
構文を教えてください。


7 :NAME IS NULL:04/12/16 16:28:30 ID:???
  ∧ ∧     ┌─────────
  ( ´ー`)   < シラネーヨ
   \ <     └───/|────
    \.\______//
      \       /
       ∪∪ ̄∪∪


8 :U ◆CZtFsGiu0c :04/12/16 16:37:48 ID:???
>>6
ALTER TABLE テーブル名 ADD CONSTRAINT 制約名 UNIQUE(カラム名)

9 :NAME IS NULL:04/12/16 16:54:20 ID:x7wdOupz
ありがとうございます。
解除する方法も教えてください。


10 :NAME IS NULL:04/12/16 16:55:44 ID:HkQr2izB
自分で調べろ。本屋に行く能力か、検索エンジンを使う能力があれば、アホでも解ることだ。

11 :NAME IS NULL:04/12/16 18:26:53 ID:x7wdOupz
>>10
いや駄目です。
実はUNIQUE追加は分かってたのです。
しかし、UNIQUE指定を外すのは、なかなか見つからなかったのです。
と言うか、その発言からするに、アナタは全然知らないでしょう。
無駄な煽りレスはやめてください。


12 :NAME IS NULL:04/12/16 18:33:38 ID:???
次の患者さんどうぞ

13 :U ◆CZtFsGiu0c :04/12/16 18:46:50 ID:???
>>11
ALTER TABLE テーブル名 D
NO CAREER

14 :NAME IS NULL:04/12/16 18:48:23 ID:PxuDTuxN
荒れる原因だから、教えてくんには答えない方がいいと思う。
教える方も悪い。

15 :NAME IS NULL:04/12/16 18:50:23 ID:???
>>13
明らかに解ってて釣ってるんだから答えるなよ

16 :NAME IS NULL:04/12/16 18:53:02 ID:x7wdOupz
>>13
どうもありがとうございました。

17 :NAME IS NULL:04/12/16 18:58:04 ID:???
>>10
>>12
>>14
>>15
クズオタクどもめ。氏ね!

>>14
何が教えてくんには答えるなだ。ここは質問スレだぞ。
パソコンから離れたら同僚からいじめられるだきの
ネット弁慶のザコオタの分際で。消えろ。


18 :NAME IS NULL:04/12/16 19:04:24 ID:d6gV77wB
ザコオタ頼りにしてる時点であんたの負けですから! 残 念!!

19 :NAME IS NULL:04/12/16 19:05:17 ID:???
>ここは質問スレだぞ。

じゃあ、質問だけ勝手にすれば?

20 :NAME IS NULL:04/12/16 19:11:12 ID:???
釣られるな。図星だったかと笑われて向こうが増長するだけだぞ。

21 :NAME IS NULL:04/12/16 19:11:50 ID:???
>>22
すみませんねえ。
前の患者さんがウンコ漏らしちゃったんで、今日はもう休診なんですよ。

22 :NAME IS NULL:04/12/16 21:13:10 ID:qu9wwr5Z
foo というテーブルに、hoge fuga hige moe
という2つのフィールドがあります。

で、hoge fuga higeが3つとも同じレコードについては、まとめて1レコードとみなし、
fooテーブルが何レコード持っているか調べたいのですが・・・
//-----------------------------------------------------------
例です:
hoge fuga hige moe
1 3 5 6
1 3 4 5
1 3 5 8
1 5 5 5
(↑1行目と3行目を同じとみなし、レコード数は3)
//-----------------------------------------------------------
どうゆうSQL文を書いたらよいのでしょうか?

select sum(*) from favorite group by hoge, fuga, hige
とやってもだめでした(そりゃそうだよね。。。)

どなたか教えていただければ幸いです。

なお、Postgres(すいません、バージョンは今わかりません)です

23 :U ◆CZtFsGiu0c :04/12/16 21:30:42 ID:???
>>22
SELECT COUNT(*) FROM (SELECT DISTINCT hoge, fuga, hige FROM foo)
ではどうですか? もっと簡潔にできるのかな。

24 :NAME IS NULL:04/12/17 00:00:08 ID:???
>>11
ADD CONSTRAINT があるなら DROP CONSTRAINT があるだろうという推測はできないのか?

25 :22:04/12/17 02:24:18 ID:xyylN+gv
>>23
ありがとうございます。

もう1度似たような質問’たぶんあってると思うんだけど・・・)ですがよろしいでしょうか?

foo というテーブルに、hoge fuga hige moe
という2つのフィールドがあります。

で、hoge fuga hige の組み合わせで、同じ組み合わせがあるか否かどうかって、
どういうふうに書いたら良いのでしょう?

SELECT COUNT(*) AS cnt FROM (SELECT hoge, fuga, hige FROM foo GROUP BY hoge,fuga, hige)
で、
cntに1以外のものがあるかどうかを、
なんかのスクリプトで(PHPの予定ですが)見ればいいでしょうか?
(CASE文とかよく分からないもので(汗))

p.s.
今自宅で環境もととのってないためテストできず、気になって眠れず・・・
会社いけばテストできますが・・・

26 :NAME IS NULL:04/12/17 03:34:12 ID:???
select (case when count(*) > 0 then 'true' else 'false' end) as result
from (select count(*) as cnt from hoge group by hoge,fuga, hige) as sub
where sub.cnt > 1;

これで、resultカラムにtrueかfalseが入ります・・・

27 :NAME IS NULL:04/12/17 03:56:47 ID:???
>>25
Webprog板での質問から疑問に思っていたんだけど、

>foo というテーブルに、hoge fuga hige moe
>という2つのフィールドがあります。

4つじゃなくてなんで”2つ”なの?

同じ組み合わせがある物だけを抜き出すのなら、

SELECT hoge,fuga,hige FROM foo GROUP BY hoge,fuga,hige HAVING count(*)>1;


28 :NAME IS NULL:04/12/17 22:39:17 ID:lankP6pa
質問です。
Column--a,b
(PK1-a,PK2-b)
を持つテーブルAに以下のようにデータが入っています。
a  b
------
1  5
1  2
1  1
2  10
2  5
2  1
3  100
3  50
3  5

ここから、
a  b
------
1  5
2  10
3  100
と抽出したいのですが、どのようなSQLを書けばよいのでしょうか?
よろしくお願いします。


29 :NAME IS NULL:04/12/17 22:57:03 ID:???
>28
aで纏めてbの最大値を出したいという意味なら、

SELECT a,MAX(b) AS b
FROM テーブルA
GROUP BY a

30 :28:04/12/17 23:10:06 ID:lankP6pa
>29
ありがとうございます。
意とするところは、そのようになります。
Max の使い方なんですね。少し調べてみます。
さらに発展させて、

Column--a,b,c
(PK1-a,PK2-b,PK3-c)
を持つテーブルAに以下のようにデータが入っています。
a  b  c
-----------
1  5  5
1  5  4
1  1  9
2  9  1
2  8  9
2  1  1
3  9  1
3  5  100
3  1  1000
から、
a  b  c
-----------
1  5  5
2  9  1
3  9  1
と抽出したいのですが、(実はこちらが本当の宿題なのですが)
似たような感じで出来そうですね。
がんばってみます。

31 :28:04/12/17 23:22:27 ID:lankP6pa
SELECT a,MAX(b),c AS b
FROM
(
SELECT a,b,MAX(c) AS c
FROM テーブルA
GROUP BY a,b
)
GROUP BY a

これで解決しました!
(もちっと、キレイにできるかもしれないが)


32 :NAME IS NULL:04/12/18 00:57:16 ID:???
>>31
動くのかそれ? 使っているDBMSは何?

SELECT *,
(SELECT MAX(c) FROM Table_A WHERE a=t1.a AND b=T1.b )AS c
FROM (SELECT a,max(b) AS b FROM Table_A GROUP BY a)AS T1;

33 :NAME IS NULL:04/12/18 02:28:27 ID:???
firebird1.0.3使っています。
コマンドプロンプトで複数行のSQL文を打つ場合
途中で間違えた時(>CONというプロンプトが帰ってくる)に
キャンセルするにはどうしたらいいですか?
Ctrl+Cやったら接続が遮断されてしまいました・・・

34 :NAME IS NULL:04/12/18 14:59:46 ID:???

\c

35 :NAME IS NULL:04/12/18 15:04:26 ID:???
>>33
一般的なSQL構文と異なる、製品に依存するような質問は専用スレで聞いたほうがいいと思うよ。

Firebird関連スレ 
ttp://pc5.2ch.net/test/read.cgi/db/1057050009/l50

36 :NAME IS NULL:04/12/18 20:49:31 ID:???
>>34
できました。ありがとうございます。

37 :NAME IS NULL:04/12/19 21:49:55 ID:J0WodSf9
質問です。
VB6(DAO)で.mdbファイルにテーブルを作成する際、それと同時にフィールドの説明欄への
文字入力を行うためのSQLコマンドは存在するのでしょうか?

過去にどこかで見たような気がするのですが、必要になったとき探してみると見つからなくて…。


38 :NAME IS NULL:04/12/19 23:12:07 ID:???
一般的なSQL構文と異なる、製品に依存するような質問は専用スレで聞いたほうがいいと思うよ。

【まだまだ】Microsoft Access クエリ2【使える】
http://pc5.2ch.net/test/read.cgi/db/1089161114/

39 :NAME IS NULL:04/12/22 18:30:16 ID:???
SQL Server 2000 です。

レコードの抽出結果の行/列を入れ替えるのに何かよい方法はないでしょうか?

例えば ID, ROW, CD, SUU という項目をもったテーブル を抽出し、

ID, ROW, CD, SUU, ROW, CD, SUU, ROW, CD SUU.... のようにしたいのです。

例えばテーブルに
1,1,1,1
1,2,2,1
1,3,1,2
1,4,2,2
とデータがあったら、
1,1,1,1,2,2,1,3,1,2,4,2,2 と返したいのですが。
元のテーブルの行数は不定です。

何かよい方法はないでしょうか?

40 :NAME IS NULL:04/12/23 00:20:49 ID:???
>>39
SQLで頑張らないでクライアント側で処理するのが吉。

41 :NAME IS NULL:04/12/23 14:30:46 ID:???
環境はOracle9iです。

日次の売上データがあります。
売上データから週次(日〜土)の統計値を抽出したいのです。

抽出したいのは、週ごとの売上の合計値、最大値、最小値、平均値です。

月次では簡単にできたのですが、週次うまくだとできません。
どなたか教えてください。


42 :NAME IS NULL:04/12/23 14:38:15 ID:???
月次を晒せ

43 :NAME IS NULL:04/12/23 15:20:20 ID:???
>42
おお、さっそく
確かこんな感じです。

select to_char(day, 'YYYYMM'), sum(val), max(val), min(val), avg(val)
from t
where day between '2000/1/1' and '2003/12/31'
group by to_char(day, 'YYYYMM')



44 :41:04/12/23 15:22:58 ID:???
訂正
s/週次うまくだとできません/週次だとうまくできません/

45 :NAME IS NULL:04/12/23 16:48:06 ID:???
TO_NUMBER(TO_CHAR(日付, 'DDD'))/7

46 :41:04/12/23 17:38:43 ID:???
>45
ありがとうございます。
なるほど、そういうやり方があったか。
なんとなくできそうな気がします。

47 :NAME IS NULL:04/12/23 21:24:36 ID:qlzX5+ej
グルーピングする明細の中に存在するコードを、
マスタと接続して名称をとってくる時に、その名称も
なんらかの計算式にしないといけないのですが、普通、それらは
どうするんでしょう?

例としては
売上データの月次集計を行ないたい時、売上データには商品コードしかないので
商品マスタと JOIN して商品名を表示させたいのですが、商品名は Where
対象ではなく、Group By の中に書くしかないと思うのですが、その場合、
商品名はグルーピング対象ではなくて、集計対象となった商品コードに
該当する商品名を取得したいのですが、どうすべきかわかりません。

グループ化する必要はないのですが、Group By の中に入れるのが
一般的でしょうか?それとも、意味はないですが MAX とかつけて
演算対象とするのが一般的でしょうか?

わかりづらいかもしれませんがよろしくお願いします。


48 :NAME IS NULL:04/12/24 12:02:42 ID:???
グループ化された結果と商品マスタをJOINする
SELECT 商品マスタ.商品名,a.* FROM 商品マスタ
INNER JOIN (SELECT 商品コード,〜 FROM 売り上げデータ GROUP BY 〜) AS a
ON 商品マスタ.商品コード=a.商品コード

49 :NAME IS NULL:04/12/24 21:33:15 ID:???
>41,46

TRUNCATE(日付,'WW')

という手もあります。書式は間違っているかもしれません。


50 :NAME IS NULL:04/12/27 13:36:35 ID:???
select * from table as a,table as b,table as c
where a.col *= b.colの*=の意味はどう解釈したらよいですか?

51 :NAME IS NULL:04/12/27 14:04:17 ID:???
外部結合と解釈

52 :NAME IS NULL:04/12/27 14:08:02 ID:???
>51
ありがとうございました!

53 :NAME IS NULL:05/01/10 23:12:56 ID:???
Blobカラムに、バイナリデータを書き込みたいのですが
16進数で 5c,5c,27 (\\') というバイトの並びがあると
エラーが出てしまい書き込めません。
どうすればBlobにデータを書き込めるのでしょうか?


54 :NAME IS NULL:05/01/11 00:17:49 ID:???
>>53
DBMSと開発言語、それとDBアクセスに使ってるライブラリを明示しないと
誰も答えようがないぞ

55 :NAME IS NULL:05/01/11 09:37:39 ID:???
Accessのmdbです。
 ┏━━━━━┓  ┏━━━━━━━━┓          
 ┃部品     ┃  ┃品目- 品目_ 再帰 ┃   ┏━━━━━┓ 
 ┃----------┃  ┃----------------┃   ┃部品_1   ┃ 
 ┃部品コード ┠─┨親部品コード    ┃  ┃----------┃ 
 ┃…      ┃  ┃子部品コード    ┠─┨部品コード ┃ 
 ┗━━━━━┛  ┃員数         ┃  ┃…      ┃ 
             ┗━━━━━━━━┛  ┗━━━━━┛ 
                              
のようなリレーションシップになっており、[部品]=[部品_1]なのですが、
これを子部品が無くなるまで展開し尽くして集計するのは、
SQLだけでは無理だとは思うのですが、
具体的にはどのようにやるのが良いのかどうしても結論が出ません。
アドバイスいただけると助かります。

http://pc5.2ch.net/test/read.cgi/db/1057509675/192-

56 :NAME IS NULL:05/01/11 10:08:33 ID:???
>>55
隣接リストモデルの木構造を展開して部品リストを作りたいのだと思うのだけど、
SQLだけだと無理だなぁ。ストアドなどを使ってDBで展開するか、ホスト言語から
再帰的に問い合わせするかどちらかしかない。
ってことで、スレ違いかなー。

新スレに移ってからSQLの質問てあまりないな。

57 :NAME IS NULL:05/01/11 10:11:32 ID:???
>>56
ありがとうございました。

58 :56:05/01/11 10:15:20 ID:???
つっこまれる前に補足
SQL99には再帰的に呼び出すコマンドが追加されていたような希ガス。
DBMSによっては既にあるのかも。
あと、関数なんかで用意されていたりしたりする。

59 :NAME IS NULL:05/01/11 14:38:57 ID:???
ソフトウェア開発技術者試験のためにSQL勉強しなきゃならんのですが
おすすめの本とかある?
午後の試験でいつもSQLで点取り逃してるから勉強しようかと思うんだけど。
将来的にはSQL使わないから、初心者向けのでOKかなぁ

60 :NAME IS NULL:05/01/11 20:25:59 ID:???
>>58
これだな http://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html

最新DBMSなら再帰SQLが使えるようになってきてるが
mdbじゃどう頑張っても無理な話。AccessVBAで何とかすることになるだろうな。

61 :57:05/01/11 20:47:03 ID:???
データモデリング勉強しても実装力が全然おっつきません。。。(TーT

62 :NAME IS NULL:05/01/11 22:35:09 ID:???
>>59
SQLが一番簡単なわけだが。

63 :NAME IS NULL:05/01/13 15:00:55 ID:???
Oracle8i使ってます。
2つのテーブルを外部結合して副問い合わせしたいのですが
うまくいかなくて悩んでます。

SELECT A.Code,A.Name,B.Name2 FROM A,B
WHERE A.Code=B.Code(+)
AND (B.Code,B.Date) IN
(SELECT B.Code,MAX(B.Date) FROM B GROUP BY B.Code);

Aテーブル Bテーブル
Code Name Code Name2 Date
0001 AAAA 0001 GGGG 2004/01/01
0002 BBBB 0001 HHHH 2004/02/02
0003 CCCC 0001 IIII 2004/03/03
0004 DDDD 0002 JJJJ 2004/01/01
0005 EEEE 0002 KKKK 2004/03/03
0005 LLLL 2004/02/02

結果:
0001 AAAA IIII
0002 BBBB KKKK
0003 CCCC (null)
0004 DDDD (null)
0005 EEEE LLLL

64 :NAME IS NULL:05/01/13 15:03:08 ID:???
表がズレました スイマセン

Aテーブル   Bテーブル
Code Name  Code Name2 Date
0001 AAAA  0001 GGGG 2004/01/01
0002 BBBB  0001 HHHH 2004/02/02
0003 CCCC  0001 IIII 2004/03/03
0004 DDDD  0002 JJJJ 2004/01/01
0005 EEEE  0002 KKKK 2004/03/03
       0005 LLLL 2004/02/02

結果:
0001 AAAA IIII
0002 BBBB KKKK
0003 CCCC (null)
0004 DDDD (null)
0005 EEEE LLLL

65 :NAME IS NULL:05/01/13 15:11:23 ID:???
結果:
0001 AAAA IIII
0002 BBBB KKKK
0003 CCCC (null)
0004 DDDD (null)
0005 EEEE LLLL

こうなって欲しいんだけど
0003 と 0004が取得できません。
誰か教えてください エロい人

66 :NAME IS NULL:05/01/13 16:00:19 ID:???
Oracleは知らんけど、LEFT(RIGHT) JOIN 使わなきゃ駄目では?

67 :NAME IS NULL:05/01/13 16:58:43 ID:???
Oracle では、left join、right join を (+) で指定できます。

SELECT * FROM A,B WHERE A.Code=B.Code(+)
SELECT * FROM A LEFT JOIN B ON A.Code = B.Code

どちらも同じ意味です

68 :NAME IS NULL:05/01/13 22:45:31 ID:epuALH3a
たとえば以下のようなテーブルで
各グループが登録した結果が何件あるかをカウントしたい
ただし、同一ID-Aに対する結果を複数登録してある場合は1件でカウントする

具体的にどうすれば実現できますか?
DBはMySQLを使っています

tabA
ID-A  内容
1   aaa
2   bbb
3   ccc

tabB
ID-A グループ  結果
1   1     1
1   1     2
1   2     2
2   2     4
2   2     2
2   3     4
2   4     2
3   1     3
3   2     6


求める結果は

グループ 件数
1    2
2    3
3    1
4    1


69 :NAME IS NULL:05/01/13 23:13:24 ID:???
>>63
SELECT A.*,T2.Name2 FROM A LEFT JOIN (
SELECT * FROM B AS T1 WHERE Date = (SELECT Max(Date) FROM B WHERE Code=T1.Code)
)AS T2 USING(Code);

--思いつき。なんか冗長な気がしないわけでもない :-)

70 :NAME IS NULL:05/01/13 23:25:44 ID:???
>>68
MySQLで動くかどうか知らんが、こんな感じか?
SELECT グループ,count(ID-A) FROM (SELECT ID-A,グループ FROM tabB GROUP BY ID-A,グループ) GROUP BY グループ;

tabAも関係ないし、tabBの「結果」カラムも関係ないな。

71 :68:05/01/13 23:39:42 ID:epuALH3a
>>70
早いですね ありがとうございます
明日試してみます

4.1系なので副問い合わせも大丈夫です

72 :yo-ko:05/01/14 10:17:33 ID:UC20sTBi
MySQLにて販売管理をしようとしています。
売上に対し複数の請求と入金がある場合があり、売上のレコードごとに請求・入金の合計値を出したいのですが悩んでます。


テーブル:売上
No B 金額
1 1  800
2 1  900
3 2  500
4 3 800
5 1 300


テーブル:請求
No 金額
1 800
2 500
2 200
4 300
5 300

テーブル:入金
No 金額
1 400
1 200
3 300
2 400
3 900
1 200

B = "1" の時の結果が以下になるようなselect文が解りません。
No 売上 sum(請求) sum(入金)
1 800  800 800
2 900  700 400
5 300  300 null

以下のように書くと入金テーブルと請求テーブルがクロス結合のようになって複数のレコードがあると
それぞれダブって集計してしまいます。なんとかならないものですかね。

SELECT 売上.No, 売上.B, sum(請求.金額), sum(入金.金額)
FROM 売上
LEFT JOIN 入金 ON 売上.No = 請求.No
LEFT JOIN 請求 ON 売上.No = 入金.No
WHERE 売上.B = 1
GROUP BY 入金.No ;

No C sum(D) sum(E)
1 800  2400 800
2 900  700 800
5 300  300 null


73 :NAME IS NULL:05/01/14 12:23:02 ID:???
>>72
SELECT 売上.No , 売上.金額 , T1.請求金額 , T2.入金金額
FROM 売上
LEFT JOIN (SELECT No,sum(金額)AS 請求金額 FROM 請求 GROUP BY No)AS T1 ON 売上.No = T1.No
LEFT JOIN (SELECT No,sum(金額)AS 入金金額 FROM 入金 GROUP BY No)AS T2 ON 売上.No = T2.No
WHERE 売上.B = 1;

売上のNoはユニークなんだろ?

74 :yo-ko:05/01/14 13:08:27 ID:UC20sTBi
ありがとうございます。
売上のNoはユニークです。

しかし、試してみたところ'SELECT〜'でエラーが出てしまいました。
MySQLのバージョンでしょうか?
使用しているバージョンは4.0.22です。

よろしくお願いします。

75 :73:05/01/14 14:16:27 ID:???
>>74
思いつきで書いただけなんで、いちいち試してません。
まぁ、MySQLも使ってないけどな。

どこでどうしくじってるんかなぁと、見直してみたがワカンネ。
ひょっとして MySQLってASが余計なんだったけ?

ってことで、ここはMySQL使いに譲って俺は寝るZzz...

76 :NAME IS NULL:05/01/14 15:12:25 ID:???
例えば、以下の構成のようなテーブルがあったときに、

ID AUT
15 片山恭一
11 宮部みゆき
11 我孫子武丸
11 梅原克文
4 京極夏彦

IDの重複しているレコードは無条件で最初の一行のみ選択し、
以下のような結果にしたいのです。

ID AUT
15 片山恭一
11 宮部みゆき
4 京極夏彦

この場合、どのようなSQLを組めばいいのでしょうか?
DBはSQLServerを使用しています。
ご教授お願いいたします。

77 :NAME IS NULL:05/01/14 16:43:10 ID:???
select id, min(aut) as aut from auttable group by id
もし順番が大事なら別のフィールドにシーケンス番号を振らないと保障できないですね。

78 :NAME IS NULL:05/01/14 16:59:48 ID:???
おぉーなるほど、こういうやり方があったのか…
助かりました、ありがとうございます。

79 :NAME IS NULL:05/01/15 01:54:55 ID:eLX+jWNY
>>74
MySQLの4.0系は副問い合わせできないんじゃなかった?
4.1系にすれば副問い合わせはできるよ

80 :NAME IS NULL:05/01/16 18:52:29 ID:MW39mL8U
SQL文のコメントアウトって
-- コメント
でよかったでしたっけ?

81 :NAME IS NULL:05/01/16 19:00:19 ID:???
そのくらい、いちいち質問するようなことじゃない。

82 :yo-ko:05/01/17 10:23:53 ID:1ElqsyMX
>>74
ですよね。
>>72
のようなことをするには、MySQLのバージョンを上げずには
出来ないのでしょうか?

83 :NAME IS NULL:05/01/18 18:23:58 ID:???
質問させて下さい。

select *
from test
where test.field not in (select 〜)

といったようなSQLがあって
サブクエリの実行結果が一件もヒットしないような条件のとき
これを、

select *
from test
where test.field is not null

と書き換えることは文法的に正しいでしょうか?
宜しくお願いします。

84 :NAME IS NULL:05/01/18 19:36:08 ID:???
>>83
書き換えることで文法的に正しいとは?
質問の意図がわからないが、
サブクエリが1行も返さない事とNULLとは別物。
SQLでのNULLは無しとか空という意味じゃなくて「不明」。

85 :NAME IS NULL:05/01/22 18:37:50 ID:pmwmkVIg
質問があります

UPDATE文で
UPDATE RECORD SET (COUNT=X, TOTALCOUNT=Y) WHERE PRIMARY=XXX
上のTOTALCOUNTの値は現在の(COUNTの値+ X)なのですが
この場合、UPDATE文内で現在のCOUNTの値を取得できないのでしょうか?

事前にSELECT COUNT FROM RECORD WHERE PRIMARY=XXX
とやるのは冗長で美しくないと思うのです

環境はAccess2000+DAO3.6です
よろしくお願いいたします

86 :NAME IS NULL:05/01/22 18:54:06 ID:???
>>85
COUNT=COUNT+X

87 :86:05/01/22 18:55:20 ID:???
という意味じゃなさそうだな

88 :86:05/01/22 18:57:32 ID:???
TOTALCOUNT=COUNT+X でいいのか?
このとき、COUNTはXになる前の値。

89 :85:05/01/22 19:09:02 ID:???
>>88
はい、そうです

試しに下のSQLを投げたら怒られました
UPDATE RECORD SET COUNT = 10,
TOTALCOUNT = (SELECT TotalCount FROM Record Where primary_key = '0001')+10
WHERE PRIMARY_KEY = '0001'

Oracleでは確か出来たはずですが・・・

90 :86:05/01/22 20:46:45 ID:???
>>89
いや、単純に、
UPDATE RECODE SET COUNT=10 , TOTALCOUNT=COUNT+10 WHERE...
じゃだめなんかと。

91 :NAME IS NULL:05/01/24 11:31:59 ID:???
全くの初心者で恐縮ですが、
number型の長さが10,0ってどういう意味ですか?

92 :NAME IS NULL:05/01/24 13:30:43 ID:???
有効桁数が全体で10桁で、小数点以下は0桁

93 :91:05/01/24 13:52:49 ID:???
>>92
ありがとうございます。助かりました。

94 :92:05/01/24 15:31:29 ID:jIzajTks
>>72
ってMySQL4.0系では出来ないんですかね?
副問い合わせを使わないでSQL文は書けないんですかね?

95 :NAME IS NULL:05/01/24 18:36:15 ID:???
んあ? 92は俺だ

96 :NAME IS NULL:05/01/25 07:38:06 ID:???
出勤と退勤を管理する仕組みを考えているのですが
うまいSQLが書けずに困っております。
お知恵を拝借できないでしょうか?

1.userテーブル
uid ユーザのユニークID
以下ユーザ情報

2.timeテーブル
uid ユーザ情報
date 日付
stime 出勤時間
etime 退勤時間

1.2のテーブルから、A日のユーザの出退勤情報を取得したいのですが、
その際にA日に出勤していないユーザの情報も取得したいと考えています。

先ほどouter joinしたものにwhereで is null かつA日であるもので抽出しても
以前に一度でも出退勤情報があるユーザが抜けてしまいorz...

cronであらかじめ当日分のデータをインサートするのは避けたいので
SQLのみで対応できないでしょうか?

97 :NAME IS NULL:05/01/25 10:51:27 ID:???
>>96
1のUID(+)=2のUIDで結合じゃないの?

98 :NAME IS NULL:05/01/25 12:47:54 ID:???
こんなじゃ駄目なんかな
SELECT user.name, tm.date, tm.stime, tm.etime
FROM user LEFT JOIN (SELECT * FROM [time] WHERE date=A日) AS tm ON user.uid = tm.uid
WHERE tm.date Is Null


99 :NAME IS NULL:05/01/25 18:25:51 ID:mUHU+OzD
売り上げデータ内客先コード    客先マスタ
uri-customer mr-customer mr-attribute
123        123 red apple
234        234 red strawberry
567        567 red apple

この場合、mr-attributeの5桁目からの文字を参照してappleだけの売り上げデータを
select文一発でもってくることできる?


100 :NAME IS NULL:05/01/25 19:01:58 ID:EnOMoXiA
できる

101 :NAME IS NULL:05/01/25 20:59:30 ID:v05ch7R9
社員表で(社員番号,氏名,所属)とか
商品表で(商品コード,商品名,単価)とかやってて
所属や単価が変わる時って、
社員番号や商品コードを参照している場合、
過去のデータ(例えば単価*受注数など)を参照しようとすると
登録された当時の正しいデータにならないと思うけど、
こういう場合って、どうするの?

SQLで解決できる?テーブル設計で対応しないとだめなのかな?


102 :NAME IS NULL:05/01/25 21:09:16 ID:???
テーブル設計

103 :96:05/01/25 21:26:14 ID:???
ありがとうございます。

98さんのSQLで行けると思ったのですが
どうもMySQL4.0なのでサブクエリができないとのエラーが
でてだめでした。

でも使えそうなSQLなのでしっかり覚えておきます。

104 :NAME IS NULL:05/01/26 11:37:07 ID:g/kUoujd
>>100
SQL文をおしえてくだされ。

105 :NAME IS NULL:05/01/26 11:49:50 ID:???
substring

106 :U ◆CZtFsGiu0c :05/01/26 12:19:57 ID:???
>>101
そういう場合は受注テーブルに単価をコピーするか、単価の履歴テーブル
を持つ、といった対応をする。どちらがいいかはケースバイケース。

107 :NAME IS NULL:05/01/26 13:33:24 ID:???
>>106
ですね。
基本的な仕様に合わせて選択するのが良いかと。

(マスターなどが間違っていても)その時点での単価というのを記録する必要がある
=履歴生成時点のデータが絶対の場合は前者、
あとの処理で過去のデータをその時点の情報で生成しなければならないのであれは後者。

だと思う。


108 :NAME IS NULL:05/01/27 15:53:15 ID:kk66tqqq
SQLテクニックの底上げも兼ねて
かんなり勉強させてもらってます。

name(text)
1,山田
1,山本
1,山下
2,小森
2,小林

というテーブルのデータを
1,山田 山本 山下
2,小森 小林
として取得するSQLは書けないでしょうか?


109 :NAME IS NULL:05/01/27 16:12:14 ID:???
ORACLEとかなら、Noに対する名称を全て連結するストアドファンクションを作成して逃げる

SELECT No, Func(No) FROM Hoge

110 :108:05/01/27 16:30:08 ID:kk66tqqq
すいません、環境書いていませんでした。
access2000です。
普通に作る場面ならストアドプロシージャに逃げるのですが
あまりプログラムでがんばりたくない場面なので、
SQLでの対応を模索中です。汎用SQLじゃ無理かな?


111 :NAME IS NULL:05/01/27 21:54:54 ID:???
無理

112 :NAME IS NULL:05/01/27 23:50:31 ID:???
>>110
AccessVBAで頑張ってくれ

113 :NAME IS NULL:05/01/28 01:12:57 ID:???
Oracle 8i を HP-UXで使用しています。

SELECT DISTINCT
TO_CHAR(rownum,'00')||':'||AAA FROM ZZZ
WHERE BBB = '2'
ORDER BY AAA;

を実行すると
ORDER BY AAA でエラーとなってしまいます。。

ORDER BY を外すとうまくいくのですが
どうにかしてORDER BY したいのです。。

どなたか御教授お願い致します


114 :NAME IS NULL:05/01/28 03:19:31 ID:???
>>113
rownum あるなら、 distinct はいらんのじゃ?

115 :NAME IS NULL:05/01/28 09:43:03 ID:kFFslgY7
select文where句で属性の違うパラメータを比較するにはどうすればよいでせうか?

116 :NAME IS NULL:05/01/28 09:54:45 ID:???
>>115
まず日本語の勉強を・・・・。
それで判るのはえすぱあですよ。

117 :U ◆CZtFsGiu0c :05/01/28 10:37:20 ID:???
>>113
どういうエラーが出ますか?

>>115
おそらくデータ型の異なるフィールドでの比較ではないかと思うのですが、
だとするとどちらかの型に合わせて変換する必要があるでしょう。

>>116
もし合ってたら、えすぱあに認定してください:-)


118 :NAME IS NULL:05/01/28 11:25:50 ID:kFFslgY7
>>117
あなたはえすぱあです。m(__)m
型にあわせて変換 はどうすればよいのでしょうか?DB2なんですが、いまひとつ方法がみあたりません。
DBをJOINしているのですが、それぞれのキー項目が片方は文字、片方が数字なんです。(T.T)

119 :U ◆CZtFsGiu0c :05/01/28 14:51:17 ID:???
>>118
マニュアルはないの? だったら、
http://publib.boulder.ibm.com/infocenter/db2help/index.jsp
から、参照情報 -> SQL -> 関数で変換関数を探しましょう。

120 :NAME IS NULL:05/01/28 15:11:33 ID:???
MySQL4で以下の文が実行できませんでした
alter table tasks add column task_insert_timestamp set default 'now()';

どこがちがうのでしょうか・・・以下ログ。。。

mysql> use hogehoge;
Database changed
mysql> alter table tasks add column task_insert_timestamp set default 'now()';
ERROR 1064: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right s
yntax to use near 'default 'now()'' at line 1
mysql>

121 :NAME IS NULL:05/01/28 15:22:45 ID:???
型は

122 :NAME IS NULL:05/01/28 15:47:39 ID:???
>>120
MySQLは使っていないのだけど、now()のところはシングルクォートて括らなくてもいいんじゃないかな?
TIMESTAMPを返す関数としてじゃなくて、文字列として認識されていそう。
もしくは CURRENT_TIMESTAMP に置き換えてみるとか。

123 :120:05/01/28 18:09:20 ID:???
すいません。列名のあとに型名いれてなかったとですorz

124 :NAME IS NULL:05/01/28 18:46:45 ID:???
>>113
仕様か不具合かわかりませんがLinux版10gでもORA-1791だっけ?になりますね。
副問い合わせでdistinctとorder byを分けてしまいましょう。

SELECT TO_CHAR(rownum, '00') || ':' || AAA
FROM
(SELECT DISTINCT
AAA FROM ZZZ
WHERE BBB = '2')
ORDER BY AAA

125 :NAME IS NULL:05/01/30 04:36:50 ID:fBh0ligt
postgresql7.3でやっております。

たとえば以下のようなデータがありまして

id | date       |
01|2005-01-25 00:00:00|
02|2005-01-23 00:12:00|
03|2005-01-23 00:10:00|
04|2005-01-23 00:00:00|
05|2005-01-22 00:01:00|
06|2005-01-22 00:00:00|
07|2005-01-21 00:00:00|

というデータがあるとしまして、日付によっては複数のデータが
入っている場合もあります。

「データのない日を除いた最新の3日分のデータを抽出したい」場合は、
どのようにselect文を書けばいいのでしょうか?
このデータの例の場合は「25日」「23日」「22日」の、idが「01」から「06」を
すべて抽出したいです。

分かる方がいましたら、ご教授のほど、よろしくお願いいたします。

126 :NAME IS NULL:05/01/30 10:24:24 ID:???
俺はめんどくさいことしたくないので先に三日分の日付を抜き出す。

127 :NAME IS NULL:05/01/30 10:31:20 ID:???
>>125
SELECT * FROM Table WHERE
DATE_TRUNC('day',date) IN (SELECT DISTINCT DATE_TRUNC('day' ,date)AS dt FROM Table ORDER BY dt DESC LIMIT 3);
サブクエリにLIMITを使っているあたりがインチキくせー。

>>126にかぶったな。

128 :125:05/01/30 13:27:53 ID:???
>>126,127

解決しました。
date_trunc()なんていう関数があったんですね。
丁寧に教えてだき、ありがとうございました。

129 :NAME IS NULL:05/01/30 20:23:33 ID:vtcQy9L2
すいません、mysql4なのですが、
ある1行(where user= 'hoge'でslectできる)と全く同じ内容で user= 'hage'でinsertにするにはどうすればいいでしょうか

130 :NAME IS NULL:05/01/30 23:05:21 ID:???
それじゃ、「全く同じ内容」では無いのでは?

131 :NAME IS NULL:05/01/30 23:57:14 ID:???
>>129
何をしたいかよくわからないが、ひょっとして、

INSERT INTO Table1 SELECT * FROM Table2 WHERE user='hoge';
ってことなんだろうか?

132 :NAME IS NULL:05/01/31 00:02:47 ID:??? ?
複雑怪奇なSQLを見たいのですが、どこに行けば見れますか?

133 :NAME IS NULL:05/01/31 03:55:57 ID:J/9Z5Xf2
>>132
開発現場


134 :NAME IS NULL:05/01/31 15:28:31 ID:???
MySQL4.0です。

tasksというテーブルのtask_insert_timestamp列のデフォルト値を、
>alter table tasks alter task_insert_timestamp set default 'now';
と変更しようとしたところ

>Query OK, 579 rows affected (0.11 sec)
>Records: 579 Duplicates: 0 Warnings: 0
と出て、

>desc tasks;

>+-----------------------+----------------+------+-----+----------------+----------------+
>| Field         | Type      | Null | Key | Default    | Extra     |
>+-----------------------+----------------+------+-----+----------------+----------------+
>| task_id        | int(11)    |   | PRI | NULL      | auto_increment |
>| task_insert_timestamp | timestamp(14) | YES |   | 00000000000000 |        |
>+-----------------------+----------------+------+-----+----------------+----------------+

のように、デフォルトの値が変わらないのですが、
どこがまちがっているのでしょうか?

135 :NAME IS NULL:05/01/31 15:45:52 ID:???
・デフォルト値は定数でなければならない

136 :NAME IS NULL:05/01/31 15:54:32 ID:???
SQL Server 2000 です。

TBL_A.CODE と TBL_B.CODE を LEFT OUTER JOIN しています。

この時 TBL_A に存在するコードで TBL_B.CODE は <NULL> と表示されています。
この TBL_B.CODE が NULL の場合は FALSE を、NULL でない場合(値がある場合)
は TRUE を返す SQL 文を作成しようとして、

SELECT TBL_A.CODE, TBL_B.CODE
CASE TBL_B.CODE
WHEN NULL THEN 'FALSE'
ELSE 'TRUE'
FROM TBL_A LEFT OUTER JOIN TBL_B.CODE ON TBL_A.CODE = TBL_B.CODE

と書きましたが、CASE の結果が必ず TRUE でかえってきます。
何がいけないのでしょうか? アドバイスお願いします。


137 :NAME IS NULL:05/01/31 15:58:25 ID:???
>>136
NULLはイコール比較できないというのは基本ですよ。
CASE文はイコール比較でしょ。

なので、SQLServerは詳しくないんだが、IsNullか何かでチェックじゃないのか?

138 :NAME IS NULL:05/01/31 16:01:47 ID:???
>>136
value = NULLだとNULLかどうかを判定できないのと同じことかと。
value IS NULLでなければダメ。isnull関数を使ってもいいかも。

139 :NAME IS NULL:05/01/31 16:02:42 ID:???
被っちまった。スマン。

140 :136:05/01/31 16:08:35 ID:???
ありがとうございます。

そういう事でしたか…。

ならば、という事で、

CASE (TBL_B.CODE IS NULL)
WHEN ...

と書いてみましたが、これでも駄目でした orz.

isnull 関数を勉強してみます。



141 :NAME IS NULL:05/01/31 16:15:42 ID:???
>>140
CASEの別の構文で

CASE
WHEN TBL.CODE IS NULL THEN 'FALSE'
ELSE ’TRUE'

でいけると思う。SQL鯖で可能かどうかは知らんが。

142 :NAME IS NULL:05/02/01 14:36:13 ID:???
マルチすみません。

ORACLE8にてトリガーステートメント中に、トリガー発動の契機となったSQLを発行した
プログラムの名前と、そのSQL文を取得したいのですが、 どのように記述すればよいのでしょうか?
宜しくお願いします。




143 :NAME IS NULL:05/02/06 10:35:46 ID:cvTuVKEo
postgres7.4.6なんですが、
データベースdice、テーブル名、favorite、列、update_timestamp
に対して、
updateをかけるとき、
特に「update_timestamp」に指定がなければ、つまりデフォルト値を、
updateしたときの日時にしたいのですが、どうかけばいいのでしょうか?

以下のようにやったら、default 値に、create tableした日時がdefault値に
なってしまいました。

どうぞどなたか、よろしくお願いします。

create table favorite(
favorite_id serial PRIMARY KEY not null,
url varchar(200) not null,
title varchar(200) not null,
memo text,
insert_timestamp timestamp with time zone not null default 'now()',
update_timestamp timestamp with time zone not null default 'now()',
delete_timestamp timestamp with time zone
);

144 :NAME IS NULL:05/02/06 10:46:14 ID:???


>>143

insert_timestamp timestamp
 with time zone not null default CUREENT_TIMESTAMP
でいるとおもわれ

145 :143:05/02/06 11:32:12 ID:???
>>144
どもです。

でも、
ERROR: column "cureent_timestamp" does not exist
と言われてしまいました。なんでだろう。。。

ちと自分でも調べてみますが、
おわかりでしたら教えていただければ幸いです

146 :NAME IS NULL:05/02/06 12:24:40 ID:???
スマソ

CURRENT_TIMESTAMPでした。
http://www.postgresql.jp/document/pg801doc/html/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT

恥ずかしい...

147 :143:05/02/06 13:21:30 ID:???
>>146
いえいえ、ありがとうございます。
無事いきました!

どうもです

148 :NAME IS NULL:05/02/07 19:53:35 ID:lCd+U9DO
ロックについてお知恵を拝借できませんでしょうか。
(環境は oracle9iR2 です)

create table t (
id number primary key,
category number not null
);
というテーブルがあって、
複数のプロセスが非同期に行を insert していくんですが、
category 毎に、行数が n の倍数になったことを
検地したいと思っています。

select *
from t
where category = 値
for update;
という形でロックして
insert して
select count(*) ...
すればいいのかと思ったんですが、
該当する行が1つもない場合には
ロックがかからないようでした。

お助けを。


149 :NAME IS NULL:05/02/07 20:34:03 ID:???
SQLによるアクセス手順ってどうゆうこと
なんでしょうか?

150 :NAME IS NULL:05/02/07 23:12:36 ID:nzLj4lY6
本を見ても簡単な例しかなく、SELECT文の原理が良く分かりません。SELECT文を勉強するための良いソースがあったら、教えてちょ。

151 :NAME IS NULL:05/02/08 19:13:58 ID:???
>>148
insertに対して
for updateしてもダメです。(だってfor updateなんだもん)
明示的にテーブルをlockしましょう。
どのモードが良いかはよくわからん。

152 :NAME IS NULL:05/02/09 19:39:51 ID:???
postgres7です、freebsd5.2です。

で、質問なのですが、
シーケンスpublic.favorite_favorite_id_seq のlast_valueが、
いつのまにか、本来の値より小さくなってしまいます。

これを正常にするにはどうすればいいのでしょう?

(updateかけてもだめだったです)

以上、よろしくお願いいたします。

153 :152:05/02/09 19:51:24 ID:???
ちなみにそのときのsql文は
update sequence favorite_group_favorite_group_id_seq(last_value) values(16);
です

154 :NAME IS NULL:05/02/09 20:15:16 ID:???
>>153
SELECT setval('favorite_group_favorite_group_id_seq', 16);

155 :152:05/02/09 21:23:47 ID:???
>>154さん
おお、ありがとうございます。

156 :148:05/02/10 03:51:56 ID:???
>151
やっぱりそうなんだ、ありがトン。

せめてcategory毎に並列作業がしたいので
苦肉の策として
create table l (
category number primary key
);
ってのを作って
こっちに対して
select category from l for update;
をするようにしてみようと思います。


157 :NAME IS NULL:05/02/10 15:46:14 ID:45NFvvXi
UPDATEでの質問です。

Aテーブル
Key
数値A
数値B
文字A

というテーブルがもともとあり、

Bテーブル
Key
数値A
数値B

というテーブルが追加されました。

このとき、BテーブルのKeyとAテーブルのKeyが一致するレコードの
B.数値A→A.数値A
へ更新したいのです。

UPDATE B JOIN A ON B.Key = A.Key
SET A.数値A = B.数値A

とやっているのですが、うまく逝きません
ご教授願えませんでしょうか?

158 :NAME IS NULL:05/02/10 16:37:22 ID:???
・DBは何か
・うまく逝かないとは何か

159 :NAME IS NULL:05/02/10 17:12:11 ID:???
>>158
DB:Oracle
うまく逝かない:SETがありませんとかなんとか

160 :NAME IS NULL:05/02/10 19:17:21 ID:???
普通に数件のデータを拾うSELECT文で、
WHEREを使わずに一件目のデータのみを抽出する方法はありませんでしょうか?

161 :NAME IS NULL:05/02/10 19:27:22 ID:???
>>160
で、数件の中のどれが一件目なのさ

162 :NAME IS NULL:05/02/10 19:45:21 ID:???
ORDER等をかけずに、
SELECT * FROM TABLE
等と書いた時に出てくる一件目です。
データが入力された順になるのかな?

163 :NAME IS NULL:05/02/10 19:51:54 ID:???
>>157
ACCESSのクエリをそのままOracleに持っていこうとしている感じですな

164 :NAME IS NULL:05/02/10 20:32:50 ID:???
>>162
入力順とかは保証されません。whereを使わないとで一件だけというのは無理。
取り出された行を他の言語で処理する必要があるでしょう。

165 :NAME IS NULL:05/02/10 20:50:02 ID:???
>164
うーん、そうですか・・・どうもです。
では、ORDER BY等をかけて、その一番最初の項目とかでも駄目でしょうか?

166 :NAME IS NULL:05/02/10 21:01:41 ID:???
>>165
ORDER BYで順番を決めたとしてもその一番目の一件だけというのは
where句や他の言語で処理して限定する必要があると思います。

167 :NAME IS NULL:05/02/10 21:08:13 ID:???
DBによってはTOPだのLIMITだのの指定でいけるだしょ。

168 :NAME IS NULL:05/02/10 22:01:01 ID:???
汎用ならカーソルか?

169 :NAME IS NULL:05/02/11 01:32:10 ID:???
>>157
UPDATE A SET A.数値A =
  (SELECT B.数値A FROM B WHERE B.Key = A.Key)
じゃなかったっけ

170 :NAME IS NULL:05/02/11 16:52:02 ID:???
UPDATE A SET A.数値A = B.数値A
FROM A JOIN B ON B.Key = A.Key
って書けるDBMSもあるよ

171 :NAME IS NULL:05/02/13 05:43:25 ID:Qt77sidg
A,B,C,Dという列があります。
Bの種類毎に最大のAの行を全て持ってくるSQLは、
どう書きましょう?

172 :NAME IS NULL:05/02/13 08:09:28 ID:???
>>171
SELECT * FROM Table WHERE (A,B) IN (SELECT max(A),B FROM Table GROUP BY B);

173 :NAME IS NULL:05/02/13 12:46:37 ID:NndmN5hG
>>171
select * from Table T where not exists ( select * from Table where B=T.B and A>T.A )

うまく最適化できない場合も多いのでIN(サブクエリ)は使わないのがふつー。

174 :NAME IS NULL:05/02/14 10:11:44 ID:???
2つの結合したテーブルを
insert文で挿入したいのだが
文がなんか上手くいかねぇ


教えて、エロイ使徒!

175 :T.O:05/02/14 18:20:50 ID:RwPSRDsG
はじめまして。駆け出しプログラマです。
ご教授頂けたら、幸いです。

特定の時間から時間まで検索するSQLってどう書けば良いのでしょうか?
(例:2005/02/14 12:00〜2005/02/15 12:00まで)

日付の範囲指定だけなら分かるのですが、時間の指定が分かりません。
(日付指定:select * from emp where hiredate >= '2005/02/14' and hiredate <= '2005/02/15')

仕事で日付関連のSQLを使う機会が多いので、投稿しました。(ご返信は少し遅れるかもしれません)

−−−−−−−−−−−−−−−−−−−−−−−−−−−−
SQL> desc emp
  名前 NULL? 型
----------------------------------------------------------------
  EMPNO NOT NULL NUMBER(4)
  ENAME   VARCHAR2(10)
  JOB   VARCHAR2(9)
  MGR   NUMBER(4)
  HIREDATE   DATE
  SAL   NUMBER(7,2)
  COMM   NUMBER(7,2)
  DEPTNO   NUMBER(2)

−−−−−−−−−−−−−−−−−−−−−−−−−−−−

176 :T.O:05/02/14 18:21:52 ID:RwPSRDsG
DB板の書き込みから移動しました。

177 :NAME IS NULL:05/02/14 18:22:30 ID:???
ネタでも釣りでもなく真面目な質問です。

DBソフトはFMしか使ったことないサルですが、
SQLとは一体何なんですか?
言語の一つですか?
MySQLやSQLServer、Oracleとかいろいろありますが、
これらの違いって何ですか?

簡単に教えてください。

178 :ふふだ:05/02/14 20:47:51 ID:OXsxBjgz
同じ値のレコードだけをSELECTするクエリというのはありますか?
DISTINCT の逆のような。
たとえば、 
| x | y | id |
----------------------------------
| 9 | 3 | 1 |
----------------------------------
| 10 | 2 | 2 |
----------------------------------
| 11 | 1 | 3 |
----------------------------------
| 12 | 5 | 4 |
----------------------------------
| 14 | 5 | 5 |
----------------------------------
| 15 | 3 | 6 |
----------------------------------
| 15 | 4 | 7 |
----------------------------------
から、
----------------------------------
| 12 | 5 | 4 |
----------------------------------
| 14 | 5 | 5 |
----------------------------------
| 15 | 3 | 6 |
----------------------------------
| 15 | 4 | 7 |
----------------------------------
を抽出することです。

179 :NAME IS NULL:05/02/14 21:08:54 ID:???
>>175
oracleだったらto_date関数で日付の書式を指定するといいと思います。
to_date('2005/02/14 12:00', 'YYYY/MM/DD HH24:MI')
こんな感じ?

180 :T.O:05/02/14 21:48:29 ID:AQy8vXib
>>179
おお!!回答頂いて有難うございます。感動です。では、
select * from emp where hiredate >= to_date('2005/02/14 12:00', 'YYYY/MM/DD HH24:MI') and hiredate <= to_date('2005/02/15 12:00', 'YYYY/MM/DD HH24:MI')

とすれば、良いのですかね?両方DATE型ですし。
(理由あって今すぐテストは出来ないのですが・・・)。

とはいえ、教えて頂いた事で、これからのSQLプログラミングで少し楽が出来そうです。
他にも調べていて、両方char型にして、数字での比較を行う手法もあるかなと思いました。
有難う御座いました。


181 :NAME IS NULL:05/02/14 21:56:05 ID:???
>>180
範囲指定するならbetweenを使う方が一般的かも。
select * from emp
where hiredate between to_date('2005/02/14 12:00', 'YYYY/MM/DD HH24:MI')
and to_date('2005/02/15 12:00', 'YYYY/MM/DD HH24:MI')


182 :T.O:05/02/14 22:03:09 ID:AQy8vXib
>>181
補足してくださって有難うございます。
なるほど〜。こちらの方が綺麗ですね。

大変参考になります。有難う御座います。
(P.S 当たり前だけど、
日付関連のSQLは日付('2005/02/14 12:00')そのもので
google検索しても引っ掛かりませんでした・・・。
こういった、一般的な用法を覚えるのは、
経験とOracleMasterの教本なのかなぁ・・・。
私の持っていた教本には載っていないし。)


183 :NAME IS NULL:05/02/14 22:36:53 ID:???
>>178
これを他のフィールドの分も書いてunionでくっつけてみたらどう?
select * from table
where x in (select x from table group by x having count(*) > 1)

184 :NAME IS NULL:05/02/14 22:52:24 ID:???
>>177
>SQLとは一体何なんですか? 
SQL:Structured Query Language
IBM社が開発したデータベース操作用言語。
リレーショナルデータベースの操作に使用する。
アメリカ規格協会(ANSI)やJISで標準化されている世界標準規格
の言語です。
ttp://e-words.jp/w/SQL.html

>MySQLやSQLServer、Oracleとかいろいろありますが、 
SQL自体は規格化されているけれども、製品として特色を出すために、微妙に色付けをして
いるので、たとえば
MySQL:ライセンス価格が安価(商用でない限りフリー)
SQLServer:Oracleに匹敵する高機能高信頼性でありながら、扱いやすいインターフェースを持つ
Oracle:信頼性では右に出るものがない(とは言い切れないかも・・・)
などの違いがあります。
データを取り出すSQL文は規格内ではほとんど同じですが、製品によっては独自の関数や構文を
もっていて、よりユーザーの要望に答えやすくしたものがあります。

FMは開発環境を含んだ統合的なものなので、エンドユーザー向けのUIを持たず、純粋にDB設計と保守のみを目的と
した上記のような製品を扱おうとすると、最初はどこから手をつけたらよいかわからないと思いますが、
MySQLあたりをダウンロードしてみて、書籍とにらめっこしながらやってみてはどうでしょう。

185 :NAME IS NULL:05/02/15 00:52:52 ID:+sDpnfE+
こんにちわ。
どなたか教えてください。
MYSQLなのですがautoincrementする主キーがあり、
そのキーが次にいくつの値を挿入するか知るにはどうすればいいでしょう?
たとえばいま20までカウントがすすんで全部、消去します。
すると次は21からなのですが、この値はどのように取得すればいいでしょうか?

186 :NAME IS NULL:05/02/15 00:58:32 ID:???
>>178
(9,3,1)は抽出しなくてもいいの?

もし含めるなら、
select * from テーブル T
where exists ( select * from テーブル where x = T.x )
or exists ( select * from テーブル where y = T.y )


187 :NAME IS NULL:05/02/15 01:05:31 ID:???
>>185
まずinsertしろ。
話はそれからだ。

188 :NAME IS NULL:05/02/15 03:35:56 ID:+sDpnfE+
185です。
>> 187
それはわかるのだが、たとえばリレーションしていたとして、
次の挿入IDをinsert前に知りたいのですよ。


189 :NAME IS NULL:05/02/15 09:01:34 ID:???
リレーションだろうがなんだろうがinsert後にわかれば十分だろ。

190 :177:05/02/15 18:01:26 ID:???
>>184

回答ありがとうございます。
ある程度SQLについて理解ができました。

重ねて質問で申し訳ないのですが、
世の中にはいろいろな言語があると思うのですが、
SQLを選択する価値等をご教授いただけますでしょうか。

よろしくお願いいたします。

191 :NAME IS NULL:05/02/15 18:09:33 ID:???
>>190
価値っていうか、SQLを使いたくてDBを使うやつはあまりいないと思う。
ふつうはDBを使うためにSQLが必要になるのでは。

192 :NAME IS NULL:05/02/15 18:44:15 ID:???
>>190
>191に同意。SQLは目的じゃなくて手段だということ。

それをふまえてあえて言うならば、現在データを設計、抽出、管理する方法が
SQLが最も普及していること、情報量/サンプルが多いこと(=不明点の解決、トラブルシューティング
が比較的容易なこと)、SQLの基礎を押さえておけば、ある製品から別の製品に移ったときに
応用が利くことがあると思います。
たとえばSQLを一切扱えないRDBMSを扱っている場合、その製品をしきりに持ち上げている人がいるけれども、
結局情報量が足りなかったり、他のRDBMSを扱う段階になったときにスキルがほとんど役に立たずに結局苦労しています。

だけど、MySQL、Oracle、MSSQLなどを扱ったときには、基礎的なSQL文に加え、その製品独自の
機能を覚えなければならないし(これは負担はそう大きくないと思う)、それとは別にクライアントのUI
(Java, HTML, VB, C#, Delphiなど)を構成するための言語を別に覚えなければならないということもある。
FMだけで完結しないから。
これはこれでとても楽しいけどね。



193 :NAME IS NULL:05/02/15 18:46:50 ID:???
>>190
頭でっかちにならずに、適当な環境を作って試せば?
SQL以外のデータ操作ってオブジェクトマッピングとか、昔ならカード型DBとかの操作かな?
そういう選択肢を調べて自分でメリット感じないと、他人に聞いても理解できないよ。

194 :Oracleの質問です:05/02/15 21:58:38 ID:fRJPeq19
いつもお世話になっております。
当方かなりの初心者です。
質問なのですが、
SQLPLUSにて、テーブル定義の表示はDESCコマンドにて行いますが、
カラムのDefaultは表示されません。
すでに定義済みのDefault値を出力するにはどのようにしたら
よいのでしょうか?
宜しくお願いします。


195 :NAME IS NULL:05/02/15 22:11:34 ID:???
a


196 :NAME IS NULL:05/02/16 09:52:18 ID:???
>>194
USER_xxx テーブルか ALL_xxx テーブルにあるんじゃないの?
マニュアル参照。


197 :NAME IS NULL:05/02/16 12:05:59 ID:XuM2Opcf
今朝しらべたらUSER_TABLE_COLUMNSにありました。回答ありがとうございました。

198 :NAME IS NULL:05/02/16 17:48:53 ID:/Ox5p2pE
DB=ORACLE10g で次のようなこと出来ますか?
会社名1,会社名2,会社名3,売上げ のフィールドがあるとき、

同じ会社名の売上合計を出す。
会社名1,2,3には、全てに値が入っている場合も有れば、どれかにだけしか値が入っていない場合も有る。

よろしくお願いします。




199 :NAME IS NULL:05/02/16 18:08:24 ID:???
>>198
アイデアだけ、あってるかは知らん。

SELECT 会社、SUM(売り上げ)
FROM

SELECT 会社1、売り上げ FROM テーブル
UNION
SELECT 会社2、売り上げ FROM テーブル
UNION
SELECT 会社3、売り上げ FROM テーブル


重複の省き方は考えてください。


200 :NAME IS NULL:05/02/16 18:17:32 ID:XuM2Opcf
OTZ

201 :NAME IS NULL:05/02/16 18:20:29 ID:???
  ○|\
 ○| ̄ヒ|_

202 :NAME IS NULL:05/02/16 18:45:37 ID:/Ox5p2pE
>>199 有難うございました。 何とかできそうです。
SELECT 会社1 AS 会社, の様に指定するんですよね。

203 :NAME IS NULL:05/02/17 15:22:56 ID:???
>>192
ある意味それは正しいと思うが、SQLってどうも設計がぼろい
ような気がして好きになれない... DBMS使いたいからしょうが
なく使ってるけどもっとましなの作ってって感じだな。


204 :NAME IS NULL:05/02/17 16:31:56 ID:???
>>203
まあしかし、ある程度の規模とか信頼性を求められるとAccessやFM, 4Dなどを使うわけには行かない
こともまた事実なんだよな。


205 :NAME IS NULL:05/02/17 20:17:30 ID:/WFLyCYA
大量のデータのなかから一定期間ごとにサンプリングしたいのですが、
SQLだけでできるものでしょうか。

たとえば以下のようなデータから 1 時間ごとに抜き出したい (10, 30, 40が欲しい)
のです。

2005/2/17 00:00, 10
2005/2/17 00:30, 20
2005/2/17 01:00, 30
2005/2/17 01:30, 20
2005/2/17 02:00, 40


206 :NAME IS NULL:05/02/17 20:31:15 ID:???
そのパターンなら、分の部分が0のもんだけ取り出せばいいじゃん

207 :NAME IS NULL:05/02/17 21:38:51 ID:/WFLyCYA
>>206
すいません例が悪かったです。
このパターンならそうなんですけど実際には時間はバラバラなんです。

208 :NAME IS NULL:05/02/17 21:54:20 ID:???
んじゃあ、その場合の「一時間ごと」の定義は何なのよ。

209 :NAME IS NULL:05/02/17 22:16:25 ID:???
あるカラムの値を、おのおの同じレコードの別のカラムにコピーしたい、
つまり

a | b
---+----
1 |
2 |
3 |

となっているのを、

a | b
---+----
1 | 1
2 | 2
3 | 3

としたいのですが、a の定義が int, b の定義が varchar になっています。
このような場合、何かうまい方法はありませんでしょうか?

実は、b の値は a と必ずしも同一にする必要はなく、b の中で一意で
あれば OK (例えば重複しないランダム文字列)と言う状態ですので、
そちらの方法でも構いません。

質問の仕方等、まずかったらご指摘下されば幸いです。

210 :NAME IS NULL:05/02/17 22:36:52 ID:???
型変換してSETすればいいじゃん

211 :NAME IS NULL:05/02/17 23:02:00 ID:???
>>210
ありがとうございます。型変換…の記述方法が分からないでいます_| ̄|○<スミマセン
SQL Server だと CONVERT(type, value) と言うそのままのものがあったのですが...

UPDATE table AS foo SET b = 型変換(varchar, foo.a) のような感じなのでしょうか。

UPDATE table AS foo SET b = foo.a ですと型に互換性が無いと言って怒られました。
使っている DB は DB2 Lite です。

212 :NAME IS NULL:05/02/18 00:03:26 ID:MOXel1Bc
UPDATE table SET b = CAST(a as varchar(10))
みたいには書けんのかな?

213 :205:05/02/18 00:25:13 ID:???
>>208
たびたびすいません。
xx:00〜xx:59 までをひとつの単位として、その区間の中で一番小さいもの
を抜きだす必要があります。以下の例だと 10, 50, 60 です。。

2005/2/17 00:00, 10
2005/2/17 00:30, 30
2005/2/17 00:59, 40
2005/2/17 01:59, 50
2005/2/17 02:00, 60



214 :NAME IS NULL:05/02/18 00:29:05 ID:???
「時」までの部分でグループ化し、各グループで分が最小の物を

215 :205:05/02/18 00:37:35 ID:???
>>214
なるほど。そうやればいいのですね。









ってSQLぜんぜん分からないっす・・・orz
勉強してきます。

216 :NAME IS NULL:05/02/18 09:26:41 ID:???
SQL以前にロジックの部分で、商と余りを上手く使って考えれば?
それをあとはSQLにするだけ。


217 :NAME IS NULL:05/02/18 11:13:14 ID:???
VARCHARで入っている各値の末尾に文字を付け加えたいのですが、
値を取って、付け加えて、格納すると言ったことは可能でしょうか?
>>209をパクらせてもらうと

a | b
----+------
1 | foo
2 | bar



a | b
----+------
1 | foo$
2 | bar$

と言った感じなのですが...


218 :NAME IS NULL:05/02/18 11:18:21 ID:???
可能。

219 :NAME IS NULL:05/02/18 12:02:43 ID:???
UPDATE テーブル
SET B = B || '$'

220 :209:05/02/18 16:17:22 ID:???
>>212
ありがとうございます。CAST は認識してくれましたが、
BIGINT->VARCHAR のキャストをサポートしない、となりました...
ここからは DBMS に依るってことなんですかね。

221 :209:05/02/18 16:24:45 ID:???
ランダム文字列が入れば良かったので取り敢えずDB2の機能を使って
これで回避しました...
UPDATE table SET b = (generate_unique() as varchar(10))
ありがとうございました。

222 :209:05/02/18 16:26:44 ID:???
失礼。
UPDATE table SET b = CAST(generate_unique() as varchar(10))
でした。蛇足ですが…

223 :NAME IS NULL:05/02/20 08:13:18 ID:AMw9tC3J
SQL Server 2000です。次のようなテーブルがあります。

KEY1(PK&FK), KEY2(PK), KEY3(PK), DATA

で、KEY1ごとに最後のレコード(KEY2 desc, KEY3 descでソートした最初のレコード)を抽出したいのですが、
やはりストアドしかないのでしょうか?

select A.KEY1, B.KEY2, B.KEY3
from MASTER A(FK元),
( select TOP 1 KEY2, KEY3 from TABLE
where TABLE.KEY1 = A.KEY1
order by KEY2 desc, KEY3 desc) B

……なんて風に書けたらいいなぁ、とか思っていたのですが、甘かったようですorz



224 :NAME IS NULL:05/02/20 08:45:44 ID:???
>223
普通にグループ化してやればいいんじゃないのか?

SELECT KEY1,MAX(KEY2),MAX(KEY3)
FROM TABLE
GROUP BY KEY1

225 :NAME IS NULL:05/02/20 08:56:07 ID:???
あ、KEY2とKEY3はそれぞれじゃなくて、纏めた形にしないと駄目なのかな?
だったらこうか。

SELECT KEY1,KEY2,KEY3
FROM TABLE
WHERE (KEY1,KEY2 || KEY3) IN
(
SELECT KEY1,MAX(KEY2 || KEY3)
FROM TABEL
GROUP BY KEY1
)

226 :223:05/02/20 09:37:35 ID:AMw9tC3J
……ごめんなさい、「||」って文法、SQL Serverじゃ通らないみたいです(T_T)

>あ、KEY2とKEY3はそれぞれじゃなくて、纏めた形にしないと駄目なのかな?
はそのとおりです。

KEY1|KEY2|KEY3
----+----+----
1| 1| 1
----+----+----
1| 2| 3
----+----+----
2| 1| 2

ってデータがあったら

1,2,3
2,1,2

ってレコードを返したいんです


227 :223:05/02/20 09:38:48 ID:???
あう、ずれてる(T_T)>表
あとageてしまってごめんなさい


228 :NAME IS NULL:05/02/20 10:09:37 ID:???
うーん、「||」は単に文字列を結合してるだけだから、それに対応する文法を使えばいけると思います。「&」とかになるのかな?
えーっと、確認すると、
1,1,3
1,2,1
っていうデータがあったら、
1,2,1
を返したいって事ですよね?

229 :223:05/02/20 10:29:06 ID:???
>>228
ですです。

なるほど、文字列連結ですね。もし&でもだめだったら関数探してみます

230 :223:05/02/20 11:07:13 ID:???
>>229

イケました。inで複数指定が出来ないのとNullだった場合も考慮して

SELECT A.KEY1,A.KEY2,A.KEY3
FROM TABLE A
WHERE (isNull(KEY2, '') + isNull(KEY3, '')) IN
(SELECT isNull(KEY2, '') + isNull(KEY3, ''))
FROM TABEL
WHERE KEY1=A.KEY1
GROUP BY KEY1)

で、どうやらOKのようです。これからテストデータを作って検証してみます。
ありがとうございました

231 :NAME IS NULL:05/02/20 15:29:34 ID:???
>>230

最大の(KEY2,KEY3)を持ってくる条件が抜けてるが良いのか?
念のためだけど、>>225のmax(key2||key3)というのは使わんほうが良い。
もしkey2が可変長文字列や整数値だった場合、間違ったレコードを
取得する可能性がある。

(A,AA)
(B,AA)
(B,DB) <- 誤
(BC,BA)
(BD,AC) <- 正

その他にも、文字列連結を使った場合は通常indexが使われないなど
問題があるので、初心者はあまりtrickyな方法を使わず正攻法を
覚えるべき。

select A.key1, A.key2, A.key3
from テーブル A
where not exists (
select * from テーブル
where key1 = A.key1
and (
( key2 > A.key2 )
or ( key2 = A.key2 and key3 > A.key3 )
)
)



232 :223:05/02/20 16:25:21 ID:???
>>230
existsキーワードですか。まだまだ学ぶべきことは多そうですね。
えと

existsキーワード:サブクエリの条件を満たすレコードがあったらtrue、なければfalse

で、「現在の行のKEY1と等しく、かつKEY2が大きいかまたはKEY2が等しくKEY3が大きい」という条件を満たすレコードが存在したらtrueになって、
先に「not」がついてるから反転してfalse、つまりKEY1の中で一番大きいKEY2+KEY3をもつレコードが抽出されるわけですね。

なるほど、ありがとうございました。非常に参考になりました。

233 :NAME IS NULL:05/02/23 21:06:19 ID:vKYM6XDJ
SQL Loaderを使ってデータを取り込みたいのですが、
データ内にスペースがあった場合に0に置き換えたいです。
どのように制御文を記述するといいでしょうか。
TRANSLATEとか記述してみたのですが上手くLoaderが動いてくれませんでした。
どうかご教授ください。

234 :233 :05/02/23 22:07:08 ID:vKYM6XDJ
自己解決した〜。

カラム名 "編集文"

でした。
ダブルコーテーションがいるのか…。

235 :NAME IS NULL:05/02/24 10:41:51 ID:???
すべてのテーブルにdelete from tabale_nameかtruncate table table_nameを
かけたいのですが構文としてはどうなりますか?
ちなみにDBはSybase11です。
よろしくお願いします

236 :NAME IS NULL:05/02/24 14:03:31 ID:???
素朴な疑問なのですが、convert関数の数値→日付値の変換って、例えば
convert(datetime,36357)だと1999-07-18になりますよね。
これって、内部ではどのような計算が行われてるのでしょうか?
ご教授お願いいたします。


237 :NAME IS NULL:05/02/24 14:28:35 ID:???
1900/01/01を基点とした日数じゃねーのか?

238 :NAME IS NULL:05/02/24 14:33:01 ID:x9bV7eQL
質問させていただきます。
例えば下の様な2つのテーブルから、SELECT 文で
「『ある食堂(単・複)のうまいメニューが属するジャンル』が好物な人物」
を検索するにはどうすればいいでしょうか?

●「好物」テーブル
+------+----------+
| 人物 | ジャンル |
+------+----------+
| 太郎 | ごはん類 |
| 次郎 | ごはん類 |
| 三郎 | めんるい |
| 四郎 | めんるい |
| 五郎 | どんぶり |
+------+----------+

●「食堂」テーブル
+----------+----------+--------+--------+--------+
| ジャンル | メニュー | A食堂 | B食堂 | C食堂 |
+----------+----------+--------+--------+--------+
| ごはん類 | 玉子ご飯 | マズイ | マズイ | マズイ |
| ごはん類 | お茶づけ | マズイ | マズイ | うまい |
| ごはん類 | おむすび | マズイ | マズイ | うまい |
| めんるい | ラーメン | うまい | マズイ | マズイ |
| めんるい | タンメン | うまい | マズイ | マズイ |
| めんるい | ソーメン | うまい | マズイ | うまい |
| どんぶり | カツどん | マズイ | マズイ | マズイ |
| どんぶり | テンどん | マズイ | うまい | マズイ |
| どんぶり | 親子どん | マズイ | マズイ | マズイ |
+----------+----------+--------+--------+--------+

例えば「A食堂またはB食堂でうまいメニューが属するジャンル(めんるい&どんぶり)」が好きな人物
を検索して

+------+
| 人物 |
+------+
| 三郎 |
| 四郎 |
| 五郎 |
+------+

という結果を得たいのです。
MySQL のバージョンは 4.0.23 です。
分かりにくくて申し訳ありませんが、よろしくお願いします。

239 :NAME IS NULL:05/02/24 14:37:47 ID:???
おぉーほんとだ!datediffで計算したら仰る通りの結果が出ました。
お陰様でスッキリしました。ありがとうございました。

240 :NAME IS NULL:05/02/24 15:20:49 ID:???
>>238
select distinct 人物 from 好物,食堂
where
好物.ジャンル=食堂.ジャンル
and
(A食堂='うまい' or B食堂='うまい')


241 :NAME IS NULL:05/02/24 15:43:11 ID:???
階層構造をDBに持たせたい時はどういう風にテーブルデザインすればいいですか?
例えばカテゴリ、サブカテゴリ、サブサブカテゴリとかがある場合とか。

242 :238:05/02/24 15:43:19 ID:x9bV7eQL
>>240
上手くいきました!
ありがとうございます!!!

243 :NAME IS NULL:05/02/24 15:50:42 ID:???
>>241
カテゴリマスタ コード、名称・・・
カテゴリ階層 親コード、子コード

問合せは階層問合せを使用するなり、プログラム側から再帰でおこなうなり。

244 :NAME IS NULL:05/02/25 00:49:53 ID:i3qYxhAS
すみません、PostgreSQLのSQL構文についての質問なのですが・・・

値と日付フィールドを持った数100件程度のレコードがあるとして、
日付の新しいものから100件だけを残して他を全て削除したいのです。

DELETE文でこのような指定は可能なのでしょうか?

試しに、

 DELETE FROM hoge_table ORDER BY date DESC OFFSET 100;

・・・とかやってみたのですがダメでした。

245 :NAME IS NULL:05/02/25 02:15:43 ID:???
delete from hoge_table where pKey not in (select pKey from hoge_table order by date desc limit 100);

delete from hoge_table where not exist (select pKey from hoge_table order by date desc limit 100);
じゃだめか?
試したことないけど

246 :NAME IS NULL:05/02/25 07:12:52 ID:???
>>245
試したことないけどそれは違うだろ。
それだと全デリのオカーソ。

247 :NAME IS NULL:05/02/25 10:43:30 ID:???
素直にデータ連番もって削除か、一端情報を取ってから削除じゃだめなんか?
または単純に一定期間保持にするとか。
件数で削除となると、1SQLで無理にやるぐらいなら一回削除点を取ったほうがいいと思うが。

248 :246:05/02/25 11:17:48 ID:???
スマソ。脊髄反射してますた。
>>245の上はOKっぽい。下はダメだろうけど。
試して無いがなぁー。


249 :244:05/02/25 11:28:08 ID:???
レスありがとうございます。
>245さんの上のやり方を実験してみます。

250 :NAME IS NULL:05/02/25 15:56:34 ID:???
MS-SQL2000で質問です。
あるテーブルにdatetime型で日付が入っているとします(便宜上2000/1/1とします)。
同じ行に何ヶ月後の何日というデータが、それぞれintegerで入っていたとします
(便宜上、1ヶ月後の15日とします)。

1本のクエリで、それぞれのdatetime値を何ヶ月後の何日というように変換して
取得したいのですが、この場合はどうすればいいんでしょう。

上記の例ですと、2000/2/15というように日付を計算させた後に表示をしたいのです。
pg上でも可能ですが、サブクエリでも使いたいので・・・

251 :250:05/02/25 17:06:04 ID:???
調べてみますた
フィールド名が日付→DateTime、何ヶ月後→MonthDiff、何日→MonthDiffとして、
Cast Year(DateTime) + "/" + Month(DateAdd(DateTime,mm,MonthDiff) + "/" + DateDiff As DateTime
文法あってるかどうかわかんないけど、こういうやり方しかないんですかねぇ


252 :NAME IS NULL:05/02/25 17:08:47 ID:???
>>250
dt datetime
m int 何ヶ月後
d int 何日

SQL鯖で動くかどうか知らんが、特にキャスト演算子は書き換えが必要だろうな。
SELECT date_trunc('month' , dt)+m*'1 month'::interval+(d-1)*'1 day'::interval FROM Table;


253 :250:05/02/25 17:27:55 ID:???
>>252
ありがとう。
だけど、SQLには、そういう類の関数はないみたいですねぇ。
SQLって、日付関連の関数がすごい貧弱だ・・・

254 :NAME IS NULL:05/02/25 17:43:09 ID:???
>>253
ちょっと解説すると
date_truncは切捨て関数なんで、date_trunc('month','2005-1-8')は'2005-1-1'というようにその月の初日になる。
m*'1 month' でmヵ月分のinterval型。
d*'1 day' はd日分のinterval型。2005-1-1+d日になるので予め1日分ひいている。
で、全て足せばお望みの結果になるかと。

date_truncの代替手段はあると思われるけどなぁ。


255 :NAME IS NULL:05/02/25 20:42:39 ID:???
>>251
それだと年をまたいだ時におかしくならない?

>>252,254
SQLServerはDateTimeはあるけどintervalはない。
dateadd()とかdatediff()で頑張るしかない

256 :NAME IS NULL:05/03/01 23:42:08 ID:6E4qrgjn
下記のようなことを行いたいのですが、もう数十時間悩んでおり、このままだとクビになります。

以下のようなテーブルが2つあります

■テーブルA
顧客ID なまえ 内線
――――――――
001、 佐藤、 001 ※同じ(これだけ残す)
002、 鈴木、 002
003、 田中、 003 
004、 佐藤、 001 ※同じ(削除)
005、 佐藤、 004
006、 鈴木、 005
007、 佐藤、 001 ※同じ(削除)

■テーブルB
伝票ID 顧客ID 購入物
001、 001、 ガム ※対応する顧客は残る
002、 003、 チョコレート
003、 004、 塩  ※対応する顧客が残らない
004、 006、 ガム
005、 002、 塩
006、 007、 塩  ※対応する顧客が残らない

テーブルAの佐藤4人中3人は、名前も内線も同じなので
顧客IDは一番小さいものだけ残し、あとは同一とみなし重複行を削除します。

そうするとテーブルBの伝票IDの001、003、006の顧客IDは全部が佐藤だったのですが
重複を削除してしまったため、003と006に対応する顧客がテーブルAから消えてしまいます。

なので、テーブルAの重複を削除するときに、同時にテーブルBの顧客IDも
一緒に一番小さい顧客IDに更新したいのです。

どうか宜しくお願いいたします。



257 :NAME IS NULL:05/03/01 23:58:39 ID:???
update B set
顧客ID = sq.min_顧客ID
from B
inner join A on(B.顧客ID = A.顧客ID)
inner join
(select なまえ, 内線, min(顧客ID) as min_顧客ID from A group by なまえ, 内線) as sq
on(A.なまえ=sq.なまえ and A.内線=sq.内線)

delete A
from A left join B on(A.顧客ID = B.顧客ID)
where B.顧客ID is null




258 :256:05/03/02 06:52:59 ID:SXcU4gI8
>257
実施すると
ORA-00933 SQLが正しく終了してません
とかいうエラーがでまつ。
あとupdate文が複雑でよくわかりません
SQLビギナー向けに教えてくだ祭

259 :NAME IS NULL:05/03/02 08:33:07 ID:???
oracleでしたか・・・すみません。sqlserverしか手元にないです。
文自体はupdateとdeleteの2文です。
update文は
1. Aをなまえと内線で集約した際の最小顧客IDをサブクエリで取得
2. BとAを顧客IDで結合
3. 1.で取得した最小顧客IDでBを更新

delete文は間違えてました。
「Aをなまえと内線で集約して2件以上存在した場合のみ消す」
でないとだめのようです。
AにあるがBに使われてなかったレコード゙が消えてしまうからです。

260 :258:05/03/02 08:46:46 ID:om6OBkzg
>259
すいません、oracleです。
せっかくのアドバイスにけちをつけるようですいません。
>1. Aをなまえと内線で集約した際の最小顧客IDをサブクエリで取得
>2. BとAを顧客IDで結合
>3. 1.で取得した最小顧客IDでBを更新
考え方は分かるのですが、やはりピンときません。
テーブルA の削除だけなら分かるのですが、innner joinが良く分かりません。
innnerjoinってwhereで書き換えられませんでしたっけ?
馬鹿ですいません。


261 :NAME IS NULL:05/03/02 11:32:16 ID:nPxajXBe
>260
削除文を修正しました。
1. Aをなまえと内線で集約して2件以上あったデータを最小顧客IDと共にサブクエリ取得
2. Aとサブクエリをなまえ、内線で結合
3. そのうちの最小顧客IDとはことなる顧客IDのデータを削除
delete A
from A inner join
(select なまえ, 内線, count(なまえ) as cnt_なまえ, min(顧客ID) as min_顧客ID
from A group by なまえ, 内線 having count(なまえ) > 1) as sq
on(A.なまえ=sq.なまえ and A.内線=sq.内線)
where A.顧客ID <> sq.min_顧客ID

>innnerjoinってwhereで書き換えられませんでしたっけ?
はい。from A inner join B on(A.顧客ID=B.顧客ID)なら
from A, B where A.顧客ID=B.顧客ID と同じです。

分かり辛くて申し訳ないです。
更新系の文は部品ごとにばらして不必要列も取得してみてみると分かりやすくなると思います。

262 :NAME IS NULL:05/03/02 11:59:13 ID:???
>>256
同じ質問だからここに合流させときますね。
物凄い勢いで誰かが質問に答えるスッドレから合流っす
http://pc5.2ch.net/test/read.cgi/db/1056977791/644-654

263 :NAME IS NULL:05/03/03 23:59:11 ID:???
不一致データの抽出を行うSQL文について質問です.

次に示す3つのテーブルがあるとします.

顧客テーブル
顧客ID,顧客名
1   ,Aさん
2   ,Bさん
3   ,Cさん

家具テーブル
家具ID,家具名
1   ,テレビ
2   ,洗濯機
3   ,たんす

顧客保持家具テーブル
レコードID,顧客ID,家具ID
1     ,1   ,1
2     ,1   ,2
3     ,2   ,1
4     ,2   ,3
5     ,3   ,2
6     ,3   ,3

このとき,サブクエリとUNION句は使用せずに,
1回でたんすを持っていない顧客のIDを取得する
SQL文作ることはできるのでしょうか.

264 :NAME IS NULL:05/03/04 01:01:43 ID:???
>サブクエリとUNION句は使用せずに
なぜ?

select a.顧客ID from 顧客テーブル AS a left join
(select 顧客ID from 顧客保持家具テーブル as b
inner join 家具テーブル as c on (b.家具ID = c.家具ID)
where 家具名 = 'たんす') as d on (a.顧客ID = d.顧客ID)
where d.顧客ID is null

265 :NAME IS NULL:05/03/04 13:04:21 ID:???
UNIONはともかくサブクエリが使えないときついな。
たんすを持ってる顧客を求めるのは簡単だから、not in か not exists
あたりと組み合わせればできるのだが。
サブクエリの代わりにViewを使えってというのは反則?

266 :NAME IS NULL:05/03/04 13:20:44 ID:???
EXCEPTとか

267 :NAME IS NULL:05/03/04 13:31:47 ID:???
面倒なので結合はしてないけど、コレでどうだ。
select 顧客ID from 顧客保持家具テーブル
group by 顧客ID having sum(case 家具ID when 3 then 1 else 0 end) = 0


268 :NAME IS NULL:05/03/04 17:14:57 ID:???
>>267
たんす -> 3
の部分のクエリを省略しちゃいかんな

269 :NAME IS NULL:05/03/04 18:39:35 ID:???
>>268
そこよりも顧客保持家具テーブルにレコードがない顧客の
扱いをつっこまれたらどうしようかと思ってましたよ。
UNIONは無しだけどEXCEPTはありっていうのが解答だったら
それはそれでなんか納得いかないですけどね。

270 :NAME IS NULL:05/03/04 19:31:25 ID:???
>264
 古い MySQL(サブクエリが使えない)だから、だったりして……

271 :NAME IS NULL:05/03/05 15:17:39 ID:???
>>269
MSSQLだと家具IDがNULLでもelseに該当します。ほかの処理系は知りません。
だめな場合もCOALESCE(読み方がわからない)やらを組み合わせれば大丈夫かも。

272 :NAME IS NULL:05/03/05 22:08:38 ID:???
サブクエリーを使わないでというのは納得できないんだが、
↓のSQLでも実現できるかな?


SELECT  DISTINCT A.顧客ID
FROM  顧客テーブル A
WHERE NOT EXISTS (SELECT * FROM 顧客テーブル B WHERE 家具ID = 3 AND A.顧客ID = B.顧客ID)


273 :272:05/03/06 09:57:03 ID:???
顧客テーブルではなく家具テーブルだし・・・
家具を1つも買ってない客は抽出されないじゃん
orz


修正!!!
↓こうかな?? (;´Д`)


SELECT  DISTINCT A.顧客ID
FROM  顧客テーブル A
WHERE NOT EXISTS (SELECT * FROM 顧客保持家具テーブル B WHERE 家具ID = 3 AND A.顧客ID = B.顧客ID)


274 :NAME IS NULL:05/03/06 12:20:51 ID:???
NOT EXISTS以下がサブクエリじゃんって突っ込みは無しですか?

275 :272:05/03/06 17:34:45 ID:???
>>274
無しです。

サブクエリーが無いSQLは、1のギアしか無いマニュアル車に乗っているようなもんですよ!!(# ゚Д゚)


276 :NAME IS NULL:05/03/06 18:07:19 ID:???
はぁ?

277 :NAME IS NULL:05/03/06 18:13:03 ID:???
267の完全版、やはりこの方法しか思いつかない。
select A.顧客ID
from 顧客テーブル A left outer join 顧客保持家具テーブル B join 家具テーブル C
on (B.家具ID = C.家具ID) on (A.顧客ID = B.顧客ID)
group by A.顧客ID having sum(case C.家具名 when 'たんす' then 1 else 0 end) = 0

278 :NAME IS NULL:05/03/06 20:14:33 ID:???
こんだけ、みんなが親身になって考えてくれてるのに、何の反応を示さない恩知らずな>>263がムカツクな。
社会常識を備えているのか?


279 :263:05/03/06 20:39:28 ID:???
お礼のレスが遅くなってしまって申し訳ありませんでした.

ご返答下さってどうもありがとうございました.

サブクエリを使わないで,というのは,
>>270さんの仰るとおり,サブクエリを使えないDBを使用しているためです.



280 :NAME IS NULL:05/03/07 19:33:59 ID:ozYIDLtO
こんなことできるんでしょか。
select AGE from table group by AGE
てやると、

AGE
-----
age1
age2
age3

て、AGE のレコードで重複しない部分だけ表示されると。
んでも、その表示されたレコードが何個あるかってわかる?
select count(AGE) from table group by AGE
てやると、

1
----
1
2
1

てなると。さらに、
select count(AGE) from table group by 1
てやると、

1
----
4

てなる。重複除いた AGE の数が "3" て出すSQL一発で打てるんでしょうか。


281 :NAME IS NULL:05/03/07 20:20:51 ID:???
日本語を学んでから出直せ

282 :NAME IS NULL:05/03/07 21:56:01 ID:???
SELECT COUNT(*) AS NUM
FROM (SELECT DISTINCT AGE FROM table) AS COUNTTABLE

これでだめですか?

283 :名無しさん@そうだ選挙にいこう:05/03/07 23:01:36 ID:q3QYEE15
Access2000つかってます。
テーブルAのカラム1の先頭2桁をZZにするにはどうすればよいのでしょう?


テーブルA
 カラム1 カラム2
 X0100  aaa
 X0101  bbb
 X0102  ccc
 X0103  ddd

↓SQL実行後↓

テーブルA
 カラム1 カラム2
 ZZ100  aaa
 ZZ101  bbb
 ZZ102  ccc
 ZZ103  ddd

こんな感じです。関数を使えるのでしょうか?


284 :NAME IS NULL:05/03/08 00:06:52 ID:???
mid()

285 :NAME IS NULL:05/03/08 01:31:13 ID:???
>>280
select (distinct AGE) from ...
そんなことよりGROUP BY の使い方が気になる。こういう使い方ってできるの?
>group by 1

286 :NAME IS NULL:05/03/08 09:13:23 ID:???
ORDER BY 1
も大丈夫。

287 :280:05/03/08 13:17:54 ID:uAPNkung
>>282 ナイスです(/・∀・)/
ありがとうです m(_ _)m

288 :NAME IS NULL:05/03/08 14:21:24 ID:7EzAYhEF
サブクエリャー!

289 :NAME IS NULL:05/03/08 16:40:32 ID:???
>>285 は select count(distinct AGE) でした。
>>286
select AGE from table group by 1 なら1列目でグルーピングだとわかるのだが
select count(AGE) from table group by 1 この場合の1列目はグルーピングで
集計した結果だからどうグループ化されるのか不思議に思ったのです。
結果は4だから何をいったいGROUP BYしたのか?

290 :NAME IS NULL:05/03/08 22:47:47 ID:???
テーブルの制約を追加・削除するとき、alter table文で制約名を指定しますが、
表の作成時に列制約で指定した制約では制約名が指定されていません。
この場合、制約の追加や削除はどのように行うのでしょうか。
特に、not null制約の場合は列制約のみでしか指定できないので、
どのように削除すればよいのでしょうか。お願いします。


291 :NAME IS NULL:05/03/09 09:46:57 ID:???
>>290
DBMS依存する可能性のある話はDBMSをきちんと書く。

で、削除って考えないで打ち消すような制約をかければいいんじゃないのか?

292 :258:05/03/09 16:24:45 ID:yL4n2lnv
以下のようなことを「SQL文のみ」で行いたいのですが、
どなたかご教授のほどお願い致します。

下記のような文字列があるとします。
aaa1bbb2ccc3ddd4
それを
1234
にしたいのです。

要するに数字だけを抜き出したいのですが
できますでしょうか。

oracle9iです。

293 :NAME IS NULL:05/03/09 16:37:10 ID:???
>>292
超無責任モードですが、正規表現でできないか?
REGEXP_REPLACEあたりで、数字以外を痴漢してしまう。


294 :292:05/03/09 16:45:50 ID:yL4n2lnv
>>293
早速のご回答ありがとうございます。
しかし残念ながらREGEXPなんとかはoracle10gからの機能のようです。
できそうだったのに悔しいです。
oracle9iです、すいません。

295 :NAME IS NULL:05/03/09 17:06:56 ID:???
>>292
translate('aaa1bbb2ccc3ddd4','acbdefg....','');
oracleにtranslateがあるかどうか知らんが。
あと、除外する文字にマルチバイトが出てくると現実的じゃないがな。

296 :NAME IS NULL:05/03/09 17:07:54 ID:???
>>294
ほんとごめんね。手元に10gのマニュアルしかなかったんで。

純粋な1SQLでは無理そうだけど、ちょこっとストアドファンクション組んで、それを呼べば?


297 :294:05/03/09 17:10:56 ID:yL4n2lnv
>>295
すいません、基本的に除外する文字は全角文字です。
実際には
■変換前:千葉県浦安市1-5-4浦安マンション203号室
■変換後:154203
のような感じにしたいのですが、無理そうですか?


298 :297:05/03/09 19:03:01 ID:yL4n2lnv
どうやらsqlだけじゃ無理みたいだと判明しました。
よろしければPL/SQLでの関数の例のようなものをご教授いただけたら幸いです。


299 :NAME IS NULL:05/03/09 22:29:15 ID:ANreh8jo
>>298
例つうかそんなに難しくないだろ?
文字列を受け取って、長さ分ループして、
1文字づつ順に切り出して数字だったら出力用変数に連結、それ以外は捨て。



300 :NAME IS NULL:05/03/09 23:05:17 ID:???
>298
検証するPL作るの面倒くさい?

301 :NAME IS NULL:05/03/10 00:28:36 ID:3kehkfpX
うちの会社のSEに
オラクルで、データ型がCLOBのフィールドに対して
LIKEで検索出来ないって言われたんですけどマジですか?

うちの会社のSEがヘボなのかオラクルがヘボなのか
どなたか教えてくださいm(__)m

302 :NAME IS NULL:05/03/10 00:41:11 ID:???
アゲちゃいました。。
本当は自分で検証したくて、オラクルのHPで
お試し版をダウンロードしようとしたら、3営業日かかると言われたので、
こちらで質問させてもらいました。
#なんて大名商売な会社なんだよ。。。
似たようなことは、BorlandのInterbaseってDBでも出来ることなんで
天下のオラクルで出来ないはずはない、、はず、、ですよね?

303 :301-302:05/03/10 00:59:00 ID:???
3営業日かかるって言われたのはうそでした。
一旦、ブラウザ閉じて、接続し直したらお試し版ダウンロードまでたどり着けました
でも、600Mのファイルをダウンロードなんて、、、、無理です。ゴメンナサイ

どなたかCLOBのフィールドに対してLIKE検索の可否を教えて下さい〜

304 :NAME IS NULL:05/03/10 01:14:22 ID:???
オラクルスレで聞けばいいんじゃないかな?

305 :301-302:05/03/10 01:23:40 ID:???
>>304
そうですね、そうします!
そうじゃないかなぁって後で思っちゃいましたが
複数スレに同じ質問を書き込むのはアレだと思ったので。。。

306 :NAME IS NULL:05/03/10 19:53:20 ID:ICT2R8x6
DB2です。
A表とB表をJOINして、和を取りたいのですがどうすればよいのでしょう?
このときunionではなく、同一キーのものは1レコードとし、片方にしかキーがないものは
NULL値としたいのです。
left join だとA表に存在するもののみとなってしまうし、inner joinは積になる。
なんとかならないもんでしょうか?

e.g.

A B
key value1 key value2
01 AA - -
02 BB 02 CC
- - 03 ZZ

これを 下記としたい。

key value1 value2
01 AA -
02 BB CC
03 - ZZ

307 :NAME IS NULL:05/03/10 19:58:10 ID:ICT2R8x6
表がぐちゃぐちゃなので再投稿

e.g.

A
+--------+
|key|value1|
+--------+
|001|AAAA|
|002|BBBB|
+--------+

B
+--------+
|key|value1|
+--------+
|002|CCCC|
|003|ZZZZ|
+--------+

これを 下記としたい。

+--------------+
|key|value1|value2|
+--------------+
|001|AAAA|------|
|002|BBBB|CCCC|
|003|-----|ZZZZZ|
+--------------+

308 :NAME IS NULL:05/03/10 21:44:00 ID:???
>>307
FULL OUTER JOIN


309 :NAME IS NULL:05/03/11 00:57:19 ID:???
外部結合という用語の定義に関して質問があります。
外部結合の左外部結合と右外部結合に関して、大多数の本には、
SELECT文のJOIN句の前(左側)に書くテーブルを優先するのが左外部結合、
SELECT文のJOIN句の後(右側)に書くテーブルを優先するのが右外部結合、
と説明されています。ところが、ある一部の本では、一対多のリレーションシップを
設定した場合に、一側のテーブルを優先する場合が左外部結合、多側の
テーブルを優先する場合が右外部結合と書かれています。
いったいどちらの定義が正しいのでしょうか?


310 :NAME IS NULL:05/03/11 10:15:31 ID:???
前者の説明で正しい。リレーションと外部結合は直接関係はない。
おそらく後者の言いたいことは一対多のリレーション関係を持つテーブルを結合する
場合は、一 left join 多 として結合することが多いということでしょう。

311 :NAME IS NULL:05/03/11 12:24:23 ID:???
>>310
わかりました。ありがとうございます。

312 :1/3:05/03/12 03:17:26 ID:???
突然ですが,面白い SQL を思いついたので,ご意見を頂きたいです.
興味を持たれた方は使ってみてくだちい。

一般的に,SQL の発行は,プリペアドステートメントを使う方がよいと
されている.その理由は,
・DBMS のキャッシュが良く効く.
・SQL インジェクション等の危険が避けられる,等.

しかし,webアプリの検索フォームなどでは,プリペアドステートメントは
使えない場合が多かった.検索条件項目が複数存在していて,いずれの項目も
必須で無い場合,項目が入力されているかどうかをチェックし,それに合わせて
SQL 文の WHERE 句の内容をツギハギしなければならないからだ.

SQL文そのものも,そしてそれにセットする引数の個数も可変なので,
プリペアドステートメントを使うのは無理だったのである.

今回思いついたのは,このような条件で,プリペアドステートメントを使う
方法である.


313 :2/3:05/03/12 03:19:15 ID:???
やることは大変簡単で,

1. WHERE 句の内容全てを 括弧で囲み,最後に「IS NOT FALSE」という
 述語を付ける.
2.空欄になっている,検索条件に含めない項目には,NULL をセットする.
 (空文字列や空白をセットしてはいけない)

この二つだけである.

例)ユーザID,職業,年齢を条件として検索する.どれも必須項目でない.
SELECT *
FROM Table_Name
WHERE
(
      user_id = ?
  AND   profession = ?
  AND   age >= ?
  AND   age < ?
)IS NOT FALSE
ORDER BY user_id


314 :3/3:05/03/12 03:20:43 ID:???
このように書くと,null をセットした項目は,検索条件として使われない
かのように振舞う.SQL を if 文でツギハギにする必要も無くなり,
ぐっとコードが読みやすくなると思う.

なんでこういう動作になるのかというと,SQL が実は3値論理だからである.
詳しくはこの辺を参照.
http://www.geocities.jp/mickindex/database/db_3vl.html
(私自身とは無関係のページです)

気になるパフォーマンスだが,PostgreSQL で測定したところ,
(  ) IS NOT FALSE がつかない場合と比べて,全く差は無かった.
実は既に,現在進行中のプロジェクトで使っている.今のところ,
全く問題は無い.

以上です.質問スレにこういうことを書くのは,かなりスレ違いですみませんが,
SQL 自体について一番詳しい方が来られるのはここだと思って,書かせていただき
ました.ご意見,ご批判などを伺いたいと思います.


315 :NAME IS NULL:05/03/12 10:30:54 ID:???
同じものを2回ずつ指定するのがスマートじゃないがベンダー依存の部分を排除するとこんな感じ。
WHERE (user_id = ? OR ? IS NULL) AND (profession = ? OR ? IS NULL)
AND (age >= ? OR ? IS NULL) AND (age < ? OR ? IS NULL)

316 :NAME IS NULL:05/03/12 11:11:54 ID:???
これはちょっと面白いねえ。PreparedStatement は面倒なんで試してないけど、
普通のsqlで書いてみると、age < NULL みたいにNULLを指定した条件は確かに
無視されるよ。仕組みは良くわかんないけど。

>>315
ベンダ依存なの?これってSQL92だと思うんだが。


317 :NAME IS NULL:05/03/12 11:12:02 ID:???
>>313
user_idが5であとがnullだったら全件ヒットしない?

318 :NAME IS NULL:05/03/12 11:25:55 ID:???
>>316
おまいの使ってるDBMSはなんだ?少なくともOracle9では動かんぞ.
まあOracleは,結構特殊だったりするけど.


319 :NAME IS NULL:05/03/12 11:34:15 ID:???
BOOLEAN値はSQL99あたりからだったかな?
そのせいでまだサポートしてなかったりシノニムで済ませてる処理系が多い。
ただ IS [NOT] [FALSE|TRUE|UNKNOWN]はpostgreSQL独自だと思ったけど。

320 :316:05/03/12 11:36:49 ID:???
>>318
俺は PostgreSQL7.3だけど、Oracleで動かないのかよ、これ。まいったな。
どうみても基本的な構文じゃないか。


321 :NAME IS NULL:05/03/12 11:53:10 ID:???
>>319
Boolean 型は確かに,SQL99 からだ.
http://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1a.html

しかし,IS [NOT] (TRUE | FALSE | UNKNOWN) は,それとは関係無く SQL92 だ.
『プログラマのためのSQL(第2版)』第11章「評価述語」に,そう説明がある.
PostgreSQL 独自拡張ではない.


322 :NAME IS NULL:05/03/12 12:09:15 ID:???
>>312-314
最初はチョト理解できなかったけど、こういうことか。
user_id = NULL 等とすると NULL(UNKOWN)になるから、

(TRUE and TRUE) -> TRUE (IS NOT FALSE)
(TRUE and NULL) -> NULL (IS NOT FALSE)
(FALSE and NULL) -> FALSE
(FALSE and FALSE) -> FALSE

いけるかも。ありがたく使わせていただきま。

323 :NAME IS NULL:05/03/12 12:29:50 ID:???
>>321
了解、SQL92なんだけどサポートしてる処理系が少ないということかな。
とりあえず OracleとMSSQLはだめっぽい。MySQLマニュアルを見た限り見当たらないけどどーなんでしょう?
>>322
IS NOT FALSEで真になるのはTRUEかUNKNOWNの場合に最終的にTRUEになるわけだ。
ただそのままいただいちゃうとまずいかも次のようにすべき。
WHERE (user_id = ?) IS NOT FALSE
AND (profession = ?) IS NOT FALSE
AND (age >= ?) IS NOT FALSE
AND (age < ?) IS NOT FALSE

324 :322:05/03/12 12:38:27 ID:???
>>323
何故「そのままいただいちゃうとまずい」のかご教示いただきたく。

325 :NAME IS NULL:05/03/12 12:51:50 ID:???
>>324
すまん、俺が間違ってた。
false and unknown は falseだからいいのか。
false and unknown を unknownと勘違いしてました。

326 :312-314:05/03/12 14:02:59 ID:???
いろいろなご意見,ありがとうございます.
見慣れない構文なので,受け入れていただけるかどうか不安でしたが,
ご理解いただけたみたいで,大変ありがたいです.

私が今回の SQL に込めたかった主張は
「もっと積極的に,NULL と3値論理を使おうよ」ということです.

NULL の危険性を理解せずに,カラムに NOT NULL 制約をつけないのは論外
ですが,NULL を目の敵のように排除して,2値論理だけしか扱わないのも,
もったいないと思うのです.3値論理はそんなに難しいものではありませんし,
2値論理にはない便利さがあるのですから.


327 :312-314:05/03/12 14:05:37 ID:???
(   ) IS NOT FALSE は,例えばこんなふうにも使えます.

テーブル同士を JOIN するとき,カラム名が共通なら USING を使うの便利だが,
一つでも共通でないカラム名がある場合は,ON TableA.id = TableB.id ... と,
ON 句をズラズラ書かなければならなくなる.USING 句と ON 句は併用できない
からである.

これには回避策があって,USING 句には共通のカラム名だけを並べ,残りのカラムは
WHERE 句で結合することができる.
しかし,これは外部結合(LEFT JOIN など)の場合は使えない.片方のカラムが NULL
になる場合が,ぜんぶ除かれてしまうからである.

そこで,(  ) IS NOT FALSE である.これで,片方が NULL でも結合ができる.

SELECT *
FROM  TableA LEFT JOIN TableB USING(a, b, c)
WHERE (TableA.hoge = TableB.fuga) IS NOT FALSE


328 :312-314:05/03/12 14:07:38 ID:???
上の SQL は,パフォーマンスは確かめてないので,自己責任で試してくだちい.

もう一つ,私の込めた主張は,
「ベンダはちゃんと,IS [NOT] (TRUE | FALSE | UNKNOWN) をサポートしてよ」
ということです.これがないと,3値論理をきちんと使えませんから.

私が試したのは Oracle9, MySQL4.1, PostgreSQL7.4 ですが,PostgreSQL しか
サポートしていませんでした.こんなに便利なのに,なんとも残念です.

とくにOracle! 再帰的SQL まで用意しているくせに,IS TRUE どころか USING
すら満足に動かぬ.優先順位というものがあるのじゃないかと思うのだけど.

他の DBMS はどうなんだろう?SQL-Server, Firebird なんかをお使いの方は
おられませんか?


329 :312-314:05/03/12 14:30:01 ID:???
PostgreSQL と Struts をお使いの方にだけ補足.

・PreparedStateMent に setInt すると,NULL を代入できません.
だから,数値も setString してやる必要があります.
この場合,比較が文字列比較になってしまいますから,きちんと数字で比較
されるよう,セットされた値をキャストしてやる必要があります.

age < ?::INTEGER

・空欄なら NULL をセットするようにするには,ActionFormBean の getter に
細工をしてやるのが便利です.

public String getAge() {
  return "".equals(this.age) ? null : this.age;
}

しばらくこのスレを離れます.次に来るのは遅くなるかもしれません.


330 :NAME IS NULL:05/03/12 15:30:05 ID:???
>>329
>PreparedStateMent に setInt すると,NULL を代入できません.
>だから,数値も setString してやる必要があります.
>この場合,比較が文字列比較になってしまいますから,きちんと数字で比較
>されるよう,セットされた値をキャストしてやる必要があります.

確実に遅くなるじゃん

331 :NAME IS NULL:05/03/12 15:37:48 ID:???
まあ何だANSI SQLはエスペラント語みたいなもんだな。
もっと下世話な例ではビデ倫みたいなのもで○○不可が売りになる。
>>329
PostgreSQLはよくわからなけどPreparedStatement#setNullじゃだめ?

332 :NAME IS NULL:05/03/12 18:11:45 ID:???
>>331
if 文を使いたくないから,この構文を導入したのに,値があるかどうかで
setInt() と setNull() をif文で切り替えるんなら,あんまり意味なくない?


333 :NAME IS NULL:05/03/12 19:16:02 ID:???
>>332
ActionFormはどっちにしろ文字型だからどうでもいいのですが、
PreparedStatementで数値の項目にsetStringするのはどうかといいたいのです。
暗黙に文字から数値の変換はやってくれてるようだけど、
これはベンダー依存ではないかといいたいわけです。
JDBCが仕様的にこの手の変換をサポートしてるならかまわないだけれどね。

334 :NAME IS NULL:05/03/12 20:24:07 ID:???
>>332
それもあるけど、問題なのは条件によってSQLを動的生成するのではなく
PreparedStatementを使いたいということらしいので
そこくらいはどうとでもなるだろう。
何ならnullかどうか判断してsetIntかsetNullか必要な方を使うメソッドでも作れば良いだけだし

335 :NAME IS NULL:05/03/13 03:03:25 ID:4M7LWvrN
ttp://www.ashisuto.co.jp/magazine/topic.php?A=17&B=183
この記事の中段下付近に CREATE VIEW と CREATE INDEX は置き換え可能
みたいなことが書かれているのですが今ひとつ理解できません。
どなたか解説してもらえないでしょうか?

336 :NAME IS NULL:05/03/13 03:52:20 ID:???
>>335
読んだけど全体的に何のことやらさっぱりだね。
何度か読み直して一部がなんとなく理解できる程度。

「理解できないのはあなたがバカだから私の提案する方法にしなさい」

って言われている気がしてきた。まぁ、それはそれでいいんだけどさ
◆本物のデータを集める◆の実例のところは一理あるかも知れんけど、
ニワトリとタマゴ的な問題で、一方の考え方を押し付けた感じがする。

スレ違いな反応でスマソ


337 :NAME IS NULL:05/03/13 10:35:50 ID:???
>>335
「抜粋・収録したものです」ってあるからライターの力量の欠如と見た。
アシストは汎用機向けのツールもつくってるから聴衆は汎用機の顧客で管理者クラスと思える。
特にVIEWをはじめ幾つかの用語がこの聴衆にわかりやすくするためにある前提で語られていて
一般的な用法ではないと思われるが、この要約ではその説明が省略されているように思える。
内容をよく理解せず抜粋して飛び飛びで文章をつないだ感じだ。

338 :NAME IS NULL:05/03/13 12:13:21 ID:???
>>335
T字形のおっさんだな。ここを読むと理解の助けになるかも。
ttp://www.sdi-net.co.jp/news-index01.htm
もともと癖の強い主張をしているだけあって、読んでも理解できない
部分もあるが。

「トラヴァーサル・テーブル」の項を読むと、最適化が弱かった時代の
古いRDBMSを相手に話しているのがわかる。

339 :NAME IS NULL:05/03/13 21:33:07 ID:???
>古いRDBMSを相手に話しているのがわかる。
納得しました。

340 :NAME IS NULL:05/03/14 09:31:44 ID:???
>>335
この部分だけ読むと意味不明だよな。
>>338さんの書いてるT型ER図ってのをすこし齧らんとわからん。

で、一応は理想的に最適化されたテーブルでは、その通りだとは思う。
あと、実装面でもクラスタ化されたIndexであれば実表参照しないので、=View実装とはなる。
しかも、Viewとちがって扱いやすいし早い。
(最近はViewに対するIndexとかあるからまた別な気もするが・・・。)

341 :312-314:05/03/14 11:03:36 ID:???
大変遅くなりました.少しだけ補足.

>>333
指摘はもっともですが,おっしゃっている内容は,実際と逆です.
PostgreSQL は String をセットされた場合,数値型に型変換はしません.
?::INTEGER は見慣れない構文ですが,これは Integer 型への明示的な
キャストです.PostgreSQL 専用の構文ですので,他のDBをお使いの方は
わかりづらかったかもしれません.

>>334
私の今回のプロジェクトは,あまり速度を必要としなかったので
記述の簡単さを考えてこのような書き方にしましたが,速度を考えた場合,
おっしゃる通り新しい関数を作って,それを実装した PreparedStatement の
子クラスを作るか,setBigDecimal() を使うかした方が良いでしょうね.


342 :312-314:05/03/14 11:56:56 ID:???
実は,私はあまり,実装の細かいところの話をするつもりはあまりなくて,
NULL と UNKNOWN を積極的に使うことによって,従来出来なかったことが
いろいろ出来るようになる,という話で盛り上がりたいと思っていたの
です.

残念ながら,それは私の力不足でうまく行かなかったようです.どうも,
私の出した例が,いずれもあまり説得的でなかったようですね.

私の例にとらわれず,今後どなたかがとても面白い利用法を思いつかれる
ことを期待します.

では,失礼します.

343 :NAME IS NULL:05/03/14 12:25:05 ID:???
>>342
奇しくも>>338のT字形のおっさんによればnull値は使うなってことになってる。

↓ここの十戒の(7)
ttp://www.sdi-net.co.jp/waseda-ext-note-20041203.htm

344 :NAME IS NULL:05/03/14 12:36:45 ID:???
T字形のおっさん(なんかこの呼称で定着しそうだが)の理論は個性的で面白いのだが、
おっさんの脳内にあるRDBMSの実装は相当古そうだから、具体的にこうすべし
こうするべからず的な部分はバイアスかけたほうがよさそうだぞ。

345 :NAME IS NULL:05/03/14 13:07:47 ID:???
まあ、設計手法は色々勉強しておいたほうがよいとは思う。
T字形を妄信するのもあれだが、いろんなエッセンスは自分で吸収すべき。
温故知新ってこともあるし、今でも通用する部分もあるし。

346 :NAME IS NULL:05/03/14 13:40:20 ID:???
標準化されたSQL使っててもDBMSによって最適化手法が
まったく異なるってのは罪だよなぁ。

347 :NAME IS NULL:05/03/14 15:15:04 ID:???
でもさ、基本的な考え方は同じでしょ?
基本は兎に角HDDアクセスさせないこと。


348 :NAME IS NULL:05/03/14 16:20:15 ID:???
DBMS毎に >HDDアクセスさせない SQLの書き方が異なるから困っとるっちゅうねん。

349 :NAME IS NULL:05/03/14 18:48:33 ID:???
それはSQLの書き方の問題か?
そもそもの設計レベルで大半は決まるものだと思うが。
SQLはその結果にすぎず、そこであまりにテクニカルなことしてるのは、設計が糞なだけ。

350 :NAME IS NULL:05/03/14 19:27:20 ID:???
DBMS毎に最適な設計が異なるから困っとるっちゅうねん。

351 :NAME IS NULL:05/03/14 19:55:01 ID:mCTqLZDk
・商品テーブル
商品コード、商品名、区分名
・テーブル1月
商品コード、商品名、売上
・テーブル2月
商品コード、商品名、売上
・テーブル3月
商品コード、商品名、売上

以上のテーブルで、3か月間の総売上数をだして、
区分別に並べ替えて、
それを売上が多い順に並べ替えかえるには
どんなSQL文になりますか?
商品コードでリレーション組んだらでいろいろしたんですが、
Error 3258がでる。。。どなたかお助けください。
ちなみに環境はAccess2003です。

352 :NAME IS NULL:05/03/14 20:24:01 ID:???
select st.商品コード,st.商品名,st.区分名,売り上げの合計 FROM 商品テーブル as st
inner join
(select Q1.商品コード, Sum(Q1.売り上げ) as 売り上げの合計
from (
select st.商品コード,売り上げ from 商品テーブル as st inner join テーブル1月 ON st.商品コード=テーブル1月.商品コード
union all
select st.商品コード,売り上げ from 商品テーブル as st inner join テーブル2月 ON st.商品コード=テーブル2月.商品コード
union all
select st.商品コード,売り上げ from 商品テーブル as st inner join テーブル3月 ON st.商品コード=テーブル3月.商品コード
) as Q1
group BY Q1.商品コード) Q1
on Q1.商品コード=st.商品コード
order by 区分名,売り上げの合計 desc

353 :NAME IS NULL:05/03/14 20:27:47 ID:???
Access使いはなぜか1月・2月・3月テーブルという分け方するやつらが多いな。
ビジュアルな環境で限られたデータを相手にするにはこっちのほうがわかりやすいのだろうか?

354 :NAME IS NULL:05/03/14 20:37:38 ID:???
>>353
Excelの延長で、データシートに直接入力してる人も多い。
便利に使えればそれでもいいかも。

次のようなクエリを保存して、それを元にもうひとつクエリ作ったほうがわかりやすいと思う

Select * From テーブル1月
Union
Select * From テーブル2月
Union
Select * From テーブル3月


355 :NAME IS NULL:05/03/14 21:00:33 ID:mCTqLZDk
352、354さん
ご教授ありがとうございます。
助かりました。
本当にありがとうございます。

356 :NAME IS NULL:05/03/15 12:35:52 ID:YtHhx7pD
SQLの文法を
BNFで表記してる資料ってあります?


357 :NAME IS NULL:05/03/15 17:49:15 ID:1wTc5Dg1
質問させてください。
現在JSPとOracle8でシステムを作っています。
JSPでの計算結果をDBに登録するのですが、
NUMBER型のカラムに対して1未満の数値、例えば0.87を入れようとすると、
登録は問題なく可能なのですが、selectして返ってくる結果が
.87
のようになってしまい、0が欠けてしまいます。
正常に読み出しできる方法を教えていただけないでしょうか。

358 :NAME IS NULL:05/03/15 18:27:03 ID:???
>>357
それはJSPの表示の問題かと。javaの機能をそのまま使うならDecimalFormat、
JSTLならfmt:formatNumberをつかってね。

359 :NAME IS NULL:05/03/15 18:46:47 ID:???
数値のフォーマットをOracle側で処理したいなら
select TO_CHAR(数値フィールド, '990.99') from ...
これでNUMBER型から文字型に変わったので、java側でgetDoubleでなく
getStringで読み出すとよい。

360 :NAME IS NULL:05/03/15 20:15:15 ID:???
質問です。
オラクルにて、SQLで接続しているサーバーやユーザー名を表示することってできますか?
それと、テーブルの最終更新日等をSQLで表示することはできますか?

361 :NAME IS NULL:05/03/17 15:54:50 ID:uwK64/SN
初歩的なもので申し訳ないのですが質問させてください。

ttp://www.kogures.com/hitoshi/webtext/db-access-select/index.html
のサイトで練習問題を解いているのですが
例題4−3のGROUP BYの問題が分かりません。どなたか解説していただけませんでしょうか。
お願いします。

362 :NAME IS NULL:05/03/17 16:14:43 ID:/ywboqHa
DATE型について質問です。
DATE型のCREATE_TIMEという列に日時を入れたいと思っているのですが、
insert into TABLE (CREATE_TIME) values ('2005/12/31');
というのは実行可能なのですが、
insert into TABLE (CREATE_TIME) values ('2005/12/31 23:59:59');
とすると、
>ORA-01861: リテラルが書式文字列と一致しません。
というエラーが出て悩んでいます。
試しに同じ2005/12/31 23:59:59という値をAccessで直接入力すると値が正常に入るようなのです。
insert into TABLE (CREATE_TIME) values (to_char('2005/12/31 23:59:59', 'YYYY/MM/DD HH24:MI:SS'));
としても、
>ORA-01722: 数値が無効です。
と出てしまいます。
SQLでDATE型にYYYY/MM/DD HH24:MI:SS形式のを入力する方法を教えていただけないでしょうか。

363 :NAME IS NULL:05/03/17 16:33:13 ID:???
>>362
× values (to_char('2005/
○ values (to_date('2005/

364 :NAME IS NULL:05/03/17 16:40:28 ID:???
>>361
4 集計(SUMとGROUP BY)
のすぐ下の囲みのところに答えが書いてあるやん。
ケース3は微妙な希ガス。

>>362
Oracleはtimestamp型をdate型に自動キャストしてくれないのか?
それともdate型を期待するところにいきなり'2005/12/31 23:59:59'を持ってきても
date型じゃないのでtimestamp型かどうかいちいち検証しない。
のどちらかか?
とりあえず前者なら、'2005/12/31 23:59:59'をdate型にキャストするだけで
いけると思うが、後者ならtimestampにキャストする。

365 :361:05/03/17 16:44:20 ID:uwK64/SN
>>364
あ、もろ答えでした・・・すいません、ありがとうございます。
確かにケース3は微妙ですね、中のデータ次第ですよね。

366 :364:05/03/17 16:49:49 ID:???
>>365
データ次第なら「間違い」なんだろうけど、そうじゃないように思える。
まさか、処理系次第だたりして...first()って標準なのか?

367 :NAME IS NULL:05/03/17 17:05:01 ID:???
>>364
暗黙の型変換はするけど、デフォルトの書式に時刻は含まれてないんで。
因みにウチの環境だと

|SQL> select * from v$nls_parameters where parameter = 'NLS_DATE_FORMAT';
|
|PARAMETER      VALUE
|------------------ -----------------------
|NLS_DATE_FORMAT  RR/MM/DD

データベースのパラメータを弄るか、でなけりゃセッション中に

|SQL> alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';
|
|セッションが変更されました。
|
|SQL> insert into hoge (CREATE_TIME) values ('2005.12.31 23:59:59');
|
|1行が作成されました。

とするしか。

368 :NAME IS NULL:05/03/18 10:50:00 ID:bz1wnhzs
where句についての質問なのですが

where 履修表.学生番号=学生表.学生弁号
and 履修表.科目番号=科目表.科目番号
and (科目名=’語学’or 科目名=’貿易論’)
and 成績=5;

のように条件で()を使うことはできるのでしょうか?

369 :NAME IS NULL:05/03/18 11:39:44 ID:???
>>368
できる。で、その程度なら試してみればいいじゃん。
ついでに、上記例の場合は、orで書くよりINで書くほうが可読性がよいとおもう。

370 :NAME IS NULL:05/03/18 11:46:06 ID:bz1wnhzs
>>369
ありがとうございます。
試したいのですが、データベースが無いんです。

371 :NAME IS NULL:05/03/18 11:52:12 ID:qh+VXfcQ
こんにちは。
いつもお世話になっています。

update文を使用して、データに改行を入れたいのですが、どうすればよいでしょうか。

対象列のデータ型はVARCHAR2です。

例えばSQLPLUSから、
SPL>update 「テーブル名」set 「対象列」='あ改行い改行う改行'
を投入し、そのあと
select 「対象列」 from 「テーブル名」
とすると
SQL>あ
SQL>い
SQL>う
と出てくればよいんですが、
SQL>update 「テーブル名」set 「対象列」='あ\nい\nう\n'
としても
SQL>あ\nい\nう\n
と、「\n」が文字列としてでてきてしまいます。

SPL>update 「テーブル名」set 「対象列」='あ
2い
3う'
と投入すると、期待通りになるのですが、
そうではなく一行にまとめたいのですがどうすれば良いでしょうか。

Oracle9iを使用しています。
宜しくお願いいたします。

372 :NAME IS NULL:05/03/18 11:53:35 ID:LK2oaBk/
| SQL>あ
| SQL>い
| SQL>う
| と出てくればよいんですが、

| そうではなく一行にまとめたいのですが

矛盾


373 :NAME IS NULL:05/03/18 11:59:50 ID:???
>>370
MySQLでもフリーな奴落として試せばいいじゃん。

374 :NAME IS NULL:05/03/18 12:06:49 ID:qh+VXfcQ
>372
すいません、わかりづらかったですね。
update文を一行にまとめたかったのです。

SQL>update 「テーブル名」set 「対象列」='あ
2い
3う'
ではなく
SQL>update 「テーブル名」set 「対象列」='あ?い?う?'
の?になんらかの文字をいれて
改行を表現したかったのですが、
\n とか \\n とか試したのですが
ダメでした。



375 :NAME IS NULL:05/03/18 12:20:54 ID:???
>>374
MSSQLだと 'あ' + CHAR(13) + CHAR(10) + ..
Oracleだと 'あ' || CHR(13) || CHR(10) || ..
ほかの処理系にも似た関数があると思うから調べてみてくれ。

376 :NAME IS NULL:05/03/18 12:26:58 ID:qh+VXfcQ
>375
できました、
神よ、ありがとう

377 :NAME IS NULL:05/03/18 19:21:58 ID:4/cvFSZi
'あ' || CHR(10) || 'い' || CHR(10) || 'う'

378 :NAME IS NULL:05/03/18 19:36:05 ID:vv1hLnM8
一年生、男性、5人
二年生、女性、3人

というクエリー結果を

    男性  女性
一年生 5人
二年生     3人

っていう風に二次元状に見せたいときどうするの?

やっぱPHPで加工するしかないのかな?

379 :NAME IS NULL:05/03/18 20:12:26 ID:???
select 学年,case [性別] when '男性' then [人数] end as 男性,case [性別] when '女性' then [人数] end as 女性
from anyview

380 :えせ壊人:05/03/18 20:24:36 ID:Jb7aT050
PostgreSQL 8.0.1を使用しています
現在の年度を取得するために以下の命令を実行しました
>Select extract(year from('NOW'::timestamp - '3 month'));
結果
>invalid input syntax for type timestamp: "3 month"

減算符号を加算符号に変えて
>Select extract(year from('NOW'::timestamp + '3 month'));
を実行すると、予想通りの正常な値を出力してくれるのですが
どっか間違えてますかねぇ?

>Select extract(year from('NOW'::timestamp + '15 month'))-1;
なんてクソな事は避けたいのですが。

381 :NAME IS NULL:05/03/18 20:33:36 ID:???
'NOW'::timestamp + '-3 month'

382 :えせ壊人:05/03/18 20:36:54 ID:Jb7aT050
>>381
即レスありがとうございました。
そのやり方で実行できました。
シーラ本には『加算/減算ができます』と書いてあったのですが
制限があるのですね。

勉強になりました

383 :NAME IS NULL:05/03/18 22:03:35 ID:???
>>382
Select extract(year from('NOW'::timestamp - '3 month'::interval));

384 :プログラマ修行中:05/03/19 23:41:58 ID:KR4nK/+8
すいません(><)学生なのですがサブクエリの問題が分からないので教えていただけないでしょうか??
 次の問題からサブクエリを使ってSQL文を考えなさい。
  売れてない商品の商品コードを受注明細テーブルから抜き出し、商品テーブルからその条件に合う商品コードと商品名を取り出す。(商品コード11,13,34)
お願いします。。

385 :NAME IS NULL:05/03/19 23:47:08 ID:???
>>384
SELECT 商品コード,商品名 FROM 商品テーブル AS T1
 WHERE NOT EXISTS (SELECT * FROM 受注明細テーブル AS T2 WHERE T2.商品コード=T1.商品コード);

386 :プログラマ修行中:05/03/19 23:52:16 ID:KR4nK/+8
>>385さん 本当にありがとうございました!!

387 :NAME IS NULL:05/03/21 03:02:35 ID:dFe3E0+N
教えてください。

仕事でVB+Oracleで開発してるんですが、
派遣社員が作ったSQLが複雑すぎて読みきれません。

INNER JOINで3つぐらい連結してる程度なのですが、
とにかく読みづらいです。

テストでデータがヒットしないので本人に聞くと
「なんでヒットしないかわからん。」
っておっしゃいます。

単体テストのレベルなら、デバッグでSQL文を取り出して
実行していけばいいのですが、客先テスト中で、ヒット
しない原因が客先のデータが悪いのか、プログラムが
悪いのかを調べるのに1テストあたり2時間ぐらい
かかってます。


一昔前のプログラムは、ダラダラとIF文がつながっていたけど、
どこで処理が抜けていたかが分かりやすかったと思います。

SQLの複雑さはどの程度までゆるされるんですか?
たとえばサブクエリは2つ以上含めないとか
コツかなんかありませんか?

ストアドを利用するのが一番ですか?
今回のプロジェクトは客先の要望でストアド禁止なんですが

388 :NAME IS NULL:2005/03/21 03:43:25(月) ID:???
>>387
例えば売上データの一覧表示したいときに
売上テーブルと商品テーブルと顧客テーブルは必要だから、
これだけで3テーブル結合しなきゃならんわな。
これに、顧客グループとか商品カテゴリなんて概念が入るとますます増える。

SQLを書いた本人が「なんでヒットしないかわからん」ってのは論外だと思うけど、
複雑さとか読みやすさって人それぞれだろうし、ケースバイケースなんじゃない。
結合するテーブル数やサブクエリの数じゃないと思う。

んで俺の場合なんだけど、良いか悪いかワカランが、VIEWを作りまくり。
とりあえず売上データ一覧ビューなんて作っておいて、必要に応じて
商品カテゴリと結合したり顧客グループと結合したり。さらにフルセットビュー
なんて全てを結合したビューを用意したりするからビューの入れ子なんてのもアリ。

ビューの入れ子をすると性能が落ちる処理系もある(あった?)みたいだけど、
一度に巨大なビューを作るより、小さなビューを入れ子にした方が、
OOPっぽくておつ? と勝手に思ってますがw。

なんか碇石みたいなものがあるのなら、俺も知りたい。

389 :NAME IS NULL:2005/03/21(月) 04:46:30 ID:???
>>388
つうか、そのためにVIEWが用意されていると思った。
DBMS毎に実装は異なるだろうけど、VIEWはCREATE文を発行したときは何もせず、
参照されたときに(その都度)それに相当するSQL文を生成して実行する。
だから、VIEWを使おうが使うまいがコストの違いは無視できる程度に収まる。

390 :388:2005/03/21(月) 05:35:04 ID:???
>>389
そうなんだけど、書籍などはVIEWの説明はあっても、事例などでVIEWを
利用しているものなんてあまり見ない。入れ子となるとなおさら。
まぁ、あまり多くの書籍を読んだわけじゃないからたまたまかもしれんが。

と、性能が落ちると書いたのは、入れ子を深くするとプランナかオプチマイザかが
うまく最良のプランをはじき出せなくなる(つうバグ?)ってのをどこかで読んだ記憶が
あるんだけど... どこにあったか忘れてしまった。

だもんで、VIEWの入れ子は好きなんだけど、なんとなく「邪道かも」って
心の奥底で引っかかっていたりする。気にしながら使い放題なんだけどなーw

391 :NAME IS NULL:2005/03/21(月) 08:11:30 ID:???
>387
そのSQLがどの程度複雑かどうかを
見せて貰えると何か改良点が分かるかも知れない。
ウチの場合レスポンス向上でどうしてもエグイSQLやストアドには
・全員目を慣らしておく
・ネストきっちり
・コメントたっぷり

392 :NAME IS NULL:2005/03/21(月) 12:01:49 ID:???
>>388
VIEWの問題は中身が見えなくなること。どれがキーで何がユニークかといった情報を
確認するために、結局VIEWがどう定義されているか調べなくてはならない。
VIEWを利用する開発者が必要に応じてVIEWを作る分には問題ないと思うが、
VIEWを事前に準備しておいて中身を気にせずこれを使え的に提供する方法だと
予想外の使われ方をされてパフォーマンスがでないケースがある。
ブラックボックスするための手段としてVIEWを捉えたら間違いの元だと思う。

393 :387:2005/03/21(月) 18:43:28 ID:EJbK4PSj
たとえば、

SELECT TA.商品番号, TA.単価
FROM テーブルA TA
INNER JOIN テーブルB TA ON TA.商品番号 = TB.商品番号
INNER JOIN テーブルC TC ON TA.コンテナ = TC.コンテナ
WHERE
TA.商品番号 = 'NO998866'
AND TB.商品区分 = '子供服'
AND TC.倉庫番号 IN ('S0001', 'S0002')

こんな感じで、テーブルを3つ繋いで期待した結果が得られないとき
テーブルA,B,Cのどこでヒットしないかわからず、
いちいち、WHERE文を削って調べてるわけです。

#元のSQL文を参考に適当につくったので、SQLがおかしいとか、
#この程度が複雑か?っていうのは無しでお願いします。

実際にはWHERE句がもう少し多いので苦労しているようです。


388さんのVIEW案では、テーブル毎にWHERE句を抜き出して

CREATE VIEW ビューA AS
SELECT * FROM テーブルA
WHERE
TA.商品番号 = 'NO998866'

などでVIEWを作って、最初のSELECTを

SELECT VA.商品番号, VA.商品
FROM ビューA VA
INNER JOIN ビューB VB ON VA.商品番号 = VB.商品番号
INNER JOIN ビューC TC ON VA.コンテナ = VC.コンテナ

にしるということですか?



394 :NAME IS NULL:2005/03/21(月) 19:31:23 ID:3QUKO9Hm
<<393
<<INNER JOINで3つぐらい連結してる程度なのですが、
<<とにかく読みづらいです。

そのSQL文は、普通のSQL文なので、テーブルを3つくっつけて外部結合で
データを取得するためには、そのSQL文しかないと思います><
私なら、order by で検索条件ごとに並べ替えて、どのにデータが入ってないのか
確認し、それに該当するプログラムを修正します。



まじめに、答えたけど一つ確認します。
釣りじゃないよね?派遣社員の人にそのSQLがおかしいとか言わない方が
よいと思うよ。



395 :NAME IS NULL:2005/03/21(月) 19:56:56 ID:SQHNYrQE
すみません。SQL初心者ですが教えていただけないでしょうか。
表の最後に合計を出したいのですがどうしたらいいかわかりません。

SELECT no, name, price
FROM テスト



No   name   price
1    ああ   1000
2    いい   500
3    うう    200

まででるのですが、下記のようにしたいんです。

No   name   price
1    ああ   1000
2    いい   500
3    うう    200
合計        1700

sumをつかえば出来ると思うのですがうまくできません。
どうしたらいいのでしょうか?
もうしわけありませんがよろしくおねがいします。


396 :NAME IS NULL:2005/03/21(月) 20:14:32 ID:???
>>393
テーブルA,B,Cのどこでヒットしないかって?
両手を拍ってパンと鳴った音は右手から出たものか左手から出たものか?

397 :387:2005/03/21(月) 20:28:14 ID:EJbK4PSj
>>394さん
釣りじゃないです。SQL自体がおかしいとは思ってないです。
ただ、もうすこし条件がおおくて、本人が「わからん」といって、
動かない原因を調べるのに2時間も3時間もかかるもんですから。

ユニットテストのレベルでは仰るような方法で調べてるのですが、
初めての現地でのテストで本人もパニクっちゃって。

仕方なしに、トラブるたびに私がSQLを展開して調べてますが、
いちいちそんなことをしないと分からないようなプログラムって
まずいですよね。

動かないときに、なにが悪いかがすぐに分かるようにしたいのです。









398 :387:2005/03/21(月) 20:34:38 ID:EJbK4PSj
>>396さん

WHERE
TA.商品番号 = 'NO998866'
AND TB.商品区分 = '子供服'
AND TC.倉庫番号 IN ('S0001', 'S0002')
のどの条件が成立していないのかがすぐに分からない
と言った方が適切ですか?


399 :NAME IS NULL:2005/03/21(月) 20:35:45 ID:???
>395
SELECT no, name, price
FROM テスト
UNION
SELECT '合計', '', SUM(price)
FROM テスト

こんなんでどうか?

400 :NAME IS NULL:2005/03/21(月) 21:53:09 ID:SQHNYrQE
>>399
ありがとう!!!!

401 :NAME IS NULL:2005/03/21(月) 22:14:54 ID:qXH0y2cD
>>395,400
with rollup とか compute とか処理系依存の方法もあるが。


402 :NAME IS NULL:2005/03/22(火) 00:00:16 ID:NPKK/k+D
質問です。
code1 code2 code3
1111 2222 3333
2222 2222 3333
3333 2222 3333

のようなデータで code2,code3 でジョインすると
3レコードとりますが、1レコードだけほしいとき、どうすればいいでしょうか?
ROWNUM < 2
以外で何かあればお願いします。

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

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)