SQL教えて〜!!

このエントリーをはてなブックマークに追加
952通りすがりの人。:02/07/23 01:05
>>949
ア、ナ〜ルほど。

失礼。失礼。
ミニモミ。でハァハァしてきますわ。
953948:02/07/23 08:33
>>951
>>select a.*
>>from 受注テーブル as a , 受注テーブル as b
>>where a.受注番号 = b.受注番号 and b.商品コード='S001';
>>で正解のはずだ。

受注番号がユニークで無ければダメだな
きっと2件あったら4件でて来てしまうな
>>953
厳密には受注番号だけでなく
受注番号+商品番号でユニークの時に
重複検索されるのだが、
その場合は、distinctを付け加えれば
回避できる。

テーブルt1
C1 C2 C3  C4
10 1 S100 あああ
10 2 S101 いいい
20 2 S100 えええ
20 3 S100 けけけ
30 1 S103 かかか

select distinct a.*
from t1 as a ,t1 as b
where a.c1 = b.c1 and
b.c3 = 'S100'
でお望みの
C1 C2  C3  C4
10 1  S100 あああ
10 2  S101 いいい
20 2  S100 えええ
20 3  S100 けけけ
が検索される。
今、accessとDB2(という鬱DB)
しかないので悪いが、どちらも
確認済。
955954:02/07/23 10:00
s/ユニークの時に/ユニークでなければ
956超弩級初心者:02/07/23 12:15
OracleからPostgresへの移植で詰まってます。

UPDATE TABLE SET SEQ = DECODE(SEQ, 2, 1, 1, 2)
WHERE ID1 = 10 AND ID2 = 100 AND SEQ IN (2,1)

ID1, ID2, SEQがユニークキーに指定されており、上記はOracleにて
SEQの1と2を入れ替えるためのSQLです。

Postgres(7.2.1)用に以下の通り書き換えました。

UPDATE TABLE SET SEQ = (CASE WHEN SEQ=2 THEN 1 WHEN SEQ=1 THEN 2 END)
WHERE ID1 = 10 AND ID2 = 100 AND SEQ IN (2,1)

しかし、「Cannot insert a duplicate key into unique index」とお叱りを受けました。
値が同時に入れ替えられず、「ユニークキーは重複できませんぜ、ダンナ」と言われているような感じです。

これを回避するにはどのようなSQLを書けばいいでしょうか?
私の頭では、SQLを3回に分けるといった非効率なものしか思い浮かびません。
どなたかエレガントなSQLをご教示くださいませ。
SELECT コーン
FROM うんこ
WHERE 食DATE=( CurrentDate( ) - Day(1) )
958デフォルトの名無しさん:02/07/26 23:07
ある抽出条件(条件1)ででてきたレコード群に対し、さらに抽出条件(条件2)を
課すにはどうすればいいですか?

select * from (select * from TBL1 where 条件1) where 条件2

等と言った感じにするのですか?
select * from TBL1
where 条件1 『and』 条件2
Postgresで試したのですけど、トリガーを使用するとき、
ユーザZでTable Aに更新かけられたとき、Table Bを更新するようなトリガーで
Table Bに更新権限がないってエラーになるんですけど、
Table Bに更新権限与えないとだめですか?
そういうもんですか?
Table Bに更新権限与えないでやる方法ないですかね?
961960:02/07/28 02:21
だめかしら?
>>960
postgresは触ったことがないが、
この手の(隠蔽させる)方法として、
直接更新できないテーブルに対して
更新ストアドプロシージャを作成し、
そのストアドプロシージャに
更新させたいユーザに実行権限を
付与することで対応できると思う。
963一緒に考えてくさい:02/07/28 14:51
SQLでBank Of England(方式)で為替の持高を算出したいと思っています。

条件分岐というのでしょうか?大きいほうの値を採用する方法と
from文のサブクエリを二つ平行につかう点が難点かと考えています。

後者くらいはうまくいきそうな気がするんですが、いまのところうまくいってません。
データベースはオラクルです。

具体的には…

データの格納されているテーブル
通貨   数量
USD 1000
EUR 500
EUR -1100
USD -800
USD 200
これを通貨毎・符号毎に集計して
A. select 通貨, sum(数量) from テーブル group by 通貨 having sum(数量)<0
B. select 通貨, sum(数量) from テーブル group by 通貨 having sum(数量)>0

通貨毎に絶対値の大きい符号の側を採用して、それらを合計する
select 最大値( abs( A.sum( 数量)), abs( B.sum( 数量))) from A, B where A.通貨 = b.通貨

ほしい結果は2300

あるファイルのアクセス履歴を取っているんですが、
過去にアクセスがなくその日初めてアクセスがあったユーザーの人数を知りたいんです。

1日 Aさん
2日 Bさん、Cさん
3日 Aさん、Dさん
4日 Aさん、Bさん、Cさん、Dさん

SQL文実行↓

1日 1人
2日 2人
3日 1人
4日 0人

かなり悩んでます。2ヶ月くらい
965デフォルトの名無しさん:02/07/30 20:23
>>964

テーブルをALOGレコードを
DAY MEMBER
1 A
2 B
2 C
3 A
3 D
4 A
4 B
4 C
4 D
だとしたら

SELECT DAY, COUNT(*) FROM
(SELECT MIN(DAY) DAY, MEMBER FROM ALOG GROUP BY MENBER) SALOG
GROUP BY DAY.
でどうかな

>>963
Bank Of England方式ってなに?
サンプルデータ、どこをどう足しても2300にならないのだけど?
966デフォルトの名無しさん:02/07/30 21:09
Ωは?
967デフォルトの名無しさん:02/07/30 23:14
965>>
当初、私もMIN関数を使っていたのですが
データの件数のせいかもしれませんが
すべてのユーザーについて、MIN関数を使うとべらぼうに遅いです。

最小である必要はなく、過去にユーザーデータがあるかどうかをみて
あった時点でそのデータは数えない。

これですべての行を調べなくてもすむんじゃないかと思うのですが、
実際にSQLを書こうとすると、どう書いていいのか分からないのです。
968デフォルトの名無しさん:02/07/31 21:35
このスレまだあったんだ。
2getしようとしてやめた記憶がある。
懐かしい。
これ次スレ立てる必要ある?
こっちに統合しちゃっていいような気がする
http://pc3.2ch.net/test/read.cgi/tech/1020158297/l50
>>967
普通のRDBMSでは「数えない」なんて事が無理な以上、あなたの希望する事は無理。
971デフォルトの名無しさん:02/08/01 00:18
すみません、教えてください!!!
Oracleで、2つのテーブル間の差分更新をしたいと考えています。
具体的には、

テーブルfoo
ID C1 C2  C3
0 あ 111 AAAA
1 い 222 BBBB
2 う 333 CCCC
3 え 444 DDDD

テーブルbar (更新される側)
ID C1 C2  C3  C4
0 あ 111 AAAA あああ
1 い 222 BBBB いいい
2 う 888 CCCC ううう
3 え 999 DDDD えええ
(実際は、片方はDBリンクしているテーブルなので、こんな変な構造
なのです)

とあった場合、それぞれの行でC1,C2,C3を比較して、異なっている行
(例ではID=2,3)の値を、foo側の値で更新したいのです。

よろしくお願いします。
>>967
「ユーザが見つかった時点で処理終了 (次のユーザ処理へ)」 みたいなのは、SQLじゃ無理でないですか?
漏れはそういったSQL記述ができるRDBMS知らないです。 あるのかな?
RPGとかCOBOLなら書けますが、もしかしたら >>965さん のSQLの方が速いかも。
>>971
試してないけど

update bar(bar.ID, bar.C1,bar.C2,bar.C3) values(select foo.ID, foo.C1, foo.C2, foo.C3
                        from foo, bar
                        where foo.ID = bar.ID and
                           (foo.C1 != bar.C1 or
                           foo.C2 != bar.C2 or
                           foo.C3 != bar.C3)) temp
where bar.ID = temp.ID

って、どうだろう?
是非とも結果を希望!
>>976
そーいう時のためにストアドプロシージャという物がある。
OracleならPL/SQL、SQLサバならT-SQL

っていうか、group byで激遅なのはINDEXが
きちんと使えていない証拠。
(または、使えるINDEXが無い)
きちんと実行計画見たか?
RDBは何使ってる?バージョンは?
975971:02/08/01 01:23
>>973
さんくす!
temp以下は思い浮かびませんでした。
今手元に環境がないので、明日早速やってみて
結果書きます。(このスレ残ってるかな?)
976973:02/08/01 01:29
>>975
いくら何でも消えることはありえないだろうて。
「スレッド一覧はこちら」というとこクリックすれば絶対にある。
#実は俺も2chきて数ヶ月知らなかった・・・・(恥
>>972
レス、ありがとうございます。
実はPHPをつかってデータベースと接続しているのですが、
IEの設定により、タイムアウトが5分に設定されています。
5分間レスポンスがないと、「サーバに接続できませんでした」と
表示されるのです。レジストリの変更により、この設定は変えられるのですが、
すべてのPCのレジストリを変更するのも大変だし、
実行するSQLも変動するので、あらかじめ作成しておくこともできません。
出力ページをリフレッシュすることで回避できるかもしれないので、
試してみます。


978971:02/08/01 14:47
できました!!!
update (select foo.C1 foo_C1,foo.C2 foo_C2,foo.C3 foo_C3,
        bar.C1 bar_C1,bar.C2 bar_C2,bar.C3 bar_C3,
        foo.ID foo_ID,bar.ID bar_ID
    from foo,bar
    where foo.ID = bar.ID and
       foo.C1 <> foo.C1 or foo.C2 <> foo.C2 or foo.C3 <> foo.C3 ) temp
   set bar_C1 = foo_C1,bar_C2 = foo_C2,bar_C3 = foo_C3
   where foo_ID = bar_ID;
だと、
『ORA-01779: 複数表にマップする列を変更できません』
でしたが、
UPDATE bar test
   SET (C1,C2,C3) =
     (SELECT C1,C2,C3
      FROM foo
      WHERE ID = test.ID AND
        (C1 <> test.C1 OR
         C2 <> test.C2 OR
         C3 <> test.C3 ))
  WHERE ID IN (
        SELECT foo.ID
        FROM foo,bar
        WHERE foo.ID = bar.ID and
           (foo.C1 <> bar.C1 OR
           foo.C2 <> bar.C2 OR
           foo.C3 <> bar.C3 ));
でうまくいきました。
979973:02/08/03 01:47
>>978
うまくいって、よかったね。
というか、おれはなんというSQL文を書いていたのだろうか。
INSERT文とUPDATE文が混ざってるよ。。。。。
マジ、寝ぼけるのもほどがある。
鬱・・・
980デフォルトの名無しさん:02/08/05 22:55
質問なんですが、

INTO :HAF.共通部.削除不可フラグ,
:HAF.共通部.システム日,
FROM HAFRDB.HAFTBL

という文があるのですが、この「:」は何を意味しているのでしょうか?
また、

WHERE 会社コード = :HAF.キー部.会社コード
AND 業務キー = :H業務キー

なんてのもあります。
参考書やネットで調べてみたのですが、わかりません…
どなたか教えてください。お願いしますm(_ _)m
>>963
よく解らんけど

select sum(数量)
from (
select 通貨,max(abs(数量)) 数量
from tbl
group by 通貨
)

じゃだめ?

>>964
Oracleは

select 日付,count(*)
from tbl a
where
not exists (
select *
from tbl b
where
b.名前 = a.名前 and
b.日付 < a.日付
)
group by 日付

とやった時は数えてないっぽいんだけど、一時表作るのと結合、
どっちが速いかってのは微妙だなぁ。>>965のが速い気がする。

>>978
DBリンク越しに結合すると強烈に遅いことが有るんで、全体に
占める更新対象の割合が小さい時は、絞込みに集合演算子使う
いいかも。
Oracle8です
数値項目で値がNullの場合、自動的にゼロを取得するようにするには
どうしたら良いのでしょうか。
よろしくお願いします。
983デフォルトの名無しさん:02/08/06 12:14
>>969
扱ってる内容が結構差別化されてるから分かれてた方がいいと思う。
というわけで誰か次スレ立てて〜
こっちと統合するんじゃないの?どうせ住み分けできてないし。
データベース Part2
http://pc3.2ch.net/test/read.cgi/tech/1020158297/
>>982
NVL
986982:02/08/06 13:26
>>985 ありがとうございます!
住み分けちゃんとできてるじゃん。たまにスレ違い質問が出るのはどこも一緒だし。
向こうの内容は自分的には必要無いから統合したら読みにくくなりそうだな。
>>987
むしろ製品固有スレにブランチを希望するのだが。
現存するスレ:PostgreSQL, MySQL, Interbase(Firebird), Access
建立してない:Oracle, MSSQLServer(MSDE), DB/2

結局、SQLゆうても標準SQL(ANSI SQL/92か?)に基づいているわけではないし。
製品固有のキツイ方言混じりのSQL文見せられてもなぁ、って想いがあるわけで。

# そもそも、ここは宿題の単発質問スレを成り行きで消化してただけじゃない?
まっ、放っておいてもスレ立てたい人が勝手に立てるでしょ
流れにまかせておけばいいんじゃない?
このスレまだ生きてる?
>>988 を訂正

現存するスレ
ORACLE & SQL Server
http://pc3.2ch.net/test/read.cgi/tech/1008908462/l50

ORACLE
http://pc3.2ch.net/test/read.cgi/tech/1010400855/l50

要するに、それなりに名前を聞くDBで個別スレが無いのはDB2だけだと。
もし次スレをたてるやつがいたら、ここら辺の関連スレの
リンクぐらいは張っておいて欲しいなぁ。
992ペーパープラチナ:02/08/07 01:11
1000間近ですな。
993デフォルトの名無しさん:02/08/07 01:15
100000000000000000000 - 10000000000000000000
994デフォルトの名無しさん:02/08/07 01:15
1000
995デフォルトの名無しさん:02/08/07 01:15
1000
996デフォルトの名無しさん:02/08/07 01:15
1000

997デフォルトの名無しさん:02/08/07 01:16
1000
998デフォルトの名無しさん:02/08/07 01:16
1000
 
999デフォルトの名無しさん:02/08/07 01:16
1000


1000デフォルトの名無しさん:02/08/07 01:17
1000!!!!            
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。