[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 03/07 11:37 / Filesize : 352 KB / Number-of Response : 955
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【帰ってきた】SQL質疑応答スレ 4問目



1 名前:NAME IS NULL [2007/04/14(土) 21:19:55 ID:hWtCYSSP]
参考リンク
sql.main.jp/cont/sql/map.html
www.atmarkit.co.jp/fnetwork/rensai/sql01/sql1.html
oraclesqlpuzzle.hp.infoseek.co.jp/
www.techscore.com/tech/sql/

前スレ:【帰ってきた】SQL質疑応答スレ 3問目
pc11.2ch.net/test/read.cgi/db/1160458216/


2 名前:NAME IS NULL mailto:sage [2007/04/14(土) 21:28:32 ID:???]
で、全スレ>989宛。
995辺りので989〜992の機能は満たしとらんか?
もしくは、意図が掴みかねる993のカキコ内容が要求仕様上重要なん?


3 名前:989 [2007/04/14(土) 22:05:01 ID:vEBJlPWj]
>>2
ああ、そうですね、それは無視してください。



4 名前:989 mailto:sage [2007/04/15(日) 10:59:08 ID:???]
>>995
とりあえず、これで試してみます。
ありがとうございました。

5 名前:NAME IS NULL [2007/04/15(日) 13:04:44 ID:mKPpVVQg]
質問一件お願いします。

以下のような単純なテーブルがあり、
valueの大きい上位3件のレコードを取得したいです。

【テーブルhoge】
name | value
a | 10
b | 30
c | 40
d | 5
e | 2
(以下大量のレコード)

【得たい結果】
c | 40
b | 30
a | 10

現在limitを用いて
select * from hoge order by value desc limit 0, 3;
としているのですが、速度が悲惨に遅いです。

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

6 名前:NAME IS NULL [2007/04/15(日) 19:39:54 ID:8Gbsm4yF]
mysqlについて質問です。
トランザクション可能なテーブルを利用した場合
通常のテーブルパフォーマンスとの差はどれくらいになるのでしょうか?

7 名前:NAME IS NULL [2007/04/15(日) 20:10:18 ID:afmYW8Mb]
MySQL5.0での質問です。

testテーブルに、datetimeとtest_txtというフィールドがあります。
PHPにて、「INSERT test SET datetime='2005/10/10'」を実行すると、
MySQLエラーで「Field 'test_txt' doesn't have a default value」
と返ってきます。
「test_txt」は何も入れないで追加したいのですが、
何か設定の変更などが必要なのでしょうか?
それともいちいち「text=''」のように入れないといけないのでしょうか?

8 名前:7 [2007/04/15(日) 20:14:46 ID:afmYW8Mb]
my.iniの
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
をコメントアウトすることで解決しました。
ですが、これは何を意味しているのでしょうか?

9 名前:NAME IS NULL mailto:sage [2007/04/15(日) 21:10:59 ID:???]
>>7
エラーの内容をきちんと書いて質問するのはよい傾向。

あとはそのエラーをまず、よく読んで見ること。

> Field 'test_txt' doesn't have a default value
⇒ 分野'テスト_txt'には、デフォルト値がありません。

これでもわからないなら、まずデータベースについてもう少し
勉強することを薦める。

10 名前:NAME IS NULL mailto:sage [2007/04/15(日) 21:46:28 ID:???]
MySQLって専用スレないんだな



11 名前:NAME IS NULL mailto:sage [2007/04/15(日) 23:06:14 ID:???]
ttp://pc11.2ch.net/test/read.cgi/db/1164490501/l50
じゃ駄目なん?

12 名前:NAME IS NULL mailto:sage [2007/04/16(月) 16:20:00 ID:???]
col1 col2      col3
 1  2007/04/16 9
 1  2007/04/15 8
 1  2007/04/14 7
 2  2007/04/14 6
 2  2007/04/16 5
 2  2007/04/15 4
 3  2007/04/15 3
 3  2007/01/14 2
 3  2007/04/16 1

主キー(col1,col2)

上のようなテーブルから、col1毎にcol2が一番大きいcol3を得たいのですがSQL書けずに困っています
よろしくお願いします。

13 名前:412 mailto:sage [2007/04/16(月) 16:20:57 ID:???]
書き忘れですが、MySQL4,0xなので副問い合わせが出来ません・・・


14 名前:NAME IS NULL mailto:age [2007/04/16(月) 17:10:32 ID:???]
あげさせてもらいます

15 名前:NAME IS NULL mailto:sage [2007/04/16(月) 20:21:59 ID:???]
SELECT COL3
FROM TABLE
LIMIT 0,1
GROUP BY COL1, COL3
ORDER BY COL2 DESC


16 名前:NAME IS NULL mailto:sage [2007/04/16(月) 22:57:56 ID:???]
質問です。次のような表が二つあります。

表1
コード    コード名   種類名
 1      果物      区分コード
2       野菜      区分コード
10       あり      割引コード
20       なし      割引コード

 
表2
名前      区分コード  割引コード
りんご      1       10
トマト        2        20
きゅうり       2       10
ぶどう       1       20


これを

名前     区分コード  種別   割引 割引有無
りんご     1       果物    10    あり
トマト      2       野菜     20    なし
きゅうり       2     野菜    10    あり
ぶどう      1       果物   20    なし

のような表にしたいのです。
UNIONを用いて式を書きたいのですがうまくいきません。
何か良い方法がないでしょうか?




17 名前:NAME IS NULL mailto:sage [2007/04/16(月) 23:04:04 ID:???]
訂正します

名前     区分コード  種別   割引コード 割引有無
りんご     1       果物      10    あり
トマト      2         野菜     20    なし
きゅうり      2        野菜    10    あり
ぶどう      1         果物   20    なし



18 名前:NAME IS NULL mailto:sage [2007/04/16(月) 23:34:22 ID:???]
>>16
表1を二つに分ける。
既にその糞設計が所与のものならViewを使って別の表に見せかける。

19 名前:NAME IS NULL mailto:sage [2007/04/17(火) 00:18:52 ID:???]
>>16

select 名前,表2.区分コード,区分.コード名 as 種別,表2.割引コード,割引.コード名 as 割引有無
from 表2,
(select コード,コード名
from 表1
where 種類名='区分コード') as 区分,
(select コード,コード名
from 表1
where 種類名='割引コード') as 割引
where 表2.区分コード=区分.区分コード
and 表2.割引コード=割引.割引コード


20 名前:16 mailto:sage [2007/04/17(火) 21:52:34 ID:???]
>>19

ありがとうございました!
おかげで助かりました。



21 名前:NAME IS NULL [2007/04/18(水) 15:33:04 ID:doDz5ry0]
日付、キー、の二つのフィールドがあるテーブルがあります。
キーごとに、過去の日付のレコード件数を取得したいのですが
どのようなSQLを書けばいいでしょうか。

日付      キー
2007/01/01   1
2007/01/01   2
2007/01/02   1
2007/01/03   1



日付      キー    カウント
2007/01/01   1     0
2007/01/01   2     0
2007/01/02   1     1
2007/01/03   1     2


22 名前:NAME IS NULL mailto:sage [2007/04/18(水) 16:10:51 ID:???]
そのカウントはどこから出てきたんだ。

23 名前:NAME IS NULL [2007/04/18(水) 17:50:43 ID:doDz5ry0]
>>22
>キーごとに、過去の日付のレコード件数を取得したいのですが
これです。
4行目のカウント「2」は、キーが1で、
日付が2007/01/03未満のデータの件数(1行目と2行目)を数えています。

24 名前:NAME IS NULL mailto:sage [2007/04/18(水) 18:15:36 ID:???]
SQL Server 2005で質問です。

以下のような「TableA」「TableB」があって
[TableA]
col1 col2 col3
------------------------
01  AAAA 1
02  AAAA 1
03  BBBB 2
04  CCCC 3
05  DDDD 4

[TableB]
col1 col2
-------------
AAAA 1
BBBB 2
CCCC 3
DDDD 4

TableAにだけ存在する行を取得するとき
以下のSQLで取得できますが

select col2 from TableA
except
select col1 from TableB

[結果]
col1 col2
-------------
AAAA 1

この内容からではTableAのcol1が01なのか02なのかが分かりません。
このような場合には差集合は使えませんか。
また差集合を使わない場合、他に良い方法はありますか。


25 名前:NAME IS NULL mailto:sage [2007/04/18(水) 18:38:19 ID:???]
24です。
SQLが間違ってました。

select col2,col3 from TableA
except
select col1,col2 from TableB

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


26 名前:NAME IS NULL mailto:sage [2007/04/18(水) 21:53:21 ID:???]
>>24
01を持って来たいのか02を持って来たいのかはオマエが決めなきゃならん。

27 名前:NAME IS NULL mailto:sage [2007/04/18(水) 22:29:57 ID:???]
文字
a
a
a
b
c
c


文字 個数
a 3
b 1
c 2

とするsql文を教えてください

28 名前:NAME IS NULL mailto:sage [2007/04/18(水) 22:33:58 ID:???]
count
group by

29 名前:NAME IS NULL mailto:sage [2007/04/18(水) 22:44:30 ID:???]
ぐぐったらでてきました
どうもです>>28

30 名前:NAME IS NULL mailto:sage [2007/04/18(水) 23:08:59 ID:???]
>>24
スカラ副問合せが出来るDBMSなら

SELECT A.日付,A.キー
,(SELECT COUNT(*) FROM TBL B
 WHERE B.キー = A.キー
 AND B.日付 < A.日付
) カウント
FROM TBL A
ORDER BY A.日付,A.キー



31 名前:NAME IS NULL mailto:sage [2007/04/18(水) 23:11:44 ID:???]
上は、>>24ではなく、>>21でした。

32 名前:NAME IS NULL mailto:sage [2007/04/19(木) 07:07:17 ID:???]
>>24
select col1,col2,col3
from TableA a
where not exists(
select *
from TableB b
where a.col2=b.col1 and a.col3=b.col2
)


33 名前:21 mailto:sage [2007/04/19(木) 12:48:54 ID:???]
>>30
動きました!!ありがとうございます。

34 名前:NAME IS NULL mailto:sage [2007/04/19(木) 16:25:37 ID:???]
>>33
01  AAAA 1 
02  AAAA 1 
のどっちか一件残すとなると>>.32だと両方消えるのでまずいのだが、
それでよかったのか?

35 名前:NAME IS NULL mailto:??? [2007/04/19(木) 18:00:13 ID:???]
ファンクションとプロシージャはどう使い分けるのですか?
違いがない様な気がして聞きました。

36 名前:NAME IS NULL mailto:sage [2007/04/19(木) 18:08:27 ID:???]
>>35
一般的にファンクションは更新が出来ない。
標準化は進んでないから例外はあると思うけどね。

37 名前:NAME IS NULL [2007/04/19(木) 20:21:08 ID:iuRHnTpA]
>>26
すいません。01、02はどちらが取れても構いません。

>>32
>>34さんも指摘してくれているように
それだと01、02が両方消えるんですよね。

やっぱり、ストアドか何かでコントロールブレイクするしかないですかね。


38 名前:NAME IS NULL mailto:sage [2007/04/19(木) 21:36:49 ID:???]
t1 t2 t3 の3つのテーブルを結合したaとbをそれぞれ作って
select したいんですがうまくいきません

イメージ的にはこんな感じです

select a.name, b.name
+from t1
|  join t2 a
|    on t1.id = a.id_1
|  join t3
|    on a.id_1 = t3.id
+
|  join t2 b
|    on t1.id = b.id_2
|  join t3
+    on b.id_2 = t3.id
where t1.id = 1

よろしくお願いします

39 名前:38 mailto:sage [2007/04/19(木) 22:27:27 ID:???]
血を吐きそうになりながらも自己解決できました〜……
いやーSQLは奥が深い!

よかったら
オススメのSQL(mysql)の参考書・テクニック本とか教えてください

40 名前:NAME IS NULL mailto:sage [2007/04/20(金) 00:12:08 ID:???]
>>39
俺も知りたかったので教えてください



41 名前:38 mailto:sage [2007/04/20(金) 16:02:06 ID:???]
select b.name, d.name
+from t1
| join t2 a
| on t1.id = a.id_1
| join t3 b
| on a.id_1 = b.id
+
| join t2 c
| on t1.id = c.id_2
| join t3 d
+ on c.id_2 = d.id
where t1.id = 1

t1.id = a.id_1 = b.id -> b.name
t1.id = c.id_2 = d.id -> d.name

みたいな感じ?
実際のSQLのほうは結果がだぶったりするんだけど
DISTINCTで無理やり消した みたいな……

まぁなんとか動けば 理解はあとからついてくるし

42 名前:NAME IS NULL mailto:sage [2007/04/20(金) 21:10:41 ID:???]
なるほど、難しい・・・
どうもです>>38

43 名前:NAME IS NULL mailto:sage [2007/04/20(金) 21:59:36 ID:???]
[TableA]
date      col  
------------------------
2007/04/20  10
2007/04/19  20
2007/04/18  30
2007/04/17  40
2007/04/16  50
2007/04/15  60
2007/04/14  70

[TableB]
date      col 移動平均 
------------------------
2007/04/20  10  30
2007/04/19  20  40
2007/04/18  30  50
2007/04/17  40  55
2007/04/16  50  60
2007/04/15  60  65
2007/04/14  70  70

TableAからTableBを作成するSQLを教えてください
dateが自身を含めて4日前までのcolの平均を求めたいです

44 名前:NAME IS NULL mailto:sage [2007/04/20(金) 23:48:07 ID:???]
>>43
SELECT c.data,c.col,SUM(c.col2)/COUNT(*) FROM
(SELECT * FROM (SELECT * FROM tablea)a CROSS JOIN (SELECT data AS data2,col AS col2 FROM tablea)b ORDER BY a.data DESC,b.data2 DESC)c
WHERE c.data >= c.data2 AND c.data2 > c.data - 5
GROUP BY c.data,c.col ORDER BY c.data DESC

dataとcolでキーなの?なんか違和感が・・・。

45 名前:NAME IS NULL mailto:sage [2007/04/21(土) 00:13:27 ID:???]
sqlの問題を自宅のパソコンで勉強したいのですが、
初心者でも分かりやすく勉強できるサイトや無料ソフトは
ないでしょうか?あれば教えてください。よろしくおねがいします。

46 名前:NAME IS NULL mailto:sage [2007/04/21(土) 00:55:38 ID:???]
>>43

SELECT a.date,a.col
,(SELECT AVG(b.col) FROM TableA b
 WHERE b.date BETWEEN a.date - 4 AND a.date
) 移動平均
FROM TableA a
ORDER BY a.date DESC

もしくは

SELECT a.date,a.col,AVG(b.col) 移動平均
FROM TableA a,TableA b
WHERE b.date BETWEEN a.date - 4 AND a.date
GROUP BY a.date,a.col
ORDER BY a.date DESC

47 名前:NAME IS NULL mailto:sage [2007/04/21(土) 01:07:01 ID:???]
>>24
select col1,col2,col3
from TableA
where (col2,col3)in(
select col2,col3
from TableA
minus
select col1,col2
from TableB
)


48 名前:NAME IS NULL mailto:sage [2007/04/21(土) 01:18:42 ID:???]
>>43
select a1.date,a1.col,sum(a2.col)/count(*)
from TableA a1,TableB a2
group by a1.date,a1.col
having a2.date between a1.date-3 and a1.date


49 名前:NAME IS NULL mailto:sage [2007/04/21(土) 12:36:56 ID:???]
学校でSQLの勉強してて自宅でも学習したいけどSQL Serverっていくらぐらいなの?

50 名前:NAME IS NULL mailto:sage [2007/04/21(土) 14:16:02 ID:???]
ただ、のやつもあるだろ。



51 名前:NAME IS NULL mailto:sage [2007/04/21(土) 15:23:46 ID:???]
>>49
Microsoft SQL Server 2005 Developer Edition 日本語版
税抜  6,800円

SQL Server 2005 Enterprise Edition 180日間 限定評価版
www.microsoft.com/japan/sql/downloads/trial-software.mspx
無料

52 名前:43 mailto:sage [2007/04/21(土) 15:24:26 ID:???]
>>44 >>46 >>48

素晴らしいです。皆さんのおかげで無事動きました

>>44
主キーはdateだけですが何か変ですか

53 名前:NAME IS NULL mailto:sage [2007/04/21(土) 22:35:33 ID:???]
>>51
サンクスです
半年も無料で使えるんだ、だったらフリーにすればいいのにね
とりあえず、今のところは無料のソフト入れて勉強したいと思います
サンクスです

54 名前:NAME IS NULL mailto:sage [2007/04/22(日) 00:12:30 ID:???]
まともに運用する時のライセンス代が馬鹿高いから試用期間も長いんだろ

55 名前:NAME IS NULL mailto:sage [2007/04/22(日) 00:39:18 ID:???]
一方ORACLEは無料で期間無制限

56 名前:NAME IS NULL [2007/04/22(日) 03:37:57 ID:p/CIzjLQ]
質問させてください
=の逆は!=ですがlikeの逆は何でしょうか?
!likeだとエラーになりました…

57 名前:NAME IS NULL mailto:sage [2007/04/22(日) 04:11:06 ID:???]
not like

58 名前:NAME IS NULL mailto:sage [2007/04/22(日) 08:47:03 ID:???]
データベースのSQLの勉強初めて疑問があるけど、なんでACCSEとか入力するだけのソフト使わないの?
わざわざ、言語で生成するメリットって自由性?自分の思ったような形にできること?
まだ、初期段階で高度なことはしてないから気づかないだけかもしれないけど

59 名前:NAME IS NULL mailto:sage [2007/04/22(日) 11:17:50 ID:???]
日本語でおk

60 名前:NAME IS NULL mailto:sage [2007/04/22(日) 13:50:40 ID:???]
最初からツールを使うのと、基礎が分かった上で便利なツールを使うのとでは全く違うっしょ。
それに、何らかのプログラムからSQLを叩く時にAccessなんかは使えないし。



61 名前:NAME IS NULL mailto:sage [2007/04/22(日) 13:56:32 ID:???]
>>58の言うACCESSとは、SQL*Plusやmysqlコマンドなんかも含むと予想
んで、「わざわざ、言語で生成する」とは、>>60でいう「何らかのプログラムからSQLを叩く」と予想

という意味でレスすると、SQL"だけ"勉強するのに「わざわざ、言語で生成する」メリットは特に無い

62 名前:60 mailto:sage [2007/04/22(日) 14:25:42 ID:???]
>61
自分は、SQL文の手打ち(コピペでもいいけどさ)のことだと認識した。


63 名前:NAME IS NULL mailto:sage [2007/04/22(日) 22:14:47 ID:???]
>>58
1.データベースの内容をある視点からみたいなー、と思う。
2.必要なSQLが頭に湧く。
3.「頭の中身を吐き出せるプラグが欲しい」と思いながら
 ぺしぺしとテキストエディタへそのSQLを吐き出す。
4.カットアンドペーストでSQL*PlusやらCSEに貼り付けて実行。

・・・大概こんなもんで用が片付くから、わざわざテーブル間の関連付けが
どうとかACCESS使って定義するまでもないからでないかい?
そらユーザーの人に便利につかってもらう為、フォームやらなんやらもいると
なってくると話は違うけども。


64 名前:NAME IS NULL mailto:sage [2007/04/22(日) 23:10:25 ID:???]
> わざわざテーブル間の関連付けがどうとかACCESS使って定義するまでもないからでないかい?

意味わからん。

テーブル間の関連付けがどっかに定義されてるとでも思い込んでるのか?

それても、制約条件のことを勘違いしているのか?

65 名前:5 [2007/04/23(月) 00:24:30 ID:vffmtpA6]
>>5です。

どなたか教えていただけないでしょうか。
ググルにもググリようがありませんし、過去ログはdat落ちして見れません。

お願いします。

66 名前:NAME IS NULL mailto:sage [2007/04/23(月) 02:57:07 ID:???]
>>65
ソート済みのテーブルを別に作って定期的に更新すりゃいんじゃね?
ってSQL初学者が言ってますよ。

67 名前:NAME IS NULL mailto:sage [2007/04/23(月) 04:11:40 ID:???]
>>65
valueに非ユニークな索引をつける。

68 名前:NAME IS NULL mailto:sage [2007/04/23(月) 07:57:05 ID:???]
>>5
DBも書かないような奴はスルーされて当然

とあえて釣られてみる

69 名前:5 [2007/04/23(月) 08:26:36 ID:vffmtpA6]
>>5です。
みなさんありがとうございます。

>>68
すみません、すっかり抜けていましたmysqlの4.12です。

>>66
テーブルを作ってみました。
驚くほど早くなりました!

>>67
インデックスを作ってみました。
こちらも驚くほど早くなりました!

取り急ぎ問題解決しましたが、
なんというか、SQL一発で解決できる問題ではなかったのでしょうか?
みなさんはどんな対処が一般的なのでしょうか。

70 名前:NAME IS NULL mailto:sage [2007/04/23(月) 08:50:27 ID:???]
>>69
つか、パフォーマンスチューニングのためには
何をしなきゃならんのか、もうちょっと勉強汁



71 名前:NAME IS NULL mailto:sage [2007/04/23(月) 09:31:02 ID:???]
>>58
自動でハナクソをほじる機械があれば一見便利そうに思うが
実際は自分の指でほじった方がずっといい。
それと同じ感覚。

72 名前:NAME IS NULL mailto:sage [2007/04/23(月) 18:44:22 ID:???]
>>64
いや、単に普段使うSQLが複数テーブルが絡む物ばかりなもんで、
テーブル1つだけの問い合わせについては失念しとった。
深読みさせてすまん。


73 名前:NAME IS NULL mailto:sage [2007/04/23(月) 21:12:24 ID:???]
>>72
余計意味わからん。

> 単に普段使うSQLが複数テーブルが絡む物ばかりなもんで、

そんな奴が >>64 に書いてることを理解できないわけないと思うが...。

74 名前:NAME IS NULL mailto:sage [2007/04/23(月) 23:18:50 ID:???]
mysqlでランキングカラムを作るにはどうしたらいいですか?


75 名前:NAME IS NULL mailto:sage [2007/04/23(月) 23:52:08 ID:???]
>>73
すまん、そう返されると、そもそもの突っ込み意図が読み取れんとしか
言えん。

元々>>63では「テーブルのJOIN」位の意味合いでテーブル間の関連付けと
書いたんだ。要は複数テーブル使った問い合わせをACCESSで作るにしても、
テーブルやらクエリーやらの画面上の箱(正式名称忘れた)同士の列を線で
結んでやって、その結合一本一本にINNERやらLEFTやらの定義を付与するよな?。

その一連の作業を、ちまちまちまちまマウス操作でやるのは面倒なんじゃっ、
という事を言いたかっただけなんだ...。頭に完成形のSQLがある時は特に。


76 名前:NAME IS NULL mailto:sage [2007/04/24(火) 00:10:42 ID:???]
>>58
Access使うし便利だよ
でもJavaで作ったソフトが売れないと儲からないの

77 名前:NAME IS NULL mailto:sage [2007/04/24(火) 00:12:40 ID:???]
エディタでコピペとかするぐらいなら Access で SQL を直接入力すればいいだけだろ。

> 頭に完成形のSQLがある時は特に。

78 名前:NAME IS NULL mailto:sage [2007/04/24(火) 00:20:54 ID:???]
アクセスで使えるSQLなんてMySQLより制限されてるんだよ

79 名前:NAME IS NULL mailto:sage [2007/04/24(火) 00:44:53 ID:???]
>>77
直接SQL入力していいんなら、そもそもAccess使う意味薄くね?。
SQL内の予約語とか強調表示してくれんし。

というかこれまでの話は、大元>>58

「データベースのSQLの勉強初めて疑問があるけど、なんでACCSEとか入力するだけのソフト使わないの?」

「ツール生成によらないSQLのベタ書きがなんでいるの?」(俺解釈)

の質問に対しての「こんな理由(=うちには後者の方が楽)があるぞ」
レスだしな。


80 名前:NAME IS NULL mailto:sage [2007/04/24(火) 03:15:16 ID:???]
> データベースのSQLの勉強初めて疑問があるけど、なんでACCSEとか入力するだけのソフト使わないの?

Accessの勉強ってならわかるが、SQLの勉強にはなっていないような気がする



81 名前:NAME IS NULL mailto:sage [2007/04/24(火) 09:24:30 ID:???]
>>74
自己結合


82 名前:NAME IS NULL mailto:sage [2007/04/24(火) 09:35:44 ID:???]
>>78
Accessつ〜か、JETの方が
MySQLより柔軟なSQL書けるだろ。


83 名前:NAME IS NULL mailto:sage [2007/04/24(火) 21:55:43 ID:???]
バージョンによるだろ。

つーか、最新版ならどっちでもあまり不自由しないだろ。

84 名前:NAME IS NULL [2007/04/29(日) 15:20:39 ID:GU/EYy4+]

はじめまして。

降順で重複非表示をさせたいのですがうまくいきません。




テーブル test1

ID pref

1 北海道
2 青森
3 福島
4 北海道
5 秋田
6 岩手
7 北海道
8 青森
9 秋田
10 福島


期待する表示は

福島
秋田
青森
北海道
岩手

なんですが。

SELECT distinct pref from test1 order by id desc;
のように
distinctとorder by を使ってみたのですが駄目でした。


SQLで一発で抽出する表記するのは無理があるんでしょうか?




85 名前:NAME IS NULL mailto:sage [2007/04/29(日) 16:01:23 ID:???]
distinctだとそれぞれの県名にどのIDが対応するのか分からないんじゃないの

prefでGROUP BYしてMIN(ID)で降順にするとか

86 名前:NAME IS NULL mailto:sage [2007/04/29(日) 18:04:23 ID:???]
max(id)だろ

87 名前:NAME IS NULL [2007/04/30(月) 00:17:58 ID:LY2aGMZK]
処理系の明記必須はテンプレに含むべきだと感じる今日この頃。

>>84
■汎用
SELECT *
FROM
(
SELECT pref, id
FROM test1
INTERSECT
SELECT pref, MAX(id)
FROM test1
GROUP BY pref
)
AS test2
ORDER BY id DESC

■postgresql限定
SELECT DISTINCT ON (id) id,pref
FROM test1
ORDER BY id DESC

でいけるはず。汎用の方は実行速度が微妙かもだ。


88 名前:NAME IS NULL mailto:sage [2007/04/30(月) 00:24:24 ID:???]
あ゛、postgresql限定がまずい...。
SELECT *
FROM
(
SELECT DISTINCT ON (pref) pref,id
FROM test1
ORDER BY pref,id DESC
)
AS test2
ORDER BY id DESC


89 名前:NAME IS NULL mailto:sage [2007/04/30(月) 00:30:26 ID:???]
つーか汎用も
SELECT *
FROM
(
SELECT pref, MAX(id) AS id
FROM test1
GROUP BY pref
)
AS test2
ORDER BY id DESC
こんなんでいいよなぁ。ごたごた書いてスマン。


90 名前:NAME IS NULL mailto:sage [2007/04/30(月) 01:11:05 ID:???]
出題に回答するスレでもないんでしょ?
いきなり答えまで書いちゃうよりも適当にヒントやるぐらいのがいいんでないの



91 名前:NAME IS NULL mailto:sage [2007/04/30(月) 01:32:30 ID:???]
スタンスもルールも個々人が好きなようにで良いだろ

92 名前:NAME IS NULL [2007/04/30(月) 03:58:25 ID:HNTwEPb8]
これを読み解けと言われたのですが、助けてもらえないでしょうか。

SELECT ITEM_ID, A.ITEM_NAME, A.MAIN_CATEGORY, A.SUB_CATEGORY, A.QUANTITY, A.POINT, A.RANKER
FROM
( SELECT ITEM_ID, A.ITEM_NAME, A.MAIN_CATEGORY, A.SUB_CATEGORY, A.QUANTITY,
A.POINT, RANK()OVER(ORDER BY POINT ASC) AS RANKER
FROM
( SELECT A.ITEM_ID, A.ITEM_NAME, A.MAIN_CATEGORY,
A.SUB_CATEGORY, A.QUANTITY, A.POINT
FROM
( SELECT B.ITEM_ID, B.ITEM_NAME, B.MAIN_CATEGORY, B.SUB_CATEGORY,
A.QUANTITY, C.URIAGE,
TRUNC((SELECT A.QUANTITY / DECODE(C.URIAGE,0,-1,C.URIAGE) FROM DUAL),2) AS POINT
FROM ( SELECT
ITEM_ID, SUM(QUANTITY) AS QUANTITY
FROM ZAIKO_TABLE
GROUP BY ITEM_ID
) A,
STORE_ITEM_MASTER B,
( SELECT A.ITEM_ID AS ITEM_ID, DECODE(B.URIAGE,NULL,0,B.URIAGE) AS URIAGE
FROM
STORE_ITEM_MASTER A
LEFT OUTER JOIN
( SELECT COM_CODE, SUM(SALES_NUM) AS URIAGE
FROM ORDER_TABLE
WHERE SALES_DATE >= (select add_months(sysdate, -1) from dual) AND
SALES_DATE <= SYSDATE
GROUP BY COM_CODE
ORDER BY URIAGE DESC
) B ON A.ITEM_ID = B.COM_CODE
ORDER BY ITEM_ID
) C WHERE B.ITEM_ID = A.ITEM_ID and A.ITEM_ID = C.ITEM_ID
ORDER BY ITEM_ID
) A WHERE A.POINT > 0
) A
) A
WHERE RANKER <= 3

93 名前:NAME IS NULL mailto:sage [2007/04/30(月) 04:33:45 ID:???]
>>89
select pref
from test1
group by pref
order by max(id) desc
/


94 名前:NAME IS NULL mailto:sage [2007/04/30(月) 05:06:53 ID:???]
>>92
>これを読み解けと言われたのですが、助けてもらえないでしょうか。
具体的に何を求めているのかが、見えてこないのですが、
SQL自体は、各テーブル名、カラム名を普通に解釈すると、
在庫数に対する売上げ個数の比率が多い上位3商品の情報を
求めるSQLかと思います。

95 名前:NAME IS NULL mailto:sage [2007/04/30(月) 05:14:10 ID:???]
>>92
とりあえず無駄なorder byがたくさんあるのは読み解いた。
意味があるのはrank() overの部分だけ。
サブクエリを全部Viewにしてみてひとつずつ何やってるか考えてみろ。

96 名前:84です。 [2007/04/30(月) 13:29:07 ID:J6a1E/oV]

みなさん、ありがとうでがんす。
とても勉強になりました。

来週、職場に戻りましたら、早速試したいと思います。


97 名前:NAME IS NULL [2007/05/01(火) 12:25:11 ID:E0G15yAt]
データベースの検索に関して、

A列とB列の値を加算して、その上で、少なくともA列の値が1以上である、
というような条件の下、最大の値をとるような行を求める場合には、
どのようなSQLを発行すればよろしいでしょうか?

よろしくお願いします。

98 名前:NAME IS NULL [2007/05/01(火) 12:29:41 ID:DXF7CsXb]
>>97
何が最大?
A + BがMAXってことかいな?

だとしたら
SELECT MAX(A + B) FROM TABLE1 WHERE A >= 1;
でいいんじゃね?


99 名前:NAME IS NULL mailto:sage [2007/05/01(火) 12:33:27 ID:???]
>>97
なあ、少しは自分で考えたのか?

100 名前:NAME IS NULL mailto:sage [2007/05/01(火) 12:35:24 ID:???]
>>98

返信ありがとうございます。

イメージとしては、

SELECT * FROM TABLE1 WHERE 先頭出現頻度 > 0 AND MAX(先頭出現頻度 + 隣接度)

といった感じで、

name p1 p2
hoge 1 2
hoke 2 4

といったデータがあったとき、 p1 と p2 を加算して最大のもので、
そのうち、少なくとも p1 が 1 以上である行の name を取得したいと考えています。






101 名前:NAME IS NULL mailto:sage [2007/05/01(火) 13:40:28 ID:???]
>>100
前提が既におかしい希ガス。

少なくとも p1 が 1 以上と言っておきながら
WHERE句に「先頭出現頻度 > 0」ってのはおかしいだろ。

WHERE句の額面通りに受け取るなら
「p1 が 0よりおおきい」で無いといけない。
条件の文言が正しいなら
「先頭出現頻度 >= 1」が正しい。

それはともかく、
例えば、SELECT TOP nが使えるなら、
SELECT TOP 1 
  a.NAME,
  MAX(a.P1 + a.P2) as MAXVAL
FROM
  TBL a
WHERE a.P1 >= 1
GROUP BY a.NAME
ORDER BY MAXVAL DESC;

なんてのでも取得可能だと思われ。


102 名前:NAME IS NULL [2007/05/01(火) 20:38:12 ID:E0G15yAt]
>>101

教えていただいたコードを参考に、以下のように SQL を発行しました。
(WordRanking と 俺 は二つの異なるテーブルです)

SELECT TOP 1 WordRanking.AAA, MAX(WordRanking.BBB+俺.CCC) AS MAXVAL
FROM WordRanking INNER JOIN 俺 ON WordRanking.AAA=俺.AAA
WHERE WordRanking.BBB>=1
GROUP BY WordRanking.AAA
ORDER BY MAXVAL DESC;

上記のコードは OleDbCommand によって実行しているのですが、どうにもエラーが発生します。
Access 上では正しく実行されているように感じられるのですが、どこか誤っている箇所がありますでしょうか?


103 名前:NAME IS NULL mailto:sage [2007/05/01(火) 20:51:51 ID:???]
だからさぁ、エラーがでるって言うなら、そのエラーメッセージぐらい書けや、このカス・厨房

104 名前:NAME IS NULL [2007/05/01(火) 20:57:59 ID:E0G15yAt]
>>103

申し訳ありません。
エラーメッセージはデータベースを扱う環境に依存するものであると考えたため、
SQL の構文の正当性の確認には必要が無いと思い、添えておりませんでした。

エラーメッセージ(例外)は以下の通りです。

「1つ以上の必要なパラメータの値が設定されていません。」
(Visual Studio.NET2003, Access2003)


105 名前:NAME IS NULL mailto:sage [2007/05/01(火) 21:53:34 ID:???]
>>104
SQLの構文としてはこれでいいかどうかを確認したい、ってことかい?
Accessで実行したら結果が返ってくるんだから問題はないんだろうな。
エラーメッセージでぐぐるなり、ADO.NETのスレとかで聞くなりしてみては。

で、SQLで個人的に気になることを言わしてもらうと
最大値をとる行が複数ある場合を考慮しなくてもいいのか、ってのと
あと、そのSQLってわざわざGROUP BYする必要あるのか?
こんなんでいいと思うが。

SELECT TOP 1 WITH TIES WordRanking.AAA, (WordRanking.BBB+俺.CCC) AS A
FROM WordRanking INNER JOIN 俺 ON WordRanking.AAA=俺.AAA
WHERE WordRanking.BBB>=1
ORDER BY A DESC;

106 名前:NAME IS NULL mailto:sage [2007/05/01(火) 22:52:23 ID:???]
>>104
俺の薄っぺらい知識で推測するに
>ORDER BY MAXVAL DESC;
を↓に変えろってことじゃないだろうか
ORDER BY MAX(WordRanking.BBB+俺.CCC) DESC;


107 名前:NAME IS NULL mailto:sage [2007/05/02(水) 10:02:48 ID:???]
そいつぁ薄すぎる

108 名前:NAME IS NULL mailto:sage [2007/05/02(水) 10:55:19 ID:???]
>>106
あ、昨日の晩の俺がいる。
便乗質問なんだが、例えばSQLイメージで
SELECT 血液型,count(*) AS 人数
FROM 日本人
GROUP BY 血液型
ORDER BY 人数
という構文(ORDER句に集約値につけた名前を直使用)は
大概のDBへの問い合わせに使えるのだろうか?
(>>104とは関係なく一般的な話として)
いや確かpostgresqlでは駄目だったんだこの構文。


109 名前:NAME IS NULL mailto:sage [2007/05/02(水) 11:00:40 ID:???]
>>108
バージョンいくつ?

110 名前:NAME IS NULL mailto:sage [2007/05/02(水) 12:06:42 ID:???]
>>109
確か7.2.1?(最後の桁が自信無い)
以前そういったことがあったんで、とりあえずGROUPとORDERを
 SELECT * FROM(集約式)AS 結果 ORDER BY 人数
こんな風に分離して逃げた覚えがあるんだ。




111 名前:NAME IS NULL mailto:sage [2007/05/02(水) 12:12:42 ID:???]
7.xは今動作環境ないなあ
8.1.4ではとりあえず、それ使えてます

112 名前:NAME IS NULL mailto:sage [2007/05/02(水) 13:03:51 ID:???]
>>112
お、8.1.4ではいけると。なら俺の知識が古いだけか...。


113 名前:NAME IS NULL mailto:sage [2007/05/02(水) 15:14:18 ID:???]
7.4でもいける。
7.2でも使えてたような気がするんだがなぁ。

114 名前:NAME IS NULL mailto:sage [2007/05/02(水) 15:57:33 ID:???]
7.2以降とそれより前は大きく違うからな、7.1以前ならありうる気がしないでもない

115 名前:NAME IS NULL [2007/05/02(水) 16:15:11 ID:M2WxE7YV]
>>105
>>106

返信、どうもありがとうございます。

>>105 によって示されたコードに
>>106 が示した箇所を修正したところ、見事に動作しました。

とても助かりました。
どうもありがとうございました。

116 名前:NAME IS NULL mailto:sage [2007/05/02(水) 18:03:09 ID:???]
>>108
7.1.2があったから試してみたけど、いけたよ。
order by 2
も試したけど、これもちゃんとソートされた。


117 名前:NAME IS NULL mailto:sage [2007/05/02(水) 19:07:26 ID:???]
>>111 >>113 >>116
なら俺の記憶はなんか別の件をねじまげてしまったんだな。嘘言ってスマン。
連休明けに7.2.1(多分)の開発環境で自分でも試してみるよ。


118 名前:NAME IS NULL mailto:sage [2007/05/02(水) 19:15:59 ID:???]
今日の日付 2007-05-02

SELECT end, start
FROM hyou
WHERE date >= now()
ORDER BY date;

end      start
2007-05-02 0
2007-05-02 0
2007-05-02 0
2007-05-03 0
2007-05-04 2007-04-29 ←
2007-05-07 0
2007-05-08 2007-05-03

これを下のように表示したいのですが、
どうSQLを組めばいいんでしょうか・・?

end      start
2007-05-02 0
2007-05-02 0
2007-05-02 0
2007-05-04 2007-04-29 ←
2007-05-03 0
2007-05-07 0
2007-05-08 2007-05-03

「start」の日付から「end」の日付の間に、今日の日付が含まれていれば
「end列に今日の日付の含まれる行」の次の行に該当するものを表示しようとしています。

119 名前:NAME IS NULL mailto:sage [2007/05/02(水) 20:15:12 ID:???]
すみません、自己解決しました。

IF( end >= now( )
AND start <= now( )
AND start <> '0000-00-00', DATE_FORMAT( now( ) , '%Y-%m-%d' ) , date ) AS bit
ORDER BY bit

120 名前:NAME IS NULL mailto:sage [2007/05/02(水) 20:22:18 ID:???]
失礼・・・「"end列に今日の日付の含まれる行"の次の行に該当するものを表示」が出来ないorz



121 名前:NAME IS NULL mailto:sage [2007/05/02(水) 20:28:54 ID:???]
>>120
order by bit,end,start
ってすればいいんじゃにか?

122 名前:NAME IS NULL mailto:sage [2007/05/02(水) 21:06:56 ID:???]
>>121
なるほど。。ORDER BYで複数指定した際の考え方がいまいち分かっていませんでしたorz
その構文で期待通りの表が得られました。ありがとうございます。

123 名前:NAME IS NULL [2007/05/08(火) 00:52:25 ID:YXJfMvSq]
sqlについての質問です。

Aテーブル
no | date
a | 2007/10/11
b | 2006/2/3
c | 2006/4/2

Bテーブル
no | date | value
a | 2004/10/3 | 24
b | 2005/2/1 | 30
c | 2008/10/11 | 13

のようなテーブルがある時、AとBのテーブルをleftjoinでnoをキーにして結合、
そして、AとBの同じnoでもdateの値が大きい方を取得、最後にその値でソートをかけたいのですが、
どのようなsqlを発行すればいいでしょうか?

欲しい結果
no | date | value
c | 2008/10/11 | 13
a | 2007/10/11 | 24
b | 2006/2/3 | 30






124 名前:NAME IS NULL mailto:sage [2007/05/08(火) 02:59:26 ID:???]
>>123
SELECT no,CASE WHEN A.date>B.date THEN A.date ELSE B.date END AS date,B.value
FROM A LEFT JOIN B USING(no) ORDER BY date;

125 名前:NAME IS NULL mailto:sage [2007/05/08(火) 13:54:02 ID:???]
すんまそん。。

正規化して外部キーが沢山あるテーブルAにinsertする場合、
各情報をそれぞれの各テーブルにinsertしていき、そのidをテーブルAに外部キーとして
記録する、とゆー以外に

なにか特殊なステートメントとかで、テーブルAに対するSQL一発で、全部済んじゃう
なんていう虫のいい方法ってあるのでそうか。。

よろしくおながいします。m(_ _)m

126 名前:NAME IS NULL mailto:sage [2007/05/08(火) 14:59:14 ID:???]
ストアド

127 名前:125 mailto:sage [2007/05/08(火) 16:05:56 ID:???]
>>126

>ある表 (テーブル) の内容を編集して別の表に格納する大量データの更新処理などを
>データベースエンジン内部で処理プログラムを実行し、入出力 (I/O) のほとんどを
>データベース内部で完結することにより、クライアント側とのデータ通信による
>オーバヘッドを削減することでバッチ処理性能を向上させる「ストアドプロシージャ」が考え出された。
ttp://ja.wikipedia.org/wiki/SQL

定型処理を登録しておくっていう感じでしょうか。これなら出来そうですね。
でも、、、、SQLiteを使う予定なので、非対応でした。。orz

一応やりようはあるってことが分かってスッキリしますた。
どうもありがとーでしたー。

128 名前:NAME IS NULL mailto:sage [2007/05/08(火) 17:12:12 ID:???]
状況がよくわからないんだけど、トリガじゃだめなの?

129 名前:NAME IS NULL mailto:sage [2007/05/08(火) 17:14:35 ID:???]
トリガでストアドを実行することになるだろうね

130 名前:NAME IS NULL mailto:sage [2007/05/08(火) 17:19:05 ID:???]
ってSQLiteの話か。
DELETEやUPDATEのカスケードはできるだろうけど、INSERTはどうなる?



131 名前:123 mailto:sage [2007/05/08(火) 18:53:56 ID:???]
>>124
できました。
ありがとうございますた。

132 名前:NAME IS NULL mailto:sage [2007/05/10(木) 08:44:19 ID:???]
TIMESTAMP型の質問ですが、TIMESTAMP型に対して演算を行うと、表示するとき時間が表示されなくなってしまいます。
何故このように表示されるのか、解説をお願い致します。

SELECT
   SYSTIMESTAMP AS A
    SYSTIMESTAMP - 1/1440 AS B
FROM
   DUAL;


以下、実行結果

A
--------------
2007/05/10 08:33:05.385

B
--------------
2007/05/10

133 名前:NAME IS NULL mailto:sage [2007/05/10(木) 09:39:19 ID:???]
>>132
DUALを使ってるからOracleのtimestamp型かな?
計算結果がDATE型に化けてる感じだね。
TO_CHARで時分秒まで書式指定してみては。

134 名前:NAME IS NULL mailto:sage [2007/05/10(木) 09:42:20 ID:???]
>>133
ありがとうございます。
試してみます。

135 名前:NAME IS NULL mailto:sage [2007/05/10(木) 09:53:41 ID:???]
>>134
その問い合わせでVIEWを作ってみると
AはTIMESTAMP型になるが、BはDATE型になる。
>>133の回答が正しいと思われ。


136 名前:133 mailto:sage [2007/05/10(木) 12:42:06 ID:???]
>>133
>>135
試してみました。
DATA型になっているようです。
TIMESTAMP型のまま計算はできないのでしょうか?

SELECT
  to_char(SYSTIMESTAMP - 1/1440,'yyyy-mm-dd hh24:mi:ss:ff'),
FROM
  DUAL;

行2でエラーが発生しました。:
ORA-01821: date format not recognized

137 名前:NAME IS NULL mailto:sage [2007/05/10(木) 13:01:34 ID:???]
>>136
DATE型に対してミリ秒まで書式指定してるからでないの?

SELECT
 SYSTIMESTAMP AS A,
 TO_CHAR(SYSTIMESTAMP - 1/1440,'YYYY/MM/DD HH24:MI:SS') AS B
FROM DUAL;
ならエラーでないし。

どうしてもTIMESTAMP型にしたいなら
SELECT
 SYSTIMESTAMP AS A,
 TO_TIMESTAMP_TZ(TO_CHAR(SYSTIMESTAMP - 1/1440,'YYYY/MM/DD HH24:MI:SS'),'YYYY/MM/DD HH24:MI:SS') AS B
FROM DUAL;
みたいにしなきゃならんと思われ。


138 名前:133 mailto:sage [2007/05/10(木) 13:34:58 ID:???]
>>137
たぶんそれです。
ありがとうございます。
早速試してみます。

139 名前:NAME IS NULL mailto:sage [2007/05/10(木) 14:51:42 ID:???]
ワキガ…それは、科学技術が発達した現代において、未だ解決手段を
      見出せない不治の病…

ワキガ…それは、人と人を分かつ人種差別の根源。ワキガこそが
     人々を争わせ、血と涙を流させる…

ワキガ…それは、夢ある若者を絶望させ、悪心を植えつける悪の源泉

ワキガ…それは、悪徳業者の儲け口。悪をのさばらせる恰好のエデン

ワキガは全てを破壊し、再生を妨害する。ワキガがある限り、この世は平和にならない。
こんにちまで、私達人間はワキガに対する対抗手段を持ち得なかった。
だが、2007年の五月。ついにワキガを撲滅するための手段が見つかった!
その名は「軽石療法」
軽石でワキを擦ることで、ワキガは消滅するのだ!なんと単純な治療法だろうか。
しかし疑ってはいけない。相対性理論も画期的だがシンプルだったではないか。
そう、画期的なものはシンプルなのだ。シンプルでなければいけないのだ。
つまり軽石療法こそが、ワキガを消滅させるための唯一の方法なのだ。

軽石療法について詳しく知りたければいますぐここへ行くことをお勧めする。
※わきが※ワキ擦り治療法※腋臭※
life8.2ch.net/test/read.cgi/diet/1172992888/

君の人生に明るい光がさすことを約束しよう。さあ来たれ悩める民たちよ。


140 名前:nobodyさん [2007/05/10(木) 17:36:02 ID:7Nf664PD]
欠番を埋めるSQLを作成しています。
テーブル名 TEST_TB

C_ID C_NAME
C00001 A
C00002 B
C00004 D
C00005 E
C00006 F

C00003を取得するSQLが書けません。
ご教授よろしくお願いいたします。



141 名前:NAME IS NULL mailto:sage [2007/05/10(木) 17:56:47 ID:???]
>>140
C_IDの桁数は6桁固定で後ろ5桁が数字でOK?

しかし1桁目が文字でゼロ詰めされてるから、
文字列操作がめんどくさいなwww

select MIN(to_number(SUBSTR(C_ID,2)) + 1) AS TARGET from TEST_TB
WHERE (to_number(SUBSTR(C_ID,2)) + 1) NOT IN (select to_number(SUBSTR(C_ID,2)) from TEST_TB)

Oracleならこれで3が戻るはずから、
戻り値をC00003にするようガンガレwww


142 名前:NAME IS NULL mailto:sage [2007/05/10(木) 21:28:29 ID:???]
Webサービス(PHP)で使うユーザとグループをSQLで管理しようと考えています。
ユーザが複数のグループに所属できるようにしたいのですが、
ユーザとグループそれぞれのテーブルの良い関連づけの仕方が思いつきません。

・ユーザのテーブルに所属グループを記す配列を付ける
・グループのテーブルに所属メンバーを記す配列を付ける
初めは以上の2通りのやり方を考えたのですが、SQLには配列が無いことに気付きました。

配列を実現するために、ユーザ(あるいはグループ)ごとに配列の代わりになるテーブルを作成するか、
カンマ区切りの数値を文字列として保存して配列のように使うか、
今はその二つの方法だけが思いつき、どちらが最適か悩んでいます。

SQLでの一般的な実現方法がありましたら、ご教授願います。

143 名前:NAME IS NULL mailto:sage [2007/05/10(木) 22:47:08 ID:???]
>>142
ユーザー表、グループ表、ユーザー・グループ対照表

144 名前:nobodyさん [2007/05/11(金) 10:19:09 ID:5xTIeHlP]
>>141
ありがとうございました。
ただ、mysqlだったのでto_numberは使えませんでした。

145 名前:NAME IS NULL mailto:sage [2007/05/11(金) 10:23:05 ID:???]
>>144
だったら最初からRDBMS名を挙げとけwww

MySQL4.1のリファレンス見ると
CASTかCONVERTが存在するから、それ使え。


146 名前:NAME IS NULL mailto:sage [2007/05/11(金) 10:23:43 ID:???]
>>144
あと、SUBSTRは、SUBSTRINGな。

147 名前:NAME IS NULL mailto:sage [2007/05/11(金) 15:27:23 ID:???]
お舞ら一般的な考え方を教えてください。
あるテーブルにUINTのフィールドがあったとします。
それはテーブルでユニークではなく、同じ値を複数のレコードがもちえるとします。

ここである操作に対して新しいレコードを作製しそのフィールドにそれまで使われてない値をいれたいんですが、この使われてない値を高速に持ってくる方法ってあるんでしょうか?

インクリメントしていってもいいんですが、レコードが削除されて使われなくなった値とか出てきます。その値も無駄にすることなく使いたいのです。
ひとつ考えたのはインクリメントしていって上限までいったら歯抜けをつめなおして関連テーブルの値を更新するものです。
もしも使われてない値を高速に持ってくることができるならそうした処理をする必要がないので、何か手段があれば教えてくださいエロイ人(´・ω・`)

148 名前:NAME IS NULL mailto:sage [2007/05/11(金) 15:42:13 ID:???]
>>147
UNSIGNED INTなら、
www.yel.m-net.ne.jp/~oss/Tips/ADO/Tips_11003.htm
をまんまパクればいいと思うが?

SELECT MIN(UINTの列名+1) AS 欠番 FROM テーブル
   WHERE UINTの列名+1 NOT IN (SELECT UINTの列名 FROM テーブル)

で取れるんじゃね?


149 名前:NAME IS NULL mailto:sage [2007/05/11(金) 18:14:51 ID:???]
さんくすです。パフォーマンス見て検討してみます。

150 名前:NAME IS NULL mailto:sage [2007/05/11(金) 19:49:42 ID:???]
UINTって約43億?
設計上INSERTとDELETEが非常に多く繰り返されてしまうのかもしれないけど、
それでも実レコードが数百万とか数千万にまで膨れ上がると、
>>148では遅くなるだろうな。(ハードも含めたシステムによるけど)

DBによるが、NOT IN より NOT EXISTSで相関クエリにした方が速そう。
でも結局、1度はテーブル全て読み込むことになってしまう。

ULONGを使うと事実上インクリメントしても一巡することはありえねぇーってなら
その方が速いんじゃね。



151 名前:NAME IS NULL [2007/05/11(金) 23:54:19 ID:m7WrnMvu]
DESC って何の略?ORDER BYで使うDESC。

152 名前:NAME IS NULL [2007/05/12(土) 00:34:43 ID:o1KON6CY]
descend

153 名前:NAME IS NULL mailto:sage [2007/05/12(土) 01:15:06 ID:???]
>>142
俺もあるシステム作ったときに同じようなことで迷った

結局、「ユーザーとグループの対照テーブル」に
「ユーザー列」+「所属するグループのキー」をカンマ区切りの文字列で格納して
JSPで分割しながら判定するようにしたけど、遅いし、無数に増えるグループだといつかカラムの容量超えるしで
結局所属できるグループ数と全体の最大グループ量に制限設けるしかなかったんだよな

よくありそうな話だし、DB設計者なら何かもっとよいDB設計がでてくるのかもね

154 名前:NAME IS NULL mailto:sage [2007/05/12(土) 02:20:53 ID:???]
「ユーザーとグループの対照テーブル」に
ユーザーID, グループIDを追加していくだけじゃダメなんですか?

155 名前:NAME IS NULL mailto:sage [2007/05/12(土) 09:21:13 ID:???]
>>153
俺も、最初 DB 使い始めの頃は同じような考え方してたよ。

一般的な正解は >>143, >>154 の言う通りで

[ユーザ表]
id
名前
...

[グループ表]
id
名前
...

[ユーザ・グループ対照表]
ユーザid
グループid

のようにして、ユーザをグループに所属させる時は [ユーザ・グループ対照表] に
ユーザid と グループid の対を挿入していく。

ある名前のユーザが所属するグループ名一覧が欲しい時は、

SELECT "ユーザ表"."名前", "グループ表"."名前"
FROM "ユーザ・グループ対照表", "グループ表", "ユーザ表"
WHERE ( "ユーザ・グループ対照表"."グループid" = "グループ表"."id"
AND "ユーザ・グループ対照表"."ユーザid" = "ユーザ表"."id" )
AND ( ( "ユーザ表"."名前" = 'いいいい' ) )

のようにする。(OpenOffice.org の Base の例)

三つものテーブルにアクセスしないといけないし、[ユーザ・グループ対照表] は
結構行数も大きくなるので、なんか非効率な感じがするけど、インデックスとか
ちゃんと設定しておけば大丈夫。

凄くよくある話だし、データベースの基本だから「データベース 正規化」とかで
ぐぐって色々見てみるといい。わかってみるとそんなに難しい概念じゃないよ。

156 名前:NAME IS NULL mailto:sage [2007/05/12(土) 15:52:24 ID:???]
なるほど、そういうことか
何か意味もなく「ユーザ・グループ対照表」のユーザーIDもしくはグループIDを一意にしないとって考えにとらわれてた

DB周りはあまり触らないのだけど、スッキリしたし勉強になったよ。ありがとう

157 名前:NAME IS NULL [2007/05/13(日) 11:18:16 ID:CvhZCYzt]
質問です。
データベースをとある条件で検索した多量の結果のうち、
項目の範囲を指定して、その範囲内だけのデータを取得するにはどうすれば良いのでしょうか?
例を挙げると、検索系のシステムで、最初の20件・・次の20件・・最後の20件、というアレです。

よくありそうな処理ですが、これの解説をされているサイト等、私には見つけることが出来ませんでした。
くだらない質問かもしれませんが、ご存知の方いらっしゃいましたらご教授くださいませ。

158 名前:NAME IS NULL mailto:sage [2007/05/13(日) 11:20:40 ID:???]
MySQL ならLimit SQLServerだったらTOP(だったか?) etc

159 名前:NAME IS NULL mailto:sage [2007/05/13(日) 11:21:18 ID:???]
>>157
limit offset構文が使えるなら、それで。
使えないなら別の方法でwww

多分にRDBMSの方言が出てくるから、
手前の使ってるDB名晒せ。


160 名前:NAME IS NULL [2007/05/13(日) 11:42:43 ID:rmiwhMVe]
Oracleで重いUPDATEをいくつか書いたスクリプトを流そうと考えています。

UPDATE tbl1 set a=1;
UPDATE tbl1 set b=2;

Object Browserかsql/plusで流す予定ですが、途中経過を出力させたいのです。
例) "UPDATE tbl1が終了しました"
どのようなSQLを書けば宜しいでしょうか?教えて下さい。



161 名前:NAME IS NULL mailto:sage [2007/05/13(日) 11:54:01 ID:???]
dbms_output使っても経過情報を
リアルタイムには出力できなかったと思うので、
SQLを実行するスクリプト側で1本目のSQL終了時に
標準出力にECHOさせるようにするしかない。



162 名前:NAME IS NULL mailto:sage [2007/05/13(日) 11:54:21 ID:???]
スクリプトの中に外部プロシージャー呼び出せばいいのでは。

163 名前:NAME IS NULL mailto:sage [2007/05/13(日) 11:58:16 ID:???]
>>158-159
標準のSQLではなく、データベースサーバによる拡張的に存在していたのですね!
使用しているのはMySQLなので、Limitを使ってみたいと思います。
これは非常に為になりました。どうもありがとうございました!

164 名前:160 [2007/05/13(日) 11:59:43 ID:rmiwhMVe]
更新情報をリアルタイム出力する必要はないです。
1個目のSQLが終わって2個目のSQLが開始されたことだけわかればOK。
ずっと放置して固まっていたというのが怖い。

>>161>>162
それを調べるのにキーワードとなる単語はありますか?
もう少し詳しく教えて頂けると助かります。

165 名前:NAME IS NULL mailto:sage [2007/05/13(日) 12:04:25 ID:???]
>>164
「Oracle EXTPROC」
とか
「Oracle 外部プロシージャ」
とかだろうなwww

標準出力にECHOするだけの外部プロシージャなら、
CでもJavaでも簡単に書けるし。


>>162
外部プロシージャでECHOさせる発送はなかったわ、俺。


166 名前:160 [2007/05/13(日) 14:06:49 ID:rmiwhMVe]
何とかなりそうです。ありがとう。

167 名前:162 mailto:sage [2007/05/13(日) 18:35:24 ID:???]
>>165
ちなみにDB2/400とかだと経過情報をリアルタイムに見れるな。

普通(?)のDB2UDBがソレっぽい事できなくて驚いたので、
ちょろっと悩んだ時期があった。

最近は前もって「5分くらいかかるから気にスンナ」ってメッセージ最初に
出すようにしたけどな。w

168 名前:NAME IS NULL [2007/05/14(月) 15:46:02 ID:o9PHUJbI]
次のように社員番号と枝番で一意であるが、枝番がNullを許容する場合、
社員番号と枝番で一意であることをどのように示すのでしょうか?
主キーはなしで、社員番号と枝番を複合して、
ユニーク制約(ユニークインデックス)とすべきでしょうか?

社員番号  枝番
123  1
123  2
123  Null

169 名前:NAME IS NULL mailto:sage [2007/05/14(月) 15:49:37 ID:???]
>>168
枝番にNULLが来るなら
UNIQUE制約しかないと思うよ。


170 名前:NAME IS NULL mailto:sage [2007/05/14(月) 16:04:54 ID:???]
枝番0を新設するほうが簡単な気がする



171 名前:NAME IS NULL mailto:sage [2007/05/14(月) 22:02:25 ID:???]
俺もそう思う。

172 名前:NAME IS NULL mailto:sage [2007/05/14(月) 22:29:41 ID:???]
>>168
ふつう、nullにuniqueは効かないから(123,null)が複数エントリできてしまうよ。
MS-SQLServerは違うみたいだけど。

173 名前:NAME IS NULL mailto:sage [2007/05/15(火) 13:07:51 ID:???]
a_tb (
date,
b_id
)

b_tb (
id,
url
)

とゆー二つのテーブルから、b_id同士をつなげて、重複しない最新の5件のurlを表示したいのです。そこで...

select DISTINCT date(a_tb.date), b_tb.url FROM a_tb, b_tb
WHERE a_tb.b_id = b_tb.id ORDER BY a_tb.date DESC LIMIT 5;

としたのですが、重複排除の集約方向が、dateの古いレコードの方に集約されてしまって、こまっています。。

つまり、a_tbに

2007-5-15 13:05:00, 5
2007-5-15 10:05:00, 5

とあると、下のレコードに集約されてしまって、上のレコードがあることが、
最新の5件の中に含まれないのです。。orz

お知恵を拝借したいです。。よろしくおながいします。

174 名前:NAME IS NULL mailto:sage [2007/05/15(火) 14:59:41 ID:???]
>>173
>date(a_tb.date)
どのDBMSを使っているか知らないが、
date() というのが時分秒を切り捨てる関数なんじゃないのかい?

175 名前:NAME IS NULL mailto:sage [2007/05/15(火) 15:48:09 ID:???]
>>174
>どのDBMSを使っているか知らないが、
スマソ。SQLite 3でつ。

>date()というのが時分秒を切り捨てる関数なんじゃないのかい?
yes。日付だけになるので、同じ日の同じURLの重複を排除すると言う感じになっておりますです。
そうしないと分秒が影響して、DISTINCTする意味が無くなってしまう気がするので。。

もしかして、、、ORDER BYで時間含めてソートしていても、
DISTINCTで日付だけでソートされた時に、ORDER BYのソートは全く関係なくなってしまうのでしょうか?
そんな気がしてきました。。

とすると、最新の5件に重複するURLが含まれないようにするには、SQLだけでは難しいのかな。。むー

もうちょと考えてきます。どうもありがとうございましたー。

176 名前:NAME IS NULL mailto:sage [2007/05/15(火) 17:19:09 ID:???]
SELECT DATE(a_tb.date), b_tb.url FROM a_tb, b_tb
WHERE a_tb.b_id = b_tb.id GROUP BY DATE(a_tb.date)
ORDER BY 1 DESC

こんなんじゃだめか?実行すらしていないが。
これじゃダメならサブクエリ使うといい

177 名前:176 mailto:sage [2007/05/15(火) 17:19:50 ID:???]
ごめ、忘れてくれ

178 名前:147 mailto:sage [2007/05/15(火) 18:09:58 ID:???]
たびたびすいません。
またIDのつけ方で悩んでるのですが、次のような方法はありですか?
UINTなどをIDとする。
IDはオートもしくは手動でインクリメントさせる。
IDが上限まできたら、すでに削除されたレコードがあるとして0から連番になるように更新する。その際関連するテーブルのID値も更新する。
つめた後のIDの最大値+1を次のIDのシードとする。



・・・こんな処理が必要なのか?だんだん疑問になってきた。皆さんID値ってどうされてるんでしょう?

179 名前:NAME IS NULL mailto:sage [2007/05/15(火) 20:07:24 ID:???]
>>178
普通にシーケンスつかって取得してるけどwww


180 名前:NAME IS NULL mailto:sage [2007/05/15(火) 23:46:12 ID:???]
>>178
> IDが上限まできたら

普通は、来ないようにする。

どの DBMS 使ってるのか知らんけど、最近の奴なら ID を 64bit にできるから、
よほど特殊なデータでない限りラップしたりしない。



181 名前:NAME IS NULL mailto:sage [2007/05/16(水) 07:08:42 ID:???]
>>178
32bitのIDを使い切る場合は、
1秒に10 IDずつ新規IDを発行すれば1日864000 IDで13年半ほどもつ。
64bit使い切ろうと思ったら、
1日4294967295(32bit相当分) IDを消費するために1秒49710 ID程度の新規発行が必要で
これでも11734883年ほどもつ。

まあなんだ頑張れ・・


182 名前:NAME IS NULL [2007/05/16(水) 16:40:18 ID:shmAdjsQ]
tbl_area
*************
area_id
-------------


tbl_shop_area
*************
area_id(FK)
shop_id(FK)
-------------

tbl_shop
*************
shop_id
-------------

という主キーを持つ三つのテーブルがあってもうすでにある程度DATAが入ってます。
shopテーブルが持つエリアの数は1つなので、tbl_shopにarea_idカラムを作って
tbl_shop_areaから対応するshop_idを持つarea_idを、そのカラムに流し込みたいのですがどうすればよいのでしょうか?

ALTER TABLE tbl_shop ADD COLUMN area_id INTEGER;
ALTER TABLE tbl_shop ADD FOREIGN KEY(area_id) REFERENCES tbl_area (area_id) ON UPDATE CASCADE ON DELETE SET NULL;
とカラムは作ったのですが、流し込むところで躓いてます。

UPDATE tbl_shop SET tbl_shop.area_id = tbl_shop_area.area_id WHERE tbl_shop.shop_id = (SELECT tbl_shop_area.shop_id FROM tbl_shop_are);
とやってみたのですが
ERROR: missing FROM-clause entry for table "tbl_shop_area"
といわれたので
UPDATE tbl_shop SET tbl_shop.area_id = tbl_shop_area.area_id FROM tbl_shop_area WHERE tbl_shop.shop_id = (SELECT tbl_shop_area.shop_id FROM tbl_shop_are);
とかしてみましたけど根本的にちがうっぽくてうまくいきません。

複数行のUPDATEはできないのでしょうか?
なんかスクリプト使わないと無理なのかな?

SQLでいける書き方あったらお願いいたします。


183 名前:182 mailto:sage [2007/05/16(水) 16:41:32 ID:???]
ちなみにpostgreSQL8.1.8です

184 名前:182 mailto:sage [2007/05/16(水) 16:59:25 ID:???]
UPDATE t_shop SET area_no = (SELECT area_no FROM t_rel_shop_area WHERE t_shop.shop_no = t_rel_shop_area.shop_no);
でできました。(微妙にカラム名違うけど気にしないでください)

お騒がせしました。

185 名前:NAME IS NULL [2007/05/17(木) 10:48:10 ID:EjOsYkVC]
おせわになってます
timestampが保存されているカラムから現在までの時間を取得したいのですが
age(add_date)
を使うと、例えば
3 mons 24 days 10:00:01.22559
という型で帰ってきてしまって、PHPなどで使うときに
"3 mons 24 days 10:00:01.22559"というテキストになって
計算に使うのが面倒なのですが、
秒数や何日、見たいな形で取得することはできないのでしょうか?

お願いいたします。


186 名前:185 [2007/05/17(木) 10:50:07 ID:EjOsYkVC]
DBの種類書くの忘れました
postgresqlです。

187 名前:NAME IS NULL mailto:sage [2007/05/17(木) 12:14:51 ID:???]
varcharの長さを短くしておくメリットって( ´Д`)なにか?あるんでしょうか?
なければすべてvarchar(Max)とかしておけばいいのかと思ったのですが

188 名前:NAME IS NULL mailto:sage [2007/05/17(木) 12:35:23 ID:???]
>>185
extract(epoch from age(d))
とかでどうかなあ。
この辺よく変わるからバージョンによるかも。

189 名前:NAME IS NULL mailto:sage [2007/05/17(木) 15:26:41 ID:???]
>>187
その長さ以上の文字列が入っちゃだめなときとか。。

190 名前:NAME IS NULL mailto:sage [2007/05/17(木) 15:48:36 ID:???]
>>189 そういう制限ないときはMaxでいいとですか?



191 名前:NAME IS NULL mailto:sage [2007/05/17(木) 17:44:34 ID:???]
>>190
DBMSによるかのう。
無制限の可変長文字列はラージオブジェクト扱いだったりでいろいろ制限があるものが多い。
varchar(max)とか言ってるからMSSQL2005かな?
旧バージョンのtext型と違い制限は少なくなってるけどまだ何かあったはず。


192 名前:NAME IS NULL mailto:sage [2007/05/17(木) 17:49:13 ID:???]
>>191 
いわれてるとおりMSSQL2005です。
なるほど。あえて8000文字までとMaxで分けてるからには実装で違いありそうですね。
通常のvarcharのサイズの長短でも影響あるのか調べて見ます。

193 名前:NAME IS NULL [2007/05/17(木) 19:37:37 ID:wTPpdrT0]
oracleで日本語の半角、全角を区別しないで検索する方法ってありますか?

194 名前:NAME IS NULL mailto:sage [2007/05/17(木) 20:27:31 ID:???]
>>187
ストアドプロシージャやユーザ定義関数内でvarchar(max)な変数が
使えなかった気がする。

なので、そういうので値いじろうとすると面倒になる。


195 名前:NAME IS NULL mailto:sage [2007/05/19(土) 21:45:20 ID:???]
【女性客拉致・強姦】 被害女性「男が4人ほどいた」と証言…ステーキ店「ペッパーランチ」店長・店員の他に共犯者か★35
news22.2ch.net/test/read.cgi/newsplus/1179576460/

ペッパーランチという大手ステーキ屋の店長達が、食事中の女性客を店内で拉致・レイプした。
店の制服・名札を着けたまま犯行に及んでいることから、レイプ後に被害者を殺す予定だった可能性が高い。
ところが報道はほとんどされず、インサイダー取引の可能性大。
同社の隠蔽工作、google対策等怪しいが、一週間経っても新情報無し。

31スレ消化 = 3万1000カキコ
関連スレレス数おおよそ 1万
ロムが これの5倍にあたる15万人?
約20万人のネラーが興味を示してます。

2chからの現段階での波及効果
○アマゾンにて一瀬邦夫社長の著者本の評に罵詈雑言
○ミクシーなどでペッパーランチアルバイトがまさかの暴言。これに対して総攻撃
○wikiのペッパーランチが書き換え合戦によりほぼ機能停止
○ペッパーフードサービスHPがポートを意図的に閉鎖
○携帯チェーンメール展開中
○ペッパーランチはてなダイアリーにて「女性客が一人で食べに行くと、逆に店員に食べられてしまうという」記載
○Yahoo グルメ、株式掲示板にてペッパーランチ炎上
○監禁場所の特定(2chスクープ)
○ペッパーフードサービスHPに掲載された謝罪文の誤字脱字に「バカじゃねーのwww」と指摘レス相次ぐ
これら繰り返される訂正レスにペッパーフードサービスは反応。合計七回もの謝罪文を訂正
(執行部は2chを見てるのは間違いないと確信)
○ファミリーマートがペッパーフードサービスとの共同商品に大して「事件の重大性」を理由に
共同開発中止を通達
○有志のブロガーさん達が、報道を抑制しているマスコミに代わって自分のブログでこの事件をエントリー開始

ペッパーランチからの攻撃
○2ch内での工作員を送り込む(煽動失敗、2chによって完全制圧される)


196 名前:NAME IS NULL mailto:sage [2007/05/20(日) 00:37:47 ID:???]
logテーブルがあって
 user_id(int)
 run_time(timestamp)
これを
 ・5/19 20時 2回 ・5/19 21時 0回
 ・5/19 22時 1回 ・5/19 23時 4回
みたいな感じで 1ページに1ヶ月分表示しているんですが
発行クエリが 31日×24時間=744回 発生するんで非常に重いんです……

なにか1回だけのSQLで744行返ってくる書き方あれば教えてください
DBはmysqlです


現在使っている方法
select count(*) from log
where uid=ユーザid and date_format(run_time, '%Y-%m-%d-%H)'=?
?は for $i (1..31){for $j(0..23){年-月-$i-$j}}



197 名前:NAME IS NULL mailto:sage [2007/05/20(日) 02:10:08 ID:???]
select date_format(run_time, '%Y-%m-%d-%H'),count(*) from log
where uid=ユーザid
group by date_format(run_time, '%Y-%m-%d-%H')

198 名前:NAME IS NULL mailto:sage [2007/05/20(日) 09:12:26 ID:???]
>>197
こういう SQL 見てて select のところの date_format() と group by
のところの date_format() に同じ内容を書かないといけないのが、なんか嫌。

select date_format(run_time, '%Y-%m-%d-%H') as DateHour, ...
group by DateHour

のようにすればよさげなんだけど、なんか駄目な理由でもあるんだろうか?

date_format(run_time, '%Y-%m-%d-%H') ぐらいならまだ許容範囲だけど、
case を使ったような長い式を書く時に特にそう思う。

199 名前:NAME IS NULL mailto:sage [2007/05/20(日) 10:50:36 ID:???]
>>198
GROUP BY や WHERE は SELECTリストを見てるんじゃなくて、
FROM句を見てるから。つーか、SELECTのところよりGROUP BY句の方が先に処理されてる。
逆にORDER BYはSELECTリストに無いとエラーになる。こちらはカーソルだからね。

とは言うものの、今のPostgreSQLのGROUP BYはORDER BYと同じように扱えたりする。
エイリアスで指定可能はもちろんのこと、
SELECT date_format(run_time, '%Y-%m-%d-%H'),count(*) FROM log
WHERE uid=ユーザid GROUP BY 1;
んでも桶。まぁ、パーサが融通利かせれば如何様にでもなるんだろうけど。


200 名前:196 mailto:sage [2007/05/21(月) 00:05:37 ID:???]
>197
ありがとうございます
countが0だと返らないのはなんかアレなんですが
まぁプログラム側で処理すればいいですね

>198
ただでさえ分かりにくいから できるだけ簡潔に書きたいですね

>199
ホリデープログラマーは気にする必要なさそうですね

ありがとうございました。またよろしくです



201 名前:NAME IS NULL [2007/05/21(月) 06:01:43 ID:HJQ5A+AS]
mysqlを勉強していますが、わからないことがありましたので、質問させていただきます

Tbl_player

id name posi
1 三浦 FW
2 柳沢 FW
3 中村 MF
5 中田 MF
7 小野 MF

こういったテーブルがあったとして、
最後のレコードのnameを抽出したい場合、Where句にはどのような抽出条件を書いたらいいのでしょうか。

SELECT name
FROM Tbl_player
WHERE ??


202 名前:NAME IS NULL mailto:sage [2007/05/21(月) 07:11:12 ID:???]
>>201
何をもって「最後のレコード」とするのが不明だが、idが一番大きい物を選ぶなら、
WHERE id = (SELECT max(id) FROM Tbl_player);
サブクエリが使えないMySQLだったら、idで降順に並べ替えて1行目。


203 名前:NAME IS NULL mailto:sage [2007/05/21(月) 21:07:36 ID:???]
select name from Tbl_player order by id desc limit 1

204 名前:NAME IS NULL mailto:sage [2007/05/23(水) 16:23:31 ID:???]
MySQL 4.1 以降ならサブクエリ可。

205 名前:NAME IS NULL mailto:sage [2007/05/23(水) 16:25:44 ID:???]
だからサブクエリが使えないMySQLだったらって書いてるんだろ
使えるMySQLもあるからわざわざ書き足してる

206 名前:NAME IS NULL mailto:sage [2007/05/23(水) 22:39:25 ID:???]
>>202, >>204
> サブクエリが使えないMySQLだったら

「全ての MySQL はサブクエリが使えない」と解釈することも可能。

特に >>202 だけ読むと、サブクエリを使う例の後に書いてるので、
多くの人は「全ての MySQL はサブクエリが使えない (と >>202
思っている)」と解釈すると思う。

「サブクエリの使えないバージョン (の MySQL) なら」と書けば
意図がより明確になる。

そもそも、>>202 でわざわざサブクエリ使う意味がないし。

207 名前:202 mailto:sage [2007/05/23(水) 23:16:06 ID:???]
最初に断っとくが、>>205は俺じゃないからな。

>>206
確かに「バージョン」と書けばよかったが、>>201はMySQLを勉強...と断っているので、
「全てのMySQLはサブクエリが使えない」とはとらんだろう。少なくとも元質の人は。

個(最大値)を選択するのに、ベンダーに依存するLIMITクエリは、このスレ的に面白くないじゃん。

208 名前:NAME IS NULL mailto:sage [2007/05/23(水) 23:30:25 ID:???]
そもそもMySQLでサブクエリ使えるようになったって誰でも知ってることだろ……

209 名前:NAME IS NULL mailto:sage [2007/05/24(木) 11:15:02 ID:???]
うちの仕事先は3.23さ……orz

210 名前:NAME IS NULL mailto:sage [2007/05/24(木) 20:51:30 ID:???]
仕事で使ってるDBなんて、そう頻繁にバージョンアップするもんでもないけどな



211 名前:NAME IS NULL mailto:sage [2007/05/24(木) 22:57:09 ID:???]
>>210
運用してるDBはそうだな。
開発用ならあっちこっちにいろんなバージョンのDBが
あることの方が多いだろwww


212 名前:NAME IS NULL [2007/05/26(土) 10:24:17 ID:4biNP+cn]
select
  a, b, c
from 
  tbl
where
  b = "hoge" and
  c = (select max(c) from tbl where b = "hoge")

c が大きいレコードが新しいレコードだとします。
bが"hoge"の中で一番新しいレコードを取得するのに、こういうsqlを考えたのですが、こういう書き方って普通でしょうか?

213 名前:NAME IS NULL mailto:sage [2007/05/26(土) 11:39:50 ID:???]
having c=max(c)

214 名前:NAME IS NULL mailto:sage [2007/05/26(土) 21:06:17 ID:???]
冠詞(The, A)を読み飛ばしてソートするSQL文をご教授くださいm(__)m

データ
The piano
A doll
the song
songs

実行結果
A doll
The piano
the song
songs


215 名前:NAME IS NULL mailto:sage [2007/05/26(土) 21:08:49 ID:???]
冠詞(The, A)を読み飛ばしてソートするSQL文をご教授くださいm(__)m

table 'rooms'

column 'object'

songs
The piano
A doll
the song

実行結果
A doll
The piano
the song
songs


216 名前:NAME IS NULL mailto:sage [2007/05/26(土) 21:33:43 ID:???]
Replace みたいな関数があれば、それで消してからソート、で OK

217 名前:NAME IS NULL mailto:sage [2007/05/26(土) 22:35:58 ID:???]
>>207
> ベンダーに依存するLIMITクエリは、

> >>201はMySQLを勉強...と断っているので、

もしかして馬鹿?

218 名前:NAME IS NULL mailto:sage [2007/05/26(土) 22:40:48 ID:???]
終わった話題を蒸し返すバカ

219 名前:NAME IS NULL mailto:sage [2007/05/26(土) 23:38:42 ID:???]
あっ、悪い。

蒸し返されると困る人がまだいたんですね。

220 名前:NAME IS NULL mailto:sage [2007/05/26(土) 23:58:31 ID:???]
その二つは別問題だろうが、
行間を端折らずに全て説明しなきゃわかんないのかね。
ひょっとして生粋の日本人かな。



221 名前:NAME IS NULL mailto:sage [2007/05/27(日) 01:22:12 ID:???]
MySQLスレに行かずにわざわざここで聞いてるくらいだから

222 名前:NAME IS NULL mailto:sage [2007/05/27(日) 04:14:25 ID:???]
MySQLスレは初心者が質問できる雰囲気では無いからなあ。

223 名前:NAME IS NULL mailto:sage [2007/05/27(日) 09:38:17 ID:???]
>>220
> 行間を端折らずに全て説明しなきゃわかんないのかね。

へ〜、ちゃんと説明できるんだ。

じゃあ説明してみてよ。

224 名前:NAME IS NULL mailto:sage [2007/05/27(日) 10:34:52 ID:???]
なんかうるさいのがいるな。
ここは汎用のSQLの質疑応答がメインだから、
特定の処理系にこだわることはないし、方言に気を使う場所だ。
質問者がたまたま環境を指定したからって、それでしか使えない方法を
教えなくちゃいけないなんてことはない。

225 名前:NAME IS NULL mailto:sage [2007/05/27(日) 10:52:01 ID:???]
粘着しているのは一人だけだから放っておけよ。ただのキチガイみたいだし。

226 名前:NAME IS NULL [2007/05/27(日) 14:20:26 ID:Hm1mP6ts]
シーケンス番号がプライマリにあるテーブルで
Insert時にSQLで1ずつシーケンス番号をカウントアップさせようとしています。

Insertの際にシーケンス番号の部分に
select max(シーケンス番号) +1 のように値を指定しようかと思っていますが
1つのtransaction内で複数回Insertしようとした際に
max(シーケンス番号)が2回目以降Isolationによって
どのように変わるか教えてください。

Identityとか使えればよいのですが
パッチ作業が頻繁に発生し、バルクイン、アウトを行うのですが
これによりシーケンス番号が変更されると聞いているため
Identityを使用できません。
(そもそもIdentityのあるテーブルでバルクイン、アウトをやらないものなのでしょうか?)

シーケンス番号に順序性等は必要ないのですが
バルクイン、アウトを行うためだけに、このようなことをしようとしています。

定石等があれば教えてください。





227 名前:NAME IS NULL mailto:sage [2007/05/27(日) 14:39:15 ID:???]
そのDBMSには独立したsequenceオブジェクトはないのかい?普通はそれを使う。


228 名前:NAME IS NULL mailto:sage [2007/05/27(日) 15:10:09 ID:???]
>>224
> 質問者がたまたま環境を指定したからって、それでしか使えない方法を
> 教えなくちゃいけないなんてことはない。

いや、俺もそんなことは問題視してないよ。

ただサブクエリ云々の言い訳として「>>201はMySQLを勉強...と断っているので、」と
言う理由あげときながら、同じレスで「ベンダーに依存するLIMITクエリは」なんて書
く奴はアフォじゃね? って思っただけ。

見事に証明してくれてありがとう。(w

229 名前:NAME IS NULL [2007/05/27(日) 16:08:41 ID:Hm1mP6ts]
>>227

Identityでもsequenceでも同じことじゃん

230 名前:NAME IS NULL mailto:sage [2007/05/27(日) 17:17:42 ID:???]
違うだろ
identity列はsequenceが自動採番される列のこと。




231 名前:NAME IS NULL mailto:sage [2007/05/27(日) 17:43:59 ID:???]
>>226
なんか矛盾してねぇ?

順序性等は必要ないのですが
バルクイン、アウトを行うためだけに、このようなことをしようとしています。
これによりシーケンス番号が変更されると聞いているため
Identityを使用できません



232 名前:NAME IS NULL [2007/05/27(日) 18:08:58 ID:Hm1mP6ts]
>>231

説明足らずでした
履歴を持つテーブルなのでプライマリーキー的にもうひとつ、かぶらない値が必要なのです。

通常履歴も管理するテーブルの場合、このように採番系のカラムをもつのは一般的ではないのでしょうか?

233 名前:NAME IS NULL mailto:sage [2007/05/27(日) 19:29:25 ID:???]
>>216
THX!!ありがとうございました。

234 名前:NAME IS NULL [2007/05/28(月) 02:17:14 ID:trwQ1/5+]
インデックスについて質問
カラムA、カラムBの複合インデックスをもっている時
WHERE カラムA = ○○
で検索した場合、インデックスは使われる?

235 名前:NAME IS NULL mailto:sage [2007/05/28(月) 06:47:51 ID:???]
>>234
使われない

236 名前:NAME IS NULL mailto:sage [2007/05/28(月) 10:04:31 ID:???]
>>234
普通は使われるはずだが、心配ならプランを確認。

237 名前:NAME IS NULL mailto:sage [2007/05/28(月) 10:36:09 ID:???]
>>234
RDBMSのオプティマイザの実装に依存する。

RBOだと使われる可能性は高いと思うし、
SQLにオプティマイザヒントなんかを埋め込むことで、
特定のRDBMSならINDEXを使うようし向けることは出来る。
・・・が、すべてのRDBMSで必ず使われる保証は無いと思う。

CBOだったらいくら適切にINDEXが作成してあっても、
TABLE FULL SCANの方が低コストと判断されたら
全表走査することもある。

238 名前:NAME IS NULL mailto:sage [2007/05/28(月) 10:45:46 ID:???]
>>232
トランザクションがロールバックしようがコミットしようが、
単純に重複しなけりゃOKって用途であれば、
俺はOracleならシーケンス使う。
他のRDBMSで自動採番系の機能が有ればそっち優先で使う。


239 名前:NAME IS NULL mailto:sage [2007/05/28(月) 15:52:21 ID:???]
(SQL Server2005)
伝票の情報を保存するような以下のテーブルで
(伝票コード , 得意先コード , 取引区分 , 金額)
取引区分が 1 , 2 , 3 , 4 しか入らない場合
インデックス(Non-Clusterd)をつけるのは無駄なのかな?
select/Insertの比率9:1とします
Insertする時にreal分割が発生すると取引区分=1 のレコード全部にロック(ラッチ)かかる?

1.ないよりマシ
2.選択性が低いので意味なし
3.さらにロック、ラッチの観点から逆効果


240 名前:NAME IS NULL mailto:sage [2007/05/28(月) 20:41:18 ID:???]
試しにやってみればいいじゃねーか。
不思議な質問だ。



241 名前:NAME IS NULL mailto:sage [2007/05/29(火) 17:58:14 ID:???]
めんどいじゃん。

242 名前:NAME IS NULL mailto:sage [2007/05/29(火) 18:22:52 ID:???]
答えるほうもめんどいわw

243 名前:NAME IS NULL mailto:sage [2007/05/29(火) 18:27:29 ID:???]
三択まで用意してやったんだぜ?サクッと答えられる奴いないの?

244 名前:239 mailto:sage [2007/05/29(火) 18:38:08 ID:???]
お前らどんだけだよ!にわかは氏ね!

245 名前:NAME IS NULL mailto:sage [2007/05/29(火) 19:11:39 ID:???]
試しにやってみればいいじゃねーか。
不思議な人だ。

246 名前:NAME IS NULL mailto:sage [2007/05/29(火) 19:34:01 ID:???]
>>239
「データが極端に少ない」 or 「データが大量にある」なら、
カーディナリティ低いINDEXにどれだけ意味がある?

実際は自分が想定するデータ件数で実験して判断しろよwww


247 名前:NAME IS NULL mailto:sage [2007/05/29(火) 20:13:50 ID:???]
>>226
>Identityとか使えればよいのですが 
>パッチ作業が頻繁に発生し、バルクイン、アウトを行うのですが 
>これによりシーケンス番号が変更されると聞いているため 
>Identityを使用できません。 
sql serverのことだったら
bcp in の時に -E オプションをつければシーケンス番号は変わらないぞよ。

248 名前:NAME IS NULL mailto:sage [2007/05/29(火) 23:16:27 ID:???]
通常タイムスタンプは同じ値でも幅があるから一意として使えない(1秒間に複数更新があった場合)。
けれど、SQLServerのTIMESTAMPは

行が更新されるたびに更新
される、データベース内で
一意なバイナリ形式の番号。
データを追加または変更
した日時とは関係ありま
せん。
以下はTUMESTAMP の
シノニムです。
ROWVERSION

だそうだ。更新されれば自動的に値が変わる。
自明だけど、反復読み取りのチェックに使える。

249 名前:NAME IS NULL mailto:sage [2007/05/29(火) 23:19:57 ID:???]
>>226
履歴を作る場合等、データによって同じ数値のカウンタが複数出る時は、行識別のidentifierと更に追加でカウンタ含む複合uniqueキーを使う。
例えば、
取引 id  カウンタ(defalt:0 0は最新データを意)
A  123
注)取引とカウンタで複合unique
という表Aをつくる。ここでは、取引:Aとid:123をinsert済
次に、
取引 id  コンスタント
A      0
注)id:unique,取引とコンスタントで複合unique
と取引名とid:nullとコンスタント:0のみの表Bを作りselect,insert:可 update,delete:拒否とする。
表Aをselectする場合、表Bより取引&idのwhereでコンスタントを探し該当する値がなければid=nullのときのコンスタントを選ぶ。
更新は、表Bに対し取引A,id,コンスタント+1を行う(これが履歴となる)。
仮に、+1処理させないルール無視のクライアント処理がきた場合、複合キーがぶつかってはじかれる(アプリに計算させてもACIDのために制限をかけている)。
idと複合uniqueのコンビネーションで反復読み取りのはざまに更新した場合の判別がやりやすくなる。(全カラム比較の必要なし)

このようにすれば、
>select max(シーケンス番号) +1 のように値を指定しようかと思っていますが
>1つのtransaction内で複数回Insertしようとした際に
>max(シーケンス番号)が2回目以降Isolationによって
>どのように変わるか教えてください。

のMRUの履歴max+1をidentifierとしてカウントアップさせるのではなくACIDを保持したまま安全にアプリに変数として持たせられる。
後、トリガー使う方法もあるけど(考え方としてはやりやすいけど)、選択の余地が無いのでバッチ等処理が重くなる。
この辺、前処理後処理含めてcobolのcallインターフェースは融通効くんだけどねえ、なにせRDBというかSQL・・(ry


250 名前:NAME IS NULL mailto:sage [2007/05/29(火) 23:33:50 ID:???]
あと履歴のレプリカ作って元表と全カラムjoinしてやれば、
たちまち履歴が更新削除禁止になるなんてこともできるぜ
(連鎖更新、連鎖削除禁止)



251 名前:NAME IS NULL mailto:sage [2007/05/30(水) 07:44:06 ID:???]
>>248
SQL Server2005ですがTimestamp列で楽観的ロックをやってます


252 名前:NAME IS NULL [2007/05/30(水) 19:16:42 ID:PlndNA/w]
SQL Server2005を使用しています。
例えば500行ヒットして先頭から50行取得するSELECT文で
SELECT TOP 50 カラムA FROM T WHERE 〜 としていたのですが
このヒット数の500も一緒に取得するにはどうしたらいいのでしょうか。

試しにSELECT TOP 50 COUNT(*) カラムA FROM T WHERE 〜
としてみましたがCOUNTにはやっぱり50が入ってきます。

ただ50行全部にCOUNT値があるのでこういう場合は
切り分けて考えた方がいいのか悩んでいます。




253 名前:NAME IS NULL mailto:sage [2007/05/30(水) 20:58:08 ID:???]
いつもロムっていましたが質問させてください。

a表
得意先コード 売上区分 売上金額  売上日
1       10    1000    2007/04/15
1       10    500     2007/05/02
2       30    2100    2007/04/28
2       13    2500    2007/05/01
3       14    3100    2007/04/10
3       25    3900    2007/04/18
4       31    4500    2007/05/15

b表
得意先コード 得意先名
1       佐藤
2       青木
3       田中
4       佐々木

c表
得意先コード 限度金額
1       10000
2       5000
3       20000
4       30000

上記3つの表から
a表の得意先コードごとに売上月で分かれた下記の様な集計表を作成したいのですが
途中でつまずいてしまいました。
どのようなSQL文を書いたら良いのか教えていただけないでしょうか。
RDBMSはOracle9.2を使用しています。
よろしくお願いします。

得意先コード 得意先名 合計売上金額 前月売上金額 今月売上金額 限度金額
1       佐藤   1500     1000     500      10000
2       青木   4600     2100     2500     5000
3       田中   7000     7000     0       20000
4       佐々木  4500     0       4500     30000


254 名前:NAME IS NULL mailto:sage [2007/05/30(水) 21:00:34 ID:???]
>>252
select ごにょごにょ into #temp from table_a where ごにょごにょ (500行分)

select top 50 ごにょごにょ, count = (select count(*) from #temp) from #temp

もしくは .NETなら
select top 50 ごにょ from table_a where ごにょ
select count(*) from table_a where ごにょ
で dataadapter.fill(dataset) とすれば
dataset.table(0) に1つ目, table(1)に2つ目が入る


255 名前:NAME IS NULL mailto:sage [2007/05/30(水) 21:07:45 ID:???]
>>253
けっこう面倒そうだけど
合計売上額は先々月のデータとかあったら足していいのけ?

まずa表から月別の売上作ってみたら?

256 名前:NAME IS NULL [2007/05/30(水) 21:20:47 ID:Mj0ff4uQ]
>>255
さっそくありがとうございます。
先月までの累積金額と今月分のを集計したいので足して集計させたいです。

a表から先月までの分と今月分のを作成するのはできると思います。

select 得意先コード, sum(売上金額) as 売上金額
from a表
where 売上日 < '2007/05/01' ←ここを変えて2回処理します
group by 得意先コード;

先月までの分と今月分とb表、c表を結合するには(+)とか使えばいいのでしょうか。
よろしくお願いします。

257 名前:NAME IS NULL mailto:sage [2007/05/30(水) 21:45:04 ID:???]
>>256
>ここを変えて2回処理します
月別でグループ化して一時表作ったら1回で済むんじゃ?

select 得意先コード, 年月 = cast( replace(売上日,'/','') as int)
,sum(売上金額) as 売上金額
into #temp from a表
where 売上日 < '2007/05/01' 
group by 得意先コード , cast( replace(売上日,'/','') as int)

累積
select 得意先コード , 累積 = sum(売上金額) from #temp group by 得意先コード

先月
select 得意先コード , 累積 = 売上金額 from #temp where 年月 = 200704

今月
select 得意先コード , 累積 = 売上金額 from #temp where 年月 = 200705

ここまで出来たらあとはjoinするだけ
ああ最初のcastはoracleでは使えないかもしれないから変えてね

258 名前:NAME IS NULL mailto:sage [2007/06/02(土) 13:34:23 ID:???]

id   name_col
1    name_1
2    name_2
3    name_3
4    name_4
5    name_5

name_col の name_ を title_ に置換して

id   name_col
1    title_1
2    title_2
3    title_3
4    title_4
5    title_5

とするにはどうすればいいですか?

259 名前:NAME IS NULL mailto:sage [2007/06/02(土) 16:46:18 ID:???]
replace(name_col,'name_','title_')

260 名前:NAME IS NULL [2007/06/02(土) 18:52:09 ID:F7i5c8na]
すんません

GROUP BY と COUNT(*)を使ったクエリで
COUNT(*)が 0 になる場合も 0 を出力してもらう方法ってありませんか?




261 名前:NAME IS NULL mailto:sage [2007/06/02(土) 19:28:25 ID:???]
col1
----
A
B
D
B

っていうテーブルがあったとして、

col1 count(*)
---- --------
A   1
B   2
C   0
D   1
E   0
・・・
Z   0

にして欲しいってこと?

無理だろ。

262 名前:NAME IS NULL mailto:sage [2007/06/02(土) 19:49:43 ID:???]
A-Zだけじゃないでしょ
全ての文字列の組み合わせで、0件の出力しなくちゃ

263 名前:NAME IS NULL mailto:sage [2007/06/02(土) 20:03:01 ID:???]
集計キーのマスタを用意すれば
外部結合とcoalesceで実現出来ると思う

264 名前:NAME IS NULL mailto:sage [2007/06/03(日) 01:50:06 ID:???]
>261
そうそう
まぁ普通に無理っすね……

>263
別テーブルと結合って考えたんですけど
めんどくさいっすね……

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


265 名前:NAME IS NULL [2007/06/03(日) 16:50:29 ID:mw/dDSFg]

Postgreでmemberの住所(address)が埼玉、群馬の女子(f)の人数を調べようと思うのですが
どのようなSQLを書いたらよいでしょう?

結果は
-------------
埼玉 50
群馬 30
-------------
のように表示させたいのですが、

select address ,count(*) from member where (address = '埼玉' or address '群馬') and (sex = 'f');

ではダメですか?

266 名前:NAME IS NULL mailto:sage [2007/06/03(日) 17:25:20 ID:???]
>>265
group by

267 名前:NAME IS NULL mailto:sage [2007/06/04(月) 18:37:01 ID:???]
>>257

257様 お力添えありがとうございます。
お教えいただいた方法で色々試してみました。
(1)と(2)で一時表(c表)を作成し(3)でd表に集計しようと考えてみましたが、
(3)のSQLを実行すると「ORA-00979 GROUP BYの式ではありません」とエラーとなってしまいます。
どのようなSQLを組んで良いのか…もう一度皆様のお力を貸していただけないでしょうか。
よろしくお願いします。


(1)
insert into c表
select 得意先コード,sum(売上金額) as 売上金額4,sum(0) as 売上金額5
from a表
where 売上日 <= '2007/04/30'
having sum(売上金額) != 0
gropu by 得意先コード

(2)
insert into c表
select 得意先コード,sum(0) as 売上金額4,sum(売上金額) as 売上金額5
from a表
where 売上日 > '2007/04/30'
having sum(売上金額) != 0
gropu by 得意先コード

(3)
insert into d表
select d表.得意先コード,b表.得意先名,c表.限度金額,sum(d表.売上金額4) as 売上金額4,
sum(d表.売上金額5) as 売上金額5
from b表,c表,d表
where d表.得意先コード = b表.得意先コード (+)
and d表.得意先コード = c表.得意先コード (+)
group by d表.得意先コード


268 名前:NAME IS NULL mailto:sage [2007/06/04(月) 18:41:38 ID:???]
>>267


申し訳ありません。
間違ったSQLを貼り付けてしまいました。
こちらが実行したSQLです。

(1)
insert into d表
select 得意先コード,sum(売上金額) as 売上金額4,sum(0) as 売上金額5
from a表
where 売上日 <= '2007/04/30'
having sum(売上金額) != 0
gropu by 得意先コード

(2)
insert into d表
select 得意先コード,sum(0) as 売上金額4,sum(売上金額) as 売上金額5
from a表
where 売上日 > '2007/04/30'
having sum(売上金額) != 0
gropu by 得意先コード

(3)
insert into e表
select d表.得意先コード,b表.得意先名,c表.限度金額,sum(d表.売上金額4) as 売上金額4,
sum(d表.売上金額5) as 売上金額5
from b表,c表,d表
where d表.得意先コード = b表.得意先コード (+)
and d表.得意先コード = c表.得意先コード (+)
group by d表.得意先コード


269 名前:NAME IS NULL mailto:sage [2007/06/04(月) 19:59:56 ID:???]
最近の Oracle は GROUP BY の前に HAVING 使えるのか?
まぁ普通に逆に書いてると予想。

270 名前:NAME IS NULL mailto:sage [2007/06/04(月) 20:24:35 ID:???]
>>269

ありがとうございます。
(1)と(2)を単独に実行しても正常に通りますが、
ご指摘のとおりHAVINGの使い方をGROUP BYの後に書くよう改めます。

(3)ですが3つの表から1つにまとめたいのですが、
皆さんならどのように書かれますか?




271 名前:NAME IS NULL mailto:sage [2007/06/04(月) 20:43:46 ID:???]
>>270
あんま読んでないけど
group by d表.得意先コード,b表.得意先名,c表.限度金額
じゃないのけ?

272 名前:NAME IS NULL mailto:sage [2007/06/04(月) 20:59:54 ID:???]
>>271

271様
お教えいただいたとおり修正しましたら動きました!!
ありがとうございました。
まだまだ勉強不足だと痛感しています…。


273 名前:NAME IS NULL mailto:sage [2007/06/05(火) 01:28:00 ID:???]
以下のようなテーブルがあって、ある指定された1つ以上のタグ全て含むfavorite_idを選択したいです。
例)SQLとC++が指定されたら、1と3が返ってくる
以下のようなSQLを考えたのですが、もっと良い書き方とか定番の書き方があれば教えてください。
SQLite使ってます。

SELECT favorite_id FROM fav_tag, tag
WHERE fav_tag.tag_id = tag.tag_id
  AND (tag.text = 'SQL' OR tag.text = 'C++')
GROUP BY fav_tag.favorite_id
HAVING COUNT(fav_tag.favorite_id) = 2;


テーブル名:fav_tag
favorite_id    tag_id
====================
1            3
1            4
1            6
1            7
2            13
2            15
2            21
3            3
3            4
3            13
4            4
5            31

・・・

テーブル名:tag
tag_id    text
====================
3        SQL
4        C++
6        HTTP
7        JAVA
13       DB
・・・

274 名前:NAME IS NULL [2007/06/05(火) 01:43:56 ID:PQi92ZZ4]
どなたかご知見がありましたらご教授ください。

現在下記のような、selectした結果をそのまま
insertするsqlを組んでいるのですが、SQL内に計算式が含まれる為か
かなり処理速度が遅い状態です。
実際はinsert項目はもっと大量にあり、
かつ選択条件もキーだけではなく
like条件も含むやや複雑なものを使用しています。


INSERT INTO 表4
SELECT
ROUND(SUM(C.商品1単価 * B.商品の重量) / SUM(B.商品の重量),3),
ROUND(SUM(C.商品2単価 * B.商品の重量) / SUM(B.商品の重量),3),
ROUND(SUM(C.商品3単価 * B.商品の重量) / SUM(B.商品の重量),3),
ROUND(SUM(C.商品4単価 * B.商品の重量) / SUM(B.商品の重量),3),

ROUND(SUM(C.商品5単価 * B.商品の重量) / SUM(B.商品の重量),3) +
ROUND(SUM(C.商品6単価 * B.商品の重量) / SUM(B.商品の重量),3),

SUM(B.商品の重量)

FROM 表A,表B,表C

WHERE

A.キー1 = B.キー1 AND
B.キー2 = C.キー2 AND
(A.対象期間 >= '2006/04/01' AND A.対象期間 <= '2007/03/31')

この場合、一気に処理をしようとしないで、
カーソルで1行づつそれぞれの単価及び重量を取得して
どんどん足しこむ計算をプログラム内で用意し、集計した結果をinsertしたほうが
処理的にやはり早いのでしょうか?

もしくは各表毎に検索処理自体も分けて
検索も極力キーのみを使用するようにしたほうが
結果として早くなるのでしょうか?

insert対象が3000件ほどあるのですが
登録に1時間以上かかっております・・・。

275 名前:NAME IS NULL mailto:sage [2007/06/05(火) 05:23:15 ID:???]
>>274
それはもう実行計画見ろとしかいいようがないな


276 名前:NAME IS NULL mailto:sage [2007/06/05(火) 11:31:24 ID:???]
>>273
ほとんど変わんないけどちょっと手直し (入力データ流し込みやすいように)
SELECT favorite_id FROM fav_tag INNER JOIN tag using(tag_id)
WHERE tag.text IN ('SQL','C++')
GROUP BY favorite_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM tag WHERE tag.text IN ('SQL','C++'))


それと相関サブクエリ使うやり方
SELECT DISTINCT favorite_id FROM fav_tag fav1
WHERE NOT EXISTS
(SELECT tag.tag_id FROM tag WHERE tag.text IN ('SQL','C++')
EXCEPT SELECT fav2.tag_id FROM fav_tag fav2
WHERE fav2.favorite_id = fav1.favorite_id);

どっちがパフォーマンス良いかは知らないので
実験して好きな方使ってくれ。

参考
ttp://codezine.jp/a/article/aid/1304.aspx?p=2


277 名前:273 mailto:sage [2007/06/06(水) 00:56:27 ID:???]
>>276
まだSQLに慣れてないので、別のやり方を挙げて頂けたのは勉強になり助かります。
ありがとうございました。

278 名前:NAME IS NULL [2007/06/06(水) 23:08:37 ID:GDaT0Jkl]

学年 学籍番号 点数
1    0001    60
1    0002    80
2    0003    90
2    0004    20

このような表からそれぞれの学年ごとに、A(80〜100点の人数)、
B(70〜80点の人数) C(60〜70点の人数) D(0〜60点の人数)を
表にするにはどうしたらよいでしょうか?

学年 A  B  C  D
1   10  15  8  9
2   11  22  2  3
3   13  9  3  10

よろしくお願いします。

279 名前:NAME IS NULL mailto:sage [2007/06/07(木) 01:40:24 ID:???]
>>278
SELECT 学年,
SUM(CASE WHEN 点数>=80 THEN 1 ELSE 0 END) AS A,
SUM(CASE WHEN 点数>=70 AND 点数<80 THEN 1 ELSE 0 END) AS B,
SUM(CASE WHEN 点数>=60 AND 点数<70 THEN 1 ELSE 0 END) AS C,
SUM(CASE WHEN 点数<60 THEN 1 ELSE 0 END) AS D
FROM 表 GROUP BY 学年;

280 名前:NAME IS NULL mailto:sage [2007/06/07(木) 21:05:56 ID:???]
order by 学年 asc

をつけといた方がいいかも。



281 名前:NAME IS NULL [2007/06/08(金) 02:10:35 ID:oKxpcUps]
SQLの勉強をしたいのですが無料で軽いフリーソフトがありましたら教えてください

282 名前:NAME IS NULL mailto:sage [2007/06/08(金) 04:28:57 ID:???]
byteaで画像データを格納したいとき、画像のパスを指定して保存、は可能ですか?


283 名前:NAME IS NULL mailto:sage [2007/06/08(金) 07:00:28 ID:???]
>>281
MySQL
SQL Server ExpressEdition


284 名前:NAME IS NULL mailto:sage [2007/06/08(金) 10:14:01 ID:???]
SQLite
PostgreSQL

285 名前:NAME IS NULL mailto:sage [2007/06/08(金) 10:20:40 ID:???]
>>281
FireBird


286 名前:NAME IS NULL [2007/06/08(金) 13:49:30 ID:4l/ZZkFv]
SQLプログラマーの先輩様に質問があります
現在私は日本電子専門学校(情報処理科1年)で先週初めてSQLServer の授業が行われたのですがプログラムを作る際考え方がわからなくて困っています(ノ_<。)
隣にいる同級生はスラスラ解いているのに自分は教科書見て探している間に時間が過ぎてる毎日です
俺はこんな風に勉強して上手くなった 式の組合せはこう考えればいいよってことがありましたら教えてください(^人^;)

287 名前:NAME IS NULL mailto:sage [2007/06/08(金) 15:02:07 ID:???]
DBに接続するアプリの作り方がわからないのか、SQLの書き方がわからないのかどっち?

288 名前:NAME IS NULL mailto:sage [2007/06/08(金) 15:14:58 ID:???]
>>286
何をどうして良いのか分からないんだったら、
目的の物を得るためには
どういう順番で何をしなければならないかを
考える癖をつけた方が良いよ。

やらなければならないことを
ナンバリングしながら箇条書きにしていくだけでも、
基本的なロジックは組み上がるからね。


289 名前:NAME IS NULL mailto:sage [2007/06/08(金) 15:27:09 ID:???]
あと、特に理由がなければ個人を特定されかねない情報は出すべきではないと思う。
エレクトロンの花とか言われるぞ。

290 名前:NAME IS NULL mailto:sage [2007/06/08(金) 23:35:26 ID:???]
>>282
可能だろ。

君が「指定されたパスから画像を読み込んで、データベースに食わせる」ことができるなら。



291 名前:NAME IS NULL [2007/06/11(月) 14:52:31 ID:DdlgA2BI]
+----------+--------+
|  DATE   | GENDER |
+----------+--------+
|2007-06-01 |  M    |
+----------+--------+
|2007-06-01 |  F    |
+----------+--------+
|2007-06-01 |  M    |
+----------+--------+
|2007-06-02 |  F    |
+----------+--------+

TOUROKUというテーブルに上記データがあるとして、
以下のように、日付毎の合計件数とMまたはFそれぞれの件数を同時に求めたいです。

+----------+------+--------+--------+
|  DATE   |COUNT|COUNT(M)|COUNT(F)|
+----------+------+--------+--------+
|2007-06-01 |  3  |   2   |   1   |
+----------+------+--------+--------+
|2007-06-02 |  1  |   0   |   1   |
+----------+------+--------+--------+

日付毎の合計を求めるだけなら
SELECT
DATE(CREATED) AS DATE,
COUNT(*) AS COUNT
FROM TOUROKU
GROUP BY DATE
;
として求められることがわかりましたが、
MとFを同時に求める方法がわかりません。
教えてください。MySQL4.2です。

292 名前:291 [2007/06/11(月) 14:53:30 ID:DdlgA2BI]
あ、ごめんなさい。
自分でわかったSQLは
日付毎の合計を求めるだけなら
SELECT
DATE,
COUNT(*) AS COUNT
FROM TOUROKU
GROUP BY DATE
;
でした

293 名前:NAME IS NULL mailto:sage [2007/06/11(月) 15:10:29 ID:???]
>>291
SELECT date, count(*) AS COUNT,
(SELECT count(*) FROM Touroku WHERE gender='M' AND date=T0.date) AS COUNT_M,
(SELECT count(*) FROM Touroku WHERE gender='F' AND date=T0.date) AS COUNT_F
FROM Touroku AS T0 GROUP BY date;

294 名前:291 mailto:sage [2007/06/11(月) 15:18:34 ID:???]
>>293
ありがとうございます、できました!
なるほどこれがサブクエリーってやつなんですね。
勉強になりました。ありがとうございました。

295 名前:NAME IS NULL [2007/06/11(月) 19:49:09 ID:u6t10WUz]
C#でOracleに接続してSQLの構文を書いてるのですが、ListBoxの選択されたアイテム
をWhereで抽出したいのですが、どのように書いてみたらいいですかね?

296 名前:NAME IS NULL mailto:sage [2007/06/11(月) 20:11:18 ID:???]
>>295
in

297 名前:NAME IS NULL mailto:sage [2007/06/11(月) 23:55:58 ID:???]
>>279
できました。
ありがとうございました。

298 名前:295 [2007/06/12(火) 16:12:20 ID:pwv6P776]
inを使って構文を書いたのですが、上手くいかず・・・具体的にどんな感じに
書いたらいいでしょうか?

299 名前:NAME IS NULL mailto:sage [2007/06/12(火) 16:28:08 ID:???]
うまくいかなかった時のSQLを書いてよ

WHERE xxx IN (1,2,3,4,5)

とか

300 名前:295 [2007/06/12(火) 17:10:51 ID:pwv6P776]
WHERE xxx IN(' + listbox + ')
このような形で書いたのですが、上手くいかず。。。



301 名前:NAME IS NULL mailto:sage [2007/06/12(火) 17:33:31 ID:???]
>>300
listboxの中身をちゃんと展開して、
>>299みたいなカンマ区切りの文字列にしろよ。


302 名前:295 [2007/06/12(火) 17:40:22 ID:pwv6P776]
listboxの中身を展開ってどうやればいいんですか?

303 名前:NAME IS NULL mailto:sage [2007/06/12(火) 18:42:35 ID:???]
いや、最初っからSQLの話じゃなくてC#の話じゃねぇの。
聞くスレ間違っているよ。

SelectionModeがOneなら、
this.listBox1.SelectedItemで取り出せるんだから、
それをDbParameterかなにかで突っ込めばいいだろ。
マルチならthis.listBox1.SelectedItemsを展開連結なり何なりと。

>>300のやり方を見ると

WHERE xxx = ’" + listBox1.SelectedItem.ToString() + "'";
としたいのか。それでもいいが、
普通はDbParameter経由で押し込むべきだろう。

なんにせ、板違いのスレ違い。

304 名前:NAME IS NULL mailto:sage [2007/06/13(水) 01:14:47 ID:???]
oracle 9

テーブル4つを共通キーで外部結合し、
他の項目をとってきてデータ出力したいが その際件数が合わない
おおよそこんな形

select t1.key1, t2.item1, t3.item1,t4.item1
from t1,t2,t3,t4
where t2.key1 = t1.key1
and t3.key1 = t1.key1
and t4.key1 = t1.key1

これだとキー以外の項目の組み合わせ分件数が膨れて出てくる
SQLで楽に以下のように出せる方法あるでしょうか?
(pl/sql等が妥当なのか?)

t1.key1, t2.item1 t3.item1 t4.item1
1 1 1 1
2 2
3
2 1 1 1
2 2
3
3 1
4 1

※テーブルの定義
table colum
t1 key1
t2 key1,item1
t3 key1,item1
t4 key1,item1


305 名前:NAME IS NULL mailto:sage [2007/06/13(水) 01:20:21 ID:???]
例えるのが難しいんだけれど、DBを作った掲示板のようなシステムを作ったとして、

あるスレッドのデータだけを取り出せるシステムを組みたい場合のテーブル設計として、
スレッド別にテーブルを新規作成してFROM句を変えるものと、
1つのテーブル内でスレッドID列みたいなものを作って、WHERE区で判別して抽出する方法がありますが、

どちらの方がいい、とかあるんでしょうか?
ぽんぽんとテーブルを新規作成するのはマズイような気もするのですが、その根拠も分からないので迷っています。

306 名前:NAME IS NULL mailto:sage [2007/06/13(水) 01:22:17 ID:???]
リストのイメージ訂正

t1.key1, t2.item1 t3.item1 t4.item1 |
--------------------------------------
1 1 1 1 |
2 2 |
3 |
2 1 1 1 |
2 2 |
3 |
3 1 |
4 1 |


307 名前:NAME IS NULL mailto:sage [2007/06/13(水) 04:36:38 ID:???]
データマイニングって何か役に立ってるの?

308 名前:NAME IS NULL mailto:sage [2007/06/13(水) 07:48:13 ID:???]
>>305
スレッド別に扱うデータ項目が異ならない限りは、
スレッド別にテーブル作る設計なんてあり得ないだろ。


309 名前:NAME IS NULL [2007/06/13(水) 18:34:40 ID:FlP9jY9L]
>>305
スレッド死んだ時とか考えるのヤだなぁ、と思った俺は違うスレッドを想像していた模様なのはおいといて・・・

「効率いいだろうけど管理メンドクサイじゃん。テーブル10000ヶとか出てきたら俺逃げるぜ?」ってジレンマは
どうやら皆持ってたようで、SQL鯖2005では
「一つのテーブルだけどユーザ定義の関数に合わせて複数の実データ構造に分けて格納します。
クエリ次第では効率アップするかもよ?」
ってな不思議な仕組みが導入されています。勉強して使いこなしてください。正直、名前忘れたけど。

Oracleは不勉強につき勘弁。

310 名前:NAME IS NULL mailto:sage [2007/06/13(水) 22:09:32 ID:???]
>>304
膨れた結果から不要なものを除外する条件を追加すれ



311 名前:305 mailto:sage [2007/06/14(木) 07:24:47 ID:???]
>>309
FROM句を変えるだけの手軽さや、他のスレッドデータも1テーブル内に混在するという怖さばかり見てて、
「テーブル10000ヶとか出てきたら」というのを余り深く考えてませんでした。
確かに逃げたくなりますね・・・

それを考慮し、SQLサーバーなどが機能面でサポートしようとしていることも知れ、勉強になりました。
ありがとうございました。

312 名前:NAME IS NULL mailto:sage [2007/06/14(木) 08:44:21 ID:???]
>>309
Oracleならパーティショニングオプションと、
パラレルクエリーで、ってことになるだろうな。


313 名前:NAME IS NULL mailto:sage [2007/06/14(木) 10:39:31 ID:???]
10000どころか、2つだってありえない

314 名前:NAME IS NULL mailto:sage [2007/06/14(木) 17:05:49 ID:???]
カーソル定義で結合を行った場合でもSELECT FOR UPDATEで更新可能ですか?
Oracle10gです。

TBL01のPKがA,B
TBL02のPKがA,B,C

DECLARE CURSOR CUR IS SELECT * FROM TBL01 JOIN TBL02 USING(A,B)

に対して、FOR UPDATE文を指定してTBL02を更新出来るか教えて頂けませんか。


315 名前:NAME IS NULL mailto:sage [2007/06/14(木) 17:31:13 ID:???]
>>314
何故、試さない?

316 名前:NAME IS NULL mailto:sage [2007/06/14(木) 18:05:01 ID:???]
設計Phaseで試せる環境が無い ('A`
Accessならあるんだけど。

317 名前:NAME IS NULL mailto:sage [2007/06/14(木) 19:16:38 ID:???]
>>316
OTNから試用版ダウンロードできるだろうに。

318 名前:NAME IS NULL mailto:sage [2007/06/15(金) 03:26:54 ID:???]
>>304
マニュアル見てfull joinのネストかな?と思ってやってみたが
onの記述でわけわからん。テンプレみたら あったな。
やり方3つもあるの?へえ〜。
たすかったよ

oraclesqlpuzzle.hp.infoseek.co.jp/7-36.html

いやここすごいね。使えるわ。


319 名前:NAME IS NULL mailto:sage [2007/06/15(金) 09:55:52 ID:???]
テーブルAとテーブルBがあって、テーブルBの主キーはテーブルAの
主キー+レコード適用日となっています。

日付を指定してレコードを検索した場合に、指定日≧適用開始日ならBから、
そうじゃないならAからレコードを取得したいのですが、これを一つのSQLで
実現する方法はないでしょううか?

なお、テーブルBには、適用日以外のキーが重複するレコードが複数います。

テーブルA
(1) ID=01, 〜

テーブルB
(2) ID=01, 適用日=6/20, 〜
(3) ID=01, 適用日=7/01, 〜

日付=7/15を指定した場合は(3)のレコードを取得したい。6/01を指定した
場合は(1)のレコードを取得したい。


320 名前:NAME IS NULL mailto:sage [2007/06/15(金) 10:16:52 ID:???]
>>319
AとBを結合して、CASE式で場合分け出来そうな希ガス。




321 名前:NAME IS NULL mailto:sage [2007/06/15(金) 12:23:21 ID:???]
多分Aを加工しBと同列でユニオンかな


322 名前:NAME IS NULL mailto:sage [2007/06/15(金) 13:04:48 ID:???]
Aの加工って?

323 名前:NAME IS NULL mailto:sage [2007/06/15(金) 13:19:23 ID:???]
>>322
システム日付でも固定値でも何でも良いから、
適用日の値を返すようなSQLで、
Aに対してSELECT書けば良いんだと思うが。

で、その結果とBのSELECTをUNIONして・・・
ってことだとオモ。


324 名前:NAME IS NULL mailto:sage [2007/06/15(金) 14:25:19 ID:???]
いや、そうやってA'を細工したとしても

1) ID=1、適用日=0000/1/1、〜 (A'。Aに対して適当な固定日を付与)
2) ID=1、適用日=6/20、〜   (B)
3) ID=1、適用日=7/1、〜   (B)

の3行に対して、例えば日付=6/25を指定したときに(2)を取得すンのは
難しいのでは?

って、TBL設計の話になっちゃうけど、こういうのって普通適用開始日と
終了日の両方持つのが一般的のような。

325 名前:NAME IS NULL mailto:sage [2007/06/15(金) 14:39:18 ID:???]
>>324
その場合どうなるべきか、ってのは
質問者の意図を推測するしかないが、
その例ではB表に7/1があるから、
指定日が6/25なら7/1のデータが
取得されないと不味いんじゃないか?
あるいはB表には6/25のデータがある、
ということなのかもしれん。

どっちにせよ、俺には>>319のデータ構造なら
A/Bの2表が有ること自体、変に思うんだが。
A表の履歴ログだ、ってことにしたって、
適用日が毎日ってならともかく、ある程度の間隔があるなら
お前さんの言うようにFrom〜Toで日付持たせてた方が
2次利用が楽なように思うしな。


326 名前:325 mailto:sage [2007/06/15(金) 14:42:37 ID:???]
あぁ、指定日≧適用開始日だったか。

だとしたらお前さんの言うとおり、
> 1) ID=1、適用日=0000/1/1、〜 (A'。Aに対して適当な固定日を付与) 
> 2) ID=1、適用日=6/20、〜   (B) 
> 3) ID=1、適用日=7/1、〜   (B) 

> の3行に対して、例えば日付=6/25を指定したときに(2)を取得
ってことだなぁ。
スマソ

327 名前:NAME IS NULL mailto:sage [2007/06/15(金) 16:04:36 ID:???]
select tbl_A.ID, coalesce(tbl_B.col1,tbl_A.col1), coalesce(tbl_B.適用日,'---')
from tbl_A left join tbl_B on (tbl_A.ID = tbl_B.ID and tbl_B.適用日 <= 指定日)
where tbl_B.適用日 is Null or tbl_B.適用日=
(select max(subB.適用日) from tbl_B subB
where subB.ID=tbl_A.ID and subB.適用日 <= 指定日);

これで
tbl_A (ID, col1)
1, aaa
2, bbb
3, ccc

tbl_B (ID, col1, 適用日)
1, aaa1, 2007/06/20
1, aaa2, 2007/07/01
2, bbb1, 2007/05/22
2, bbb2, 2007/06/30
2, bbb3, 2007/07/01
3, ccc1, 2007/07/01

から、指定日=2007/06/30で
1, aaa1, 2007/06/20
2, bbb2, 2007/06/30
3, ccc, ---
と出るけどこういうことでよいのかな?

>適用日以外の"キーが重複するレコードが複数"います
ってのが意味わかんないので〜の所に何入ってるのかよくわからん。

328 名前:NAME IS NULL mailto:sage [2007/06/15(金) 17:50:58 ID:???]
>>327
推測だが、例えば会社マスタ_カレントと会社マスタ_予約があって

会社マスタ_カレント:
会社CD=01、会社名=▲▲▲▲▲

会社マスタ_予約:
会社CD=01、適用日=6/1、会社名=▽▽▽▽▽
会社CD=01、適用日=7/1、会社名=■■■■■
会社CD=01、適用日=9/4、会社名=○○○○○

てなってて、日付=6/20でマスタを取得すると、"▽▽▽▽▽" が欲しい、て
ことなんジャマイカ?


329 名前:NAME IS NULL mailto:sage [2007/06/16(土) 00:49:00 ID:???]
>>319
SELECT top 1 * FROM
(SELECT 名称 FROM TableA A
WHERE ID = 指定キー AND 適用年月日 <= 指定日
UNION ALL
SELECT 名称 FROM TableB B
WHERE ID = 指定キー
)
こんな感じか?

330 名前:NAME IS NULL mailto:sage [2007/06/16(土) 10:23:23 ID:???]
A ORDER BY 適用年月日 DESC
ああしもた。いるなあ




331 名前:NAME IS NULL mailto:sage [2007/06/16(土) 10:59:56 ID:???]
>>329
DESCでnullは最初になるんだっけ?最後になるんだっけ?

標準的なSQLで正攻法ならこうだな。

select ID, null from A
where A.ID=指定キー
and not exists (
select * from B B0
where B0.ID=指定キー
and B0.適用年月日<=指定日
)
union all
select ID, 適用年月日 from B
where B.ID=指定キー
and B.適用年月日<=指定日
and not exists (
select * from B1
where B1.ID=B.ID
and B1.適用年月日>B.適用年月日 )


332 名前:NAME IS NULL mailto:sage [2007/06/16(土) 16:51:29 ID:???]
>>331
そのSQLは流石にあかんやろ。。。

333 名前:NAME IS NULL mailto:sage [2007/06/16(土) 22:43:56 ID:???]
ん?なんかおかしいところあった?
環境の違いによらずに安定したパフォーマンスが出るよう書いたつもりだけどね。

334 名前:NAME IS NULL mailto:sage [2007/06/16(土) 23:01:09 ID:???]
全然関係ないけどぉ、最近のOracleはSQLが拡張されまくってて便利つーか
ワケワカランつーか、全然追いつけない。

>319 の質問も、例えば環境を最新のOracle(10G?)に限定すればなんか使える
独自機能ないかなぁとオモテ調べてみたけど2分で挫折

335 名前:NAME IS NULL mailto:sage [2007/06/17(日) 11:04:55 ID:???]
>>333
問題ないと思うよ


336 名前:NAME IS NULL mailto:sage [2007/06/17(日) 13:18:07 ID:???]
>>333
>>335

下のほうのBテーブルから取ってくるところの
existsの中が間違ってるだろ。
指定する日付がBテーブルに存在する全ての適応日より
大きいなら欲しい結果が返ってくるけどね。


337 名前:NAME IS NULL mailto:sage [2007/06/17(日) 19:42:29 ID:???]
>>336
あ、なるほど。

and B1.適用年月日<=指定日

が抜けてたってだけか。

338 名前:NAME IS NULL mailto:sage [2007/06/18(月) 15:35:48 ID:???]
329と331って、なんとなく感覚的に331のほうがコスト高い気がするけど。
top nはsqlserver?oracleだと329をさらにselectで括ってrownum=1で抽出
か。sqlserverがあればサックリコスト見れるんだけど。

339 名前:NAME IS NULL mailto:sage [2007/06/18(月) 22:19:39 ID:???]
あぁもう効率考えるの鬱陶しいから1時間に1回バッチ処理しちまえっ。お前ら10分間待てっ。
バッチ処理中の処理要請?そんなのキューに10分だけ溜めとけっ。
後でエラーは返送するから再入力よろしくっ。

…って、全部キューに溜め込んだ方が単純でいい?
…あれ?それぐらいCOBOLで30年前からできてる?
…え?FTPで都度転送するだけで仕様満たしちゃう?

嗚呼、汎用機万歳orz

340 名前:NAME IS NULL mailto:sage [2007/06/18(月) 23:33:04 ID:???]
まあ、unionとか使い出すとCOBOLやらRPGの方が性能出るだろうなぁ。



341 名前:NAME IS NULL [2007/06/18(月) 23:37:57 ID:n2nHvTvM]
SQLで、ある行の前後のデータをとってくるうまい方法はありますか。
たとえば
select id from blog_table where date = '2007-01-01';
というSQLを実行して id = 123 という結果が得られたとします。
そして、
select * from blog_table order by date;
というSQLを使って、dateで全データをソートしたうえで、id = 123 である行の前後の行をとってきたいのです。
今はうまい方法が思い浮かばないので、SQLだけでなくRubyとかを使って
list = execute('select * from blog_table order by date') # 全部とってくる
i = list.each_with_index { |v, i| break i if v == 123 } # データのindexを見つける
prev_data = list[i-1] # 前の行
next_data = list[i+1] # 次の行
としているのですが、どう考えても無駄すぎるので、うまい方法があれば教えてください。


342 名前:NAME IS NULL mailto:sage [2007/06/19(火) 00:55:13 ID:???]
>>341
dateは一意?

343 名前:NAME IS NULL mailto:sage [2007/06/19(火) 01:37:37 ID:???]
同じ値が無けりゃ、未満で最大とより大きい最小をもってくりゃいいな

344 名前:NAME IS NULL mailto:sage [2007/06/19(火) 01:51:23 ID:???]
table名から察するにdateがdate型なら一意じゃなさそう。
dateが一意じゃなく複数ある場合、その順序は概ね一定になるが保証されているわけじゃない。

ブログの<link rel="next">と<link rel="prev">の分を抽出したいのなら、
記事毎にインクリメント(歯抜けあり)されているであろうidを使った方が早くね。

WHERE id = (SELECT max(id) FROM blog_table WHERE id < 123)
OR id = (SELECT min(id) FROM blog_table WHERE id > 123);

dateが一意なら上に挙げたSQL文のidをdateに変更すればおk。

まぁidが必ずしもdate順に並んでいない場合もあるだろうから、厳密にしたいのなら
min(date)で取り出した複数行の中からmin(id)を選ぶとか。
SQLで一発抽出も可能だが、DBのなかに記事はあるけど未公開になってる
とか、その他いろいろな条件も増えてWHEREが無駄に複雑になるから、
SQLである程度絞り込んだら、ホスト言語(Ruby)側で処理させる方が楽っぽ。

345 名前:NAME IS NULL [2007/06/19(火) 16:06:08 ID:nZn4pPC5]
数値をカンマ区切りにしたいんですけど、できますか?

346 名前:NAME IS NULL mailto:sage [2007/06/19(火) 16:13:01 ID:???]
to_char(num, '999,999,999');
とかでどうか

347 名前:NAME IS NULL [2007/06/19(火) 18:41:50 ID:JyFlQMM7]
月の検索ってどうやったら良いですか?
「誕生日の近い人一覧」を表示したいのですが、
データベースに「1982-12-01」(データ型は日付)で入っていて、
年を無視して月のみで検索できずに悩んでます。

348 名前:NAME IS NULL mailto:sage [2007/06/19(火) 18:51:20 ID:???]
>>347
where Month(日付)  = ?
Month()は日付から月だけを抜き出す関数の意味。標準じゃないから各DBMSのマニュアルで調べる。
ただし、この方法では日付に索引があってもつかわれないから、
頻繁にこの問い合わせをする必要があるなら、
別に月だけのフィールドをテーブルに追加して索引を作っておく。

349 名前:NAME IS NULL mailto:sage [2007/06/19(火) 18:54:42 ID:???]
where to_char(hiduke, 'MM') = '01'
とか。

>>348も書いてるけどこのままじゃインデックスが使えないので
to_char(hiduke, 'MM') に対してインデックスを張るとか工夫が必要。

350 名前:NAME IS NULL mailto:sage [2007/06/19(火) 19:06:19 ID:???]
日付関係はDBMSで違っていてほとんど統一が取れてないから
DBの種類は書いといたほうがいい。



351 名前:NAME IS NULL mailto:sage [2007/06/19(火) 19:30:02 ID:???]
「誕生日に近い人」なら月よりも、その年の通算日数の方がよくね?
EXTRACT(DOY FROM 誕生日) 又は date_part('doy',誕生日);
月末基準で調べても、翌月初旬の日を出てくるし。

ex.) 誕生日が10日以内の人
SELECT * FROM Table
WHERE EXTRACT(DOY FROM 誕生日) - EXTRACT(DOY FROM CURRENT_TIMESTAMP)
BETWEEN 0 AND 10;

352 名前:347 mailto:sage [2007/06/20(水) 11:01:23 ID:???]
たくさんの回答に感謝です。
とても参考になりました。
ありがとうございます。
やり方もたくさんあるのですね。
決まった形が無いみたいで、自分みたいな初心者には、とても難しく感じますが、
がんばろうと思います。
お返事、遅れてしまい申し訳ありませんでした。


>>351
いわれて見るまで、気がつかなかったです。
そうですね。月末の事を考えると、この形式がベストみたい。
ありがとうございます。
 
>>350
DBは、postogresu使用です。
教えていただいたSQLが通ったので、よかったですが、
次回からはDBの種類も記入することにします。
ご指摘、ありがとうございます。

>>348,349
「インデックスを張る」ですか。
うーん。ちょっと難しそうなのと、>>351の方法で解決したので今回はなしで行きたいと思います。
インデックスについて、また調べてみますね。
勉強になりました。ありがとうございます。

353 名前:351 mailto:sage [2007/06/20(水) 19:30:41 ID:???]
>>352
postogresuってなんだよー。
まぁ俺も怪しい日本語が混じってたが。

で、インデックスを無視していたのでちょっと老婆心的補足。
誕生日通算日数の関数インデックスを作って、
CREATE INDEX birthday_doy_idx FROM Table(EXTRACT(DOY FROM 誕生日));

>>351で書いたSQLをちょっと変更。
SELECT * FROM Table
WHERE EXTRACT(DOY FROM 誕生日)
BETWEEN EXTRACT(DOY FROM CURRENT_TIMESTAMP)
AND EXTRACT(DOY FROM CURRENT_TIMESTAMP)+10;

とすれば、インデックスを使って抽出するようになる。
--元質の人はもう見てないだろうけどなぁ。

354 名前:NAME IS NULL mailto:sage [2007/06/21(木) 23:42:17 ID:???]
SELECT TbmSection.SectionID, TbmSection.SectionCode, TbmSection.SectionName
FROM TbmSection INNER JOIN
( SELECT SectionID FROM TbmAssignSection WHERE DeleteFlg = 0
UNION
SELECT SectionID FROM TbmSectionExecutive WHERE EmployeeID = '000000' )
test_tbl ON test_tbl.SectionID = TbmSection.SectionID
WHERE TbmSection.DeleteFlg = 0

このようなSQL文を実行するとします。
下から二行目にUNIONで結合させたテーブル名にtest_tblと別名をつけていますが、
これを別名をつけずに実行しようとするとエラーになるのです。
実行環境はEnterprise Managerです。
ちなみに、別名をつけずに実行すると、Enterprise Managerが別名(test_tbl)があった
位置に勝手にDERIVEDTBLを付けてそれもまたエラーになってしまいます。

'これがその例です↓
DERIVEDTBL ON TbmAssignSection.SectionID = TbmSection.SectionID

長々と若干意味不明に書いてしまいましたが、要はtest_tblという別名を付けずに冒頭
のSQL文を正常に動作させたいのですが、なんとかならないものなのでしょうか?
テーブル定義書も無い中、解答が得られるとは考えにくいのですがわかる方いらっしゃった
らぜひお願いします。

355 名前:NAME IS NULL [2007/06/21(木) 23:47:04 ID:T2K/E1DB]
現在学校でSQL Server の勉強をやってるんですが自宅でも勉強したいのですが無料で軽いフリーソフトがありましたら教えてください


356 名前:NAME IS NULL mailto:sage [2007/06/22(金) 00:00:10 ID:???]
>>355
>>281-285

357 名前:355の者です [2007/06/22(金) 00:14:12 ID:Jkf5KiTi]
先週ヤフオクでSQLの参考書(やさしいSQL入門)というのを購入したんですが
内容がSQL Serverのことが全然書かれてなかったので別の参考書を購入しようかと検討中なんですがお勧めの参考書ってありませんか?
問題と説明が詳しく書かれているのがありましたら教えてください

358 名前:NAME IS NULL mailto:sage [2007/06/22(金) 06:35:51 ID:???]
>>357
普通にDBマガジンとかWEB+DBPRESSとか雑誌を買えよ。

359 名前:NAME IS NULL mailto:sage [2007/06/22(金) 06:48:27 ID:???]
>>357
技術本、参考書のたぐいは
自分に合う合わないが有るから
本屋で立ち読み汁。


360 名前:NAME IS NULL mailto:sage [2007/06/22(金) 09:25:33 ID:???]
>>358
そういう雑誌って初心者が見ても楽しめますかね?



361 名前:NAME IS NULL mailto:sage [2007/06/22(金) 11:14:57 ID:???]
むしろ初心者向け情報が中心という気もする。
初心者と言わないでも、DB屋さん以外のPGとかが本棚に置いとくくらいには。

あと、定期的(毎年3〜4月号あたりかな?)に、初心者向け特集をやる技術系雑誌は多いと思う。

362 名前:NAME IS NULL mailto:sage [2007/06/22(金) 11:49:37 ID:???]
>>361
ありがとうです。大学の図書館にあるか見てきますノシ

363 名前:NAME IS NULL [2007/06/22(金) 13:54:53 ID:H0pevYdj]
Apache+Mysqlで原因不明のエラーが出るのだが
[error] [client] ( owner = 2 OR access IN ('PUBLIC', 'LOGGED_IN', 'user2') ) AND (weblog IN (1))

構文として間違っているのなら指摘してくれ
構文としておkなら考えられる原因を指摘してくれ
色々と初心者な上、オープンソースのプログラムを使ってるからよく分からんのじゃ

364 名前:NAME IS NULL mailto:sage [2007/06/22(金) 14:22:30 ID:???]
>原因不明のエラー
こっちを詳しく

365 名前:NAME IS NULL [2007/06/22(金) 14:51:53 ID:H0pevYdj]
>>364
詳しくと言われてもApacheのエラーログに出てくるのはコレだけなんだ
[error] [client] ( owner = 2 OR access IN ('PUBLIC', 'LOGGED_IN', 'user2') ) AND (weblog IN (1))

PHPでMYSQLにアクセスしているみたいなのだが
エラー出力がこれだけだとどうにも対応できず、ここに来てしまった

366 名前:NAME IS NULL mailto:sage [2007/06/22(金) 15:00:48 ID:???]
そういう時はコマンドラインでもGUIでもいいからそのDBで
手でSQLを実行してみればいい
それはSQLの一部でしかないので、全体がわからんとあれだけど
前の行には出てないの?
あとMySQLのバージョンも書いてくれ

367 名前:NAME IS NULL mailto:sage [2007/06/22(金) 15:27:19 ID:???]
>>363
Apache + MySQLとはいえ、
PHPで何かのスクリプトをApacheから動かしてるから
エラーがApacheのログに残ってるんだろ?
なんてスクリプトなのかもうちょっと詳しく。

エラーにある内容はWhere句の式としては
妥当である可能性は高いけれど。


368 名前:NAME IS NULL [2007/06/22(金) 15:31:21 ID:H0pevYdj]
>>366
全体は分からんけど、とりあえず探してみる。
一つのPHPファイルに記述されているのはそれくらいで
RequireやらIncludeで辿ると膨大な数のファイルでちょっと無理かもしれんが・・・

何度そのPHPを実行しても出てくるのはその一行だけ。
Mysqlのバージョンは6.0Alpha

369 名前:NAME IS NULL [2007/06/22(金) 15:41:47 ID:H0pevYdj]
>>367
$friends = run("friends:get",array($page_owner));
if (!empty($friends)) {
$where2 = "weblog IN (" ;
$first=true;
foreach($friends as $friend) {
if (!$first) {
$where2 .= ", ";
}
$where2 .= $friend->user_id;
$first=false;
}
$where2 .= ")";
$extensionContext = trim(optional_param('extension','weblog'));
$where3 = "";
if(is_array($CFG->weblog_extensions)){
if($extensionContext!='weblog' && array_key_exists($extensionContext,$CFG->weblog_extensions)){
if(array_key_exists('type',$CFG->weblog_extensions[$extensionContext])){
$extraType = $CFG->weblog_extensions[$extensionContext]['type'];
$where3 = "AND ident IN(select ref FROM ".$CFG->prefix."tags WHERE tagtype='weblog' AND tag=".$db->qstr($extraType).")";
}
}
else{
$nofilter = array();
foreach($CFG->weblog_extensions as $key => $value){
if($key!='weblog' && array_key_exists('type',$value)){
$nofilter[] = $value['type'];
}
if($key!='weblog' && array_key_exists('values',$value)){
if(is_array($value['values'])){
$nofilter=array_merge($value['values'],$nofilter);
}
else{
$nofilter[] = $value['type'];
}
}
}
if(!empty($nofilter)){
$nofilter = implode(',',array_map(array($db,'qstr'),$nofilter));
$where3 = "AND ident not IN(select ref FROM ".$CFG->prefix."tags WHERE tagtype='weblog' AND tag in (".$nofilter."))";
}
}
}

$where1 = run("users:access_level_sql_where",$_SESSION['userid']);
error_log('('.$where1.') AND ('.$where2.') '.$where3);
$posts = get_records_select('weblog_posts','('.$where1.') AND ('.$where2.') '.$where3,null,'posted DESC','*',$weblog_offset,POSTS_PER_PAGE);
$numberofposts = count_records_select('weblog_posts','('.$where1.') AND ('.$where2.') ' .$where3);

正直このerror_logが怪しくなってきた・・・
これ消すだけで解決したらすまん。

370 名前:NAME IS NULL [2007/06/22(金) 15:43:08 ID:H0pevYdj]
if (!empty($posts)) {

$lasttime = "";

foreach($posts as $post) {

$time = gmstrftime("%B %d, %Y",$post->posted);
if ($time != $lasttime) {
$run_result .= "<h2 class=\"weblogdateheader\">$time</h2>\n";
$lasttime = $time;
}

$run_result .= run("weblogs:posts:view",$post);

}

$weblog_name = htmlspecialchars(optional_param('weblog_name'), ENT_COMPAT, 'utf-8');

if ($numberofposts - ($weblog_offset + POSTS_PER_PAGE) > 0) {
$display_weblog_offset = $weblog_offset + POSTS_PER_PAGE;
$back = __gettext("Back"); // gettext variable
$run_result .= <<< END

<a href="{$CFG->wwwroot}{$weblog_name}/{$extensionContext}/friends/skip={$display_weblog_offset}"><< $back</a>
<!-- <form action="" method="post" style="display:inline">
<input type="submit" value="<< Previous 25" />
<input type="hidden" name="weblog_offset" value="{$display_weblog_offset}" />
</form> -->

END;
}
if ($weblog_offset > 0) {
$display_weblog_offset = $weblog_offset - POSTS_PER_PAGE;
if ($display_weblog_offset < 0) {
$display_weblog_offset = 0;
}
$next = __gettext("Next"); // gettext variable
$run_result .= <<< END

<a href="{$CFG->wwwroot}{$weblog_name}/{$extensionContext}/friends/skip={$display_weblog_offset}">$next >></a>

END;
}

}
else{
$type =(isset($extraType))?$extraType:$extensionContext;
$run_result = "<p>".sprintf(__gettext("Your friends currently don't have any %s"), strtolower($type))."</p>";
}
}

上下少し省いたけどこんな感じ



371 名前:NAME IS NULL [2007/06/22(金) 15:49:12 ID:H0pevYdj]
解決した
誰がどう見てもPHPにErrorを出力するスクリプトが書いてあっただけですね
だめだ俺・・・早くなんとかしないと・・・

もう済んでしまったことはしょうがないので今後気をつけます
スレ汚し失礼しますた

372 名前:NAME IS NULL mailto:sage [2007/06/22(金) 16:01:52 ID:???]
ハゲワロス

373 名前:NAME IS NULL mailto:sage [2007/06/22(金) 16:14:03 ID:???]
デバッグならcgiやphpやjspでSQLをstderrに出すのはよくやる。
残ってたって事か。しかしこのスレで延々とPHPのソース貼られても・・・

374 名前:NAME IS NULL mailto:sage [2007/06/23(土) 17:09:42 ID:???]
以下の様にUNIONの結果をソートすると劇的に速度低下してしまいます。

SELECT 商品名,値段,産地FROM 肉
UNION ALL
SELECT 商品名,値段,産地 FROM 魚介
 ORDER BY 値段

上記クエリは簡略例ですがUNION結果に対するORDER BYは必須です。
ORACLE9です。ヒントでもいいので情報ください。

375 名前:NAME IS NULL mailto:sage [2007/06/23(土) 17:16:05 ID:???]
SELECT 商品名,値段,産地FROM 肉 ORDER BY 値段
UNION ALL
SELECT 商品名,値段,産地 FROM 魚介 ORDER BY 値段

ってすればいいんでね?


376 名前:NAME IS NULL mailto:sage [2007/06/23(土) 18:23:49 ID:???]
>>375
合わせた結果をソートしたものと、各々ソートしたものを合わせた
結果が同じとは限らんだろ。

そもそもそんな書き方できないし。

>>374
個々のテーブルのソートは早いの?

377 名前:NAME IS NULL mailto:sage [2007/06/23(土) 18:31:11 ID:???]
>> 376
個々のテーブルのソートは早いです(Indexあり)
ただUnionした結果に対してのソートは遅いです。
データ件数(Unionした結果件数)に比例して速度低下しています。

378 名前:デフォルトの名無しさん [2007/06/23(土) 19:45:13 ID:jr0+yJsz]
ご教授ください。
予算テーブルが
予算(年月、予算項目、予算金額);年月、予算項目が主キー
となっており、例えば
2007年6月、水道費、5000
2007年6月、光熱費、7000
2007年6月、食費、12000
とあって、縦持ちのテーブルを横持ちで↓

      水道費  光熱費  食費   
2007年6月  5000   7000   12000

と表示したい場合のSQL文を教えてください。


379 名前:NAME IS NULL mailto:sage [2007/06/23(土) 19:51:53 ID:???]
>>377
UNIONしたVIEWにINDEX張ればいいんでね?

380 名前:NAME IS NULL mailto:sage [2007/06/23(土) 20:24:55 ID:???]
9iはviewにインデックスなんて張れるんだっけか?



381 名前:NAME IS NULL mailto:sage [2007/06/23(土) 20:55:03 ID:???]
viewにindex張れるのってSQL Serverだけ?

382 名前:NAME IS NULL mailto:sage [2007/06/24(日) 11:16:31 ID:???]
>>378


oraclesqlpuzzle.hp.infoseek.co.jp/9-1.html
相関サブクエリを使用する方法はpostgresでも動きます。
ただ、このパターンだと横列数(予算項目数分)を
ハードコーディングする必要がありますね。

oraclesqlpuzzle.hp.infoseek.co.jp/10-75.html
階層問い合わせを使う方法はOracleでないと動作しないと思います。
このパターンは横列数は意識しませんが、指定文字をセパレータとして
1カラムとしてデータを出力します。

メンテナンス性、可読性を踏まえてプログラム側で出力加工してみては?

383 名前:NAME IS NULL mailto:sage [2007/06/24(日) 11:44:37 ID:???]
>>378 クロス集計ですね。

select 年月,

sum(
case
when 予算項目 = 水道費 then 予算金額
else 0
end) as 水道費,

from 予算テーブル group by 年月;

384 名前:378 [2007/06/24(日) 15:11:37 ID:+uq9wgbc]
>>382,383
ご教授ありがとうございました。
参考にさせていただきます。


385 名前:NAME IS NULL mailto:sage [2007/06/25(月) 12:00:58 ID:???]
ご教授とは - 大辞林 第二版 (三省堂) からの引用

(1) (ア) 児童・生徒に知識・技能を与え、そこからさらに知識への興味を呼び起こすこと。(イ) 専門的な学問・技芸を教えること。「国文学を―する」「書道―」
(2) 大学などの高等教育機関において、専門の学問・技能を教え、また自らは研究に従事する人の職名。助教授・講師の上位。

ご教示とは - 大辞林 第二版 (三省堂) からの引用

(1) [「きょうし」とも] おしえしめすこと。示教。「御―を賜りたく」
(2) 実験・調査で、研究者の意図する行動を被験者にとらせるための指示。

386 名前:NAME IS NULL mailto:sage [2007/06/25(月) 13:22:12 ID:???]
>385

引用だけの文章は違法。

387 名前:NAME IS NULL mailto:sage [2007/06/25(月) 14:04:07 ID:???]
引用先が書いてあればOK
元は紙媒体のケースもあるし

388 名前:NAME IS NULL mailto:sage [2007/06/25(月) 14:22:39 ID:???]
>>387
質量ともに文章の本体が主、引用される物が従、
でなければ著作権違反に問われる可能性がある。
ttp://qrl.jp/?265873

389 名前:NAME IS NULL mailto:sage [2007/06/25(月) 15:38:56 ID:???]
さあ、通報した。

390 名前:NAME IS NULL mailto:sage [2007/06/25(月) 20:20:11 ID:???]
>>388
あーつまり、引用ってのは、利用する側の著作物が主、利用される側の著作物が従の関係のものを言う訳だ。
まとめると、
・385は引用では無い。
・386は間違っている(引用と言うからには利用される側の著作物が従であり、これは違法にならない)。
・388のリンク先ではモンタージュ写真の場合についてのみ語られている(385の場合ではどうなるかは正確には不明)。
・385は著作権違反に問われる可能性がある(素人考えだがモンタージュ写真だろうが辞書の内容だろうが俺は同じに思える)。
という事か。

後385は、辞書では無く↓(教授 教示でググって最初に出たサイト)のコピーに見える。
ttp://blogs.wankuma.com/jeanne/archive/2005/11/24/19566.aspx



391 名前:NAME IS NULL mailto:sage [2007/06/26(火) 00:46:24 ID:???]
 皆様のお力をお貸しください。

 下記3テーブルがSQL Server 2005 Expressをインストールしたテーブル上にあります。

[製品マスタ]
製品名/生産親品番/製品タイプ/シリーズ/電圧記号/容量記号/特性1/特性2/特性3/サイズ記号/ユーザーコード/加工記号/社内管理識別記号/サイズ1/サイズ2
--------------------------------------------------------------------------------------------------------------------------
AAB1A100AAA/AAB1A010AAA/A/AB/1A/100/A/A/A/////1/1
AAB1A100AAA/AAB1A010AAA/A/AB/1A/100/A/A/A///TA//1/1
AAB1A100AAA      A/AAB1A100AAA      A/A/AB/1A/100/A/A/A////A/1/1
AAB1A100AAA1TA   A/AAB1A100AAA      A/A/AB/1A/100/A/A/A///TA /A/1/1
                             ・
                             ・

[注文テーブル]
注文番号/ 注文品番/分納番号/数量
-----------------------------
1/AAB1A010AAA/1/10
1/AAB1A010AAA/2/10
2/AAB1A010AAA1TA/1/3
3/AAB1A010AAA1TA   A/1/10
                             ・
                             ・

[進捗管理テーブル](工程管理コードが1000以上は2次加工品。それ以下は半製品)
製造日番/生産品番/工程管理コード/在庫数/良品数 
------------------------------------------
12345-03/AAB1A010AAA/1220/15/
12345-01/AAB1A010AAA1TA/1220/1/
23456-03/AAB1A010AAA/1100//5
23456-02/AAB1A010AAA1TA/1100//1
23456-01/AAB1A010AAA1TA   A/1100//2
45678-00/AAB1A010AAA/990//30
                             ・
                             ・

そこから下記のような

注文番号/ 注文品番/分納番号/数量/出荷予定製造日番
---------------------------------------------
1/AAB1A010AAA/1/20/12345-03
1/AAB1A010AAA/2/10/12345-03
1/AAB1A010AAA/2/10/23456-03
2/AAB1A010AAA1TA/1/3/12345-01
2/AAB1A010AAA1TA/1/3/23456-02
2/AAB1A010AAA1TA/1/3/45678-00
3/AAB1A010AAA1TA   A/1/10/23456-01
3/AAB1A010AAA1TA   A/1/10/45678-00
                             ・
                             ・

結果を取り出したいのですが、どのようなSQLを書いてよいものかわかりません。
もし、SQLだけで不可能なら、どこまでをSQL上で処理しますか?

ご指導のほどよろしくお願いいたします。

392 名前:NAME IS NULL mailto:sage [2007/06/26(火) 01:33:18 ID:???]
>>391
製品マスタにプライマリキーのような物が見あたらね。
-- 複合で出せないわけではなさそうだが。
いったいマスタテーブルと他のテーブルとをどう関連付けりゃいいのやら。
出力例の1行目の数量が20になってのもイマイチ不明。
なんか、マスタの親品番を再帰的に掘っているようにも見えるが、再帰するときの条件も不明瞭。

設計からやり直した方がよだそうだな。

393 名前:391 mailto:sage [2007/06/26(火) 04:03:22 ID:???]
>>392殿

先ほどは各テーブルの要点になりそうなところだけを抽出したため、こんな感じになってしまいました。

実際のテーブルは以下のとおりです。


[注文テーブル]注文番号(PK)/ 注文品番/受注数量/注残数量/...
             └───┐
[引当基本情報テーブル]注文番号(PK)/引当番号(PK)/ 出荷予定品番/引当数量/...
                   │         │          └──────────┐
                   │         │                           │
[引当詳細情報テーブル]注文番号(PK)/引当番号(PK)/明細行番号(PK)/製造日番/...     │
                ┌─────────────────────┘        │
[進捗管理テーブル]製造日番(PK)/品番/工程管理コード/在庫数/良品数...            │
                                                         │
          ┌───────────────────────────────-┘
[製品マスタ]製品名(PK)/生産親品番/製品タイプ/シリーズ/電圧記号/容量記号/特性1/特性2/特性3/サイズ記号/ユーザーコード/加工記号/社内管理識別記号/サイズ1/サイズ2/...


394 名前:391 mailto:sage [2007/06/26(火) 04:04:04 ID:???]
・製品を大きく分けて3つに分けています。(コードの数字が大きいほど完成品に近い)
 ・在庫(工程管理コード:1220)
 ・2次加工仕掛品(工程管理コード:1200〜1000)
 ・1次加工仕掛品(工程管理コード:990〜0) 

・製造日番は各製品の不足合計を生産親品番でまとめて計上することになっています。
 計上した製造日番は"AAAAA-00"で工程管理コード0番から1次加工品工程を進め、工程管理コード990が完了後、2次加工で必要な分を"AAAAA-01"見たいな形で分割し、加工して倉庫へ入庫ます。

・生産親品番は
  製品タイプ+シリーズ+電圧記号+容量記号+特性1+特性2+特性3+サイズ記号+社内管理識別記号

  製品タイプ+シリーズ+電圧記号+容量記号+特性1+特性2+特性3+ユーザーコード+社内管理識別記号
で求めることができます。(ただし、サイズ記号orユーザーコードと社内管理識別記号との間はスペースで区切り、社内管理識別記号は18文字目になければならないというルールがあります)


 で、現在、どの注文にどの製造日番を割り当てるかを決めるSQL文を考えていたのですが、さっぱり考え付かず、ここに質問させていただいた次第です。

395 名前:392 mailto:sage [2007/06/26(火) 06:08:47 ID:???]
>>393-394
すまんが、そうゴチャゴチャ書かれても、理解する気力ない。
てか、>>391の製品マスタ.製品名のAAB1A100AAAは2行あるように見えるが?

とりあえず 最後の「どの注文にどの製造日番を割り当てるか」だけ注目して
他の余計な物をバッサリと捨てた。参考になるかどうかワカランが。

注文テーブル(正確に言うと受注残テーブルかな)
 注文番号 注文品番 注文数量

進捗管理テーブル(まだ在庫がある製造分と、これからの予定分...?)
 製造日番 製造品番 製造数量(在庫分のみ?)

SELECT T3.*,T4.製造日番 FROM
(
SELECT *,
COALESCE((SELECT sum(製造数量) FROM 注文テーブル WHERE 製造日番<T1.製造日番 AND 製造品番=T1.製造品番),0)AS ptotal,
COALESCE((SELECT sum(製造数量) FROM 注文テーブル WHERE 製造日番<=T1.製造日番 AND 製造品番=T1.製造品番),0)AS ntotal
FROM 注文テーブル AS T1
) AS T3
FULL JOIN
(
SELECT *,
COALESCE((SELECT sum(注文数量) FROM 進捗管理テーブル WHERE 注文番号<T2.注文番号 AND 注文品番=T2.注文品番),0)AS ptotal,
COALESCE((SELECT sum(注文数量) FROM 進捗管理テーブル WHERE 注文番号<=T2.注文番号 AND 注文品番=T2.注文品番),0)AS ntotal
FROM 進捗管理テーブル AS T2
)AS T4
ON (T3.製造品番=t4.注文品番 )
WHERE T4.ntotal BETWEEN T3.ptotal AND T3.ntotal
OR T4.ptotal >T3.ptotal
ORDER BY T4.注文番号;

製造日番と注文番号はユニークで昇順に処理していく。
また、納入済み分の処理などを考えるとさらに複雑になるヨカソ。
最後になんだが、SQL鯖使いじゃないので、SQL鯖で動くかどうかもワカラン。


396 名前:392 mailto:sage [2007/06/26(火) 06:30:01 ID:???]
あや、一部訂正。
製造数量(在庫分のみ?) → 製造数量(製造済み分は残っている在庫分のみ)
意味通じるかなぁ?

× WHERE T4.ntotal BETWEEN T3.ptotal AND T3.ntotal
○ WHERE T4.ntotal BETWEEN T3.ptotal+1 AND T3.ntotal
まぁ、WHERE (T4.ntotal > T3.ptotal AND T4.ntotal <= T3.ntotal) でもいいんだけど。

で、これ以上突っ込まれて聞かれても俺は答える気力ない。
と、先に断っておく、スマソ。

397 名前:392 mailto:sage [2007/06/26(火) 07:35:56 ID:???]
何度もスマソ。WHRER句のOR以下もおかしいな。一つにまとめて
WHERE (T3.ptotal < T4.ntotal AND T3.ntotal > T4.ptotal)
ORDER BY order_num;

って一つじゃないか。もう、頭まわってね...orz
まだ間違ってるかも。



398 名前:NAME IS NULL mailto:sage [2007/06/28(木) 14:42:43 ID:???]
SELECT *
FROM テーブル
WHERE フィールド1 = 条件文
  OR フィールド2 = 条件文
  OR フィールド3 = 条件文


で検索した結果で、何に引っかかって表示されているのか調べる方法はないですか?
ずららーっと、結果は問題なく表示されてるけど、どの検索条件に一致しているのかを知りたい。

399 名前:NAME IS NULL mailto:sage [2007/06/28(木) 16:14:23 ID:???]
>>398
取得するカラムの1つをCASE式で評価して
適当なフラグ立てると良いんじゃね?


400 名前:398 mailto:sage [2007/06/28(木) 17:41:46 ID:???]
ありがとう。
やってみる!



401 名前:NAME IS NULL [2007/06/29(金) 19:17:50 ID:0VuwylaN]
住所 結婚
-------------
埼玉 未婚
群馬 既婚
埼玉 未婚
山梨 既婚
東京 既婚

こんな感じのデータを
↓のようなデータに表にまとめたいのですが、どのようなSQL文を書けばよいですか?

住所 既婚 未婚
----------------------
・・・・
群馬 3104 1202
埼玉 7937 3929
千葉 6113 3797
東京 9232 7088
山梨 2987 1022
・・・・

402 名前:NAME IS NULL mailto:sage [2007/06/29(金) 20:05:09 ID:???]
select 住所
    ,sum(case when 結婚='既婚' then 1 else 0 end) 既婚
    ,sum(case when 結婚='未婚' then 1 else 0 end) 未婚
from テーブル
group by 住所;

403 名前:NAME IS NULL mailto:sage [2007/07/01(日) 08:47:40 ID:???]
phpMyAdminでテーブルの作成日時と最終更新日が表示されていますが
システム関数みたいなもので取得できるのでしょうか。

404 名前:NAME IS NULL mailto:sage [2007/07/02(月) 03:13:23 ID:???]
Enterprise Manager のクエリ実行で出てくる
DERIVEDTBL とは一体なんなんでしょうか? ヘルプ見ても載っていないし、
検索しても海外のサイトばっかりで訳わかめです(;´Д`)

405 名前:NAME IS NULL [2007/07/02(月) 20:19:15 ID:RRdUYWi/]
とある Access2003 のデータベースにて、

SELECT * FROM 1 WHERE ホゲホゲ > 1

といった操作を行うと適切なデータが返されます。

しかし、

SELECT * FROM 1 WHERE 1.ホゲホゲ > 1

といった操作を行うと、

クリエ式1 「1.ホゲホゲ > 1」 の構文エラー:演算子がありません

といったエラーが返されます。

どういった原因により構文エラーが発生しているのでしょうか。
よろしくお願いします。

406 名前:NAME IS NULL mailto:sage [2007/07/02(月) 20:31:03 ID:???]
あなた、何をしたいの?

407 名前:NAME IS NULL mailto:sage [2007/07/02(月) 20:54:04 ID:???]
>>403
show table status like 'テーブル名';

>>404
derived table (導出表?)
クエリから導き出されるテーブルとかそんな意味合いだったと思う

>>405
[1].ホゲホゲ

全部RDBMS依存なんで次からは適切なスレを探してね

408 名前:403 mailto:sage [2007/07/03(火) 02:58:32 ID:???]
>>407 さん
ありがとうございます、取得できました!
descぐらいしか思いつかなかった自分がお恥ずかしい。

409 名前:NAME IS NULL [2007/07/03(火) 11:20:36 ID:kH14UgW7]
Accessで質問です。

データで、「住所」フィールドから都道府県を抜き出したく思い
Accessのフィールドに↓のように書きましたが、うまくいきません。

都道府県: Left([住所],InStr([住所],"都" Or "道" Or "府"Or "県"))

どのようにしたらよいでしょうか?
SQLでもその他の方法でもかまいません。

元データ
東京都新宿区
埼玉県秩父市
東京都杉並区
群馬県高崎市
京都府舞鶴市


抜き出したいデータ
東京都
埼玉県
東京都
群馬県
京都府


410 名前:NAME IS NULL mailto:sage [2007/07/03(火) 12:05:06 ID:???]
>>409
極論を言うとテーブル設計が悪い。
都道府県を切り出す必要があるのなら、
最初から住所は都道府県と市区町村以降は
分離すべきだろ。

SELECT 住所, Max(都道府県) AS 都道府県
FROM (SELECT テーブル1.住所, Left([住所],InStr([住所],"都")) AS 都道府県 from テーブル1 UNION ALL
SELECT テーブル1.住所, Left([住所],InStr([住所],"道")) AS 都道府県 from テーブル1 UNION ALL
SELECT テーブル1.住所, Left([住所],InStr([住所],"府")) AS 都道府県 from テーブル1 UNION ALL
SELECT テーブル1.住所, Left([住所],InStr([住所],"県")) AS 都道府県 from テーブル1
)
GROUP BY 住所;

でパフォーマンスは悪そうだけど、何とか取れるとは思うが。




411 名前:NAME IS NULL [2007/07/03(火) 14:22:42 ID:DZCkMDG+]
>>407

どうもありがとうございます。
おかげで作業を進めることができました。

412 名前:NAME IS NULL [2007/07/03(火) 14:23:22 ID:DZCkMDG+]
↑ >>405 です。

413 名前:NAME IS NULL [2007/07/03(火) 16:46:00 ID:DSeuzHZM]
table名[ list** ]には 列名が[name]の1つだけあります。
いま、list01とlist02の積集合の数を得たいのですが、
「INTERSECTを使って」なるべくシンプルなSQLを教えてくださいm(_ _)m
(DBはSQLiteですが大体Oracle等と同じだと思います)

ちなみに、以下のSQLで得ることはできますが、サブクエリがなんか無駄
な感じがしてしまいます...

SELECT count(name) FROM list01
WHERE name IN
(SELECT name FROM list01 INTERSECT SELECT name FROM list02)

414 名前:NAME IS NULL mailto:sage [2007/07/03(火) 17:33:01 ID:???]
SELECT count(name) FROM (SELECT name FROM list01 INTERSECT SELECT name FROM list02)
SQLiteだとこれでいけたけど。
PostgreSQLだと後ろに名前つけないとならんかった

415 名前:391 [2007/07/03(火) 19:57:35 ID:wpvZa8NM]
>>392殿

 返事が遅くなりまして申し訳ございません。
 教えていただいたSQL文を実際の環境に合わせて実装してみたいと思います。

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

416 名前:404 mailto:sage [2007/07/03(火) 20:28:57 ID:???]
>>407
ご解答ありがとうございました。
少しすっきり致しました

417 名前:NAME IS NULL [2007/07/04(水) 09:42:51 ID:qkT/tPH1]
d_tbl
id | name | status | date
----+------+--------+------------
1 | ahoo | 1 | 2007-07-01
2 | hoge | 4 | 2007-07-01


m_tbl
id | name | order
----+------+-------
1 | 上 | 4
2 | 中 | 3
3 | 下 | 2
4 | 最悪 | 1

select d.name,m.name,d.date from d_tbl as d left join m_tbl as m on d.status = m.id order by d.id,m.order

普段上記でデータを取得して使用しているのですが
追加で作成したシステムでm_tblのIDの並びを4>1>2>3
の順で出力しなくてはならなくなりました。
ですが私の知る限りorder byでそういったことができないと思い
現状データを取得した後プログラムで並び替えを行わせています。
しかしこのままだとデータが増えた際に処理が遅くなるのは目に見えており
なんとかSQLでやりたいのですがどのようにすればできるのでしょうか?

DBはpostgres 8を使用しています。

418 名前:NAME IS NULL mailto:sage [2007/07/04(水) 10:10:25 ID:???]
4123って4種類限定なの?
ORDER BY id = 4 desc, i
とか使えるよ

419 名前:NAME IS NULL mailto:sage [2007/07/04(水) 10:12:49 ID:???]
最後、d が抜けた。 ORDER BY id = 4 DESC, id ASC ね

420 名前:417 [2007/07/04(水) 10:16:13 ID:qkT/tPH1]
>>418
ありがとうございます
実際には10種類ほどあります
id=[番号],で順番を指定できるんですね



421 名前:413 mailto:sage [2007/07/04(水) 10:33:47 ID:???]
>>414
ありがとう!その通りでいけました!FROMのところにサブクエリ使えるんだね・・・。

422 名前:NAME IS NULL mailto:sage [2007/07/04(水) 12:15:28 ID:???]
外部参照キーが自分自身のテーブルにあるカラムをさす場合について質問です。

create table emp(
  id     integer      auto_increment primary key,
  name   varchar(50)  not null,
  mgr_id integer      references emp(id)
);

というテーブルがあったときに

select t0.id, t0.name, t1.id, t1.name from emp t0, emp t1 where t0.mgr_id=t1.id;

とした場合、mgr_idがnullの項目が検索されません。

select t0.id, t0.name, t1.id, t1.name from emp t0, emp t1 where t0.mgr_id is not NULL or t0.mgr_id=t1.id;

とすると、検索結果がおかしいです。
この場合、どのようなSQLを書けばいいでしょうか。
あるいはヒントとなるキーワードを教えてください。


423 名前:NAME IS NULL mailto:sage [2007/07/04(水) 13:26:46 ID:???]
>>422
not外すとどうなる?

424 名前:仕様書無しさん [2007/07/04(水) 13:32:00 ID:fg5TH2Y3]
>>422
なんでnot Nullなん?null項目がでるわけない上に、そりゃぁ検索結果
がおかしいでしょ。

NOTはずすか、外部結合だな。

425 名前:422 mailto:sage [2007/07/04(水) 16:23:43 ID:???]
反応ありがとうございます。
is not nullはis nullの間違いでした。しかしis nullにしてもやっぱり結果がおかしいです。
例えば

mysql> insert into emp values(NULL, 'Foo', NULL);
mysql> insert into emp values(NULL, 'Bar', 1);
mysql> insert into emp values(NULL, 'Baz', 2);
mysql> select * from emp;
+----+------+--------+
| id | name | mgr_id |
+----+------+--------+
| 1 | Foo | NULL |
| 2 | Bar | 1 |
| 3 | Baz | 2 |
+----+------+--------+

のときに、
mysql> select t0.id, t0.name, t1.id, t1.name from emp t0, emp t1 where t0.mgr_id is NULL or t0.mgr_id=t1.id;
+----+------+----+------+
| id | name | id | name |
+----+------+----+------+
| 1 | Foo | 1 | Foo |
| 2 | Bar | 1 | Foo |
| 1 | Foo | 2 | Bar |
| 3 | Baz | 2 | Bar |
| 1 | Foo | 3 | Baz |
+----+------+----+------+

となります。
mgr_idがnot nullであるようなテーブルしか使ったことなかったので、今回の場合はどうしたらいいか分かりません。


426 名前:422 mailto:sage [2007/07/04(水) 16:28:06 ID:???]
>>424
「外部結合」がキーワードのようですので調べてみます。



427 名前:仕様書無しさん [2007/07/04(水) 16:50:28 ID:fg5TH2Y3]
select t0.id, t0.name, t1.id, t1.name
from emp t0 left join emp t1
on t0.mgrid=t1.id

428 名前:422 mailto:sage [2007/07/04(水) 17:02:05 ID:???]
>>427
ありがとうございます。外部結合のleft joinが答えでした。
こんなの知らなかったよー。SQL入門じゃ教えてくれなかったから、中級以上の機能なのでしょう。

where t0.mgr_id = t1.mgr_id を使う場合と比べて、パフォーマンスに違いはありますか。
もしよければ教えてください。

429 名前:NAME IS NULL mailto:sage [2007/07/04(水) 17:02:22 ID:???]
ただ「おかしい」とか書くから、何回もやり取りしなくちゃ解決しないんだ

430 名前:仕様書無しさん [2007/07/04(水) 17:10:25 ID:fg5TH2Y3]
>>428
この程度のコードだとパフォーマンスは変わらないと思う。
SQLはFROM句から評価されていくことは知ってるでしょ?
まずFROM句で直積をとってからWHERE句以降を評価し、最後にSELECT句
で抽出(射影)するから。

でもLEFT JOINには
select … from 表 left join (select… from表 where…)
on ○○ left join (select… from 表 where…) on ○○ 
とか続くのもあるから(というよりそんなのばっかり)、そうなると分からない。



431 名前:NAME IS NULL mailto:sage [2007/07/04(水) 17:10:51 ID:???]
>>428
あんたの学習レベルが低いだけだよ

432 名前:422 mailto:sage [2007/07/04(水) 17:59:56 ID:???]
>>430
丁寧な回答ありがとうございます。
SQLは宣言的だから中の仕組みががblackboxであり、そのためにチューニングで苦労しますよね。
Javaのチューニングだったら簡単なのに。


433 名前:NAME IS NULL mailto:sage [2007/07/04(水) 18:08:47 ID:???]
>>432
プロファイラとかついてるだろ?

434 名前:NAME IS NULL mailto:sage [2007/07/04(水) 18:11:44 ID:???]
LEFT JOIN も知らなかったやつがチューニングの話をするなんて、
何かの冗談ですか

435 名前:NAME IS NULL [2007/07/04(水) 18:40:23 ID:qkT/tPH1]
joinする対象が2つ以上あった場合どのようにして結合したらいいのでしょうか?
select d.*,c.name from
(select a.cid,b.name from Atbl as a left join Btbl as b on a.bid = b.id)
as d left join Ctbl as c on d.cid = c.id;
と書くしかないのでしょうか?

436 名前:NAME IS NULL mailto:sage [2007/07/04(水) 18:42:37 ID:???]
よくわからんが、
FROM xxx
LEFT JOIN yyy ON 〜
LEFT JOIN zzz ON 〜

みたいに並べることはできる。

437 名前:435 [2007/07/04(水) 18:44:01 ID:qkT/tPH1]
>>436
ありがとうございます
並べて書いてみます

438 名前:NAME IS NULL mailto:sage [2007/07/04(水) 20:32:05 ID:???]
>>434
ネタだろwww

・・・と思いたいが、パフォーマンス云々の寝言言う前に
とりあえず実行計画確認してから来いと言いたい訳だがwww


439 名前:NAME IS NULL [2007/07/05(木) 18:16:43 ID:XuEszA9P]
インデックスのパフォーマンスに関する質問です。

性別のように、カーディナリティの低い(とりうる値の種類の少ない)
フィールドはインデックスを使ったほうが遅くなる、
むしろテーブルスキャンのほうが速い、とよく聞きます。

しかし、
select count(gender) from mytable where gender = 1
のように、単純に件数をカウントする場合は、
参照数も少なくて速いように思われるのですが、
こういうクエリが多い場合でも、インデックスは
使用しない方がよいのでしょうか。

440 名前:NAME IS NULL mailto:sage [2007/07/05(木) 19:03:14 ID:???]
>>439
別にインデックス作っても良いんじゃね?



441 名前:NAME IS NULL mailto:sage [2007/07/05(木) 19:42:25 ID:???]
インデックス作っても良いけど(コストベースオプティマイザのDBMSでは)
使われないかもね。

とりあえず作ってみて実行計画と実際の処理時間を
調べてみるのが早いと思うけど。

442 名前:NAME IS NULL mailto:sage [2007/07/05(木) 19:48:40 ID:???]
>>439
別に作ったら作ったで検索は速くなると思うが、その分データの追加の時に
遅くなるからなぁ。

DB2とかは各カラムの統計情報を収集してオプティマイザが働くので、
まあ、性別みたいなのにはINDEXつけなくても、そこそこにスピードでるけど。

実際はRDBMSによって動作はまちまちなんで実行計画で確認汁。

443 名前:NAME IS NULL mailto:sage [2007/07/05(木) 20:07:59 ID:???]
>>439
DBによって違うかな?
PostgreSQLの場合はとインデックスが張られているフィールドでCountしても
必ずテーブル本体を読みに行くので、プランナが判断でインデックス検索を
必要としないと下すと、端からインデックスは使用されない。

Oracleはインデックス検索だけで、Countできるらしいので、その場合は有用かも。
-- 本当かどうか、この質問にも当てはまるかどうかも知らないが、どっかにTipsとして取り上げられてた。

一応PostgreSQLの場合はと限定すれば、
プランナの判断とINSERT時のインデックス構築を考えれば、
使われなさそうなインデックスは張らないほうが得策となる。

444 名前:NAME IS NULL mailto:sage [2007/07/05(木) 21:25:31 ID:???]
性別とかはインデックスはない方がいいと思うけどな〜
更新パフォーマンスがたおちじゃね?(SQL Server)
ttp://www.atmarkit.co.jp/fdb/rensai/drk05/drk05_3.html

445 名前:439 mailto:sage [2007/07/05(木) 21:54:11 ID:???]
>>440-444

回答ありがとうございます。
総合すると、エンジンによって処理が異なるため
一概にどれが正解ということはない、
オプティマイザの結果と相談、ということですね。

さらに、更新時のパフォーマンスとのトレードオフも
考慮すべきと(これはインデックスの一般的な検討事項ですが)。

大変参考になりました。

446 名前:NAME IS NULL [2007/07/05(木) 23:19:50 ID:CfhiNk+E]
ORACLEで
列1だけ共通して、あとはバラバラのテーブルAとBがあって
列1が100のときの
Aの列2、Bの列5の集計を取り出したいとき

SELECT SUM(A.列2) + SUM(B.列5)
FROM A
LEFT OUTER JOIN B
USING(列1)
WHERE A.列1 = 100

で集計した結果と
AとBを別々に集計した結果が異なります

SQL全然触ったことないので
自分的にはWHEREとOUTER JOINの組み合わせが
ミスってるような気がします
職人の方、ご教授お願いします

別々で集計したときは

SELECT SUM(列2)
FROM A
WHERE 列1 = 100



SELECT SUM(列5)
FROM B
WHERE 列1 =100

の結果を集計をしました

(スレ用に可読性を考慮して、わざと全角で記入してます)

447 名前:NAME IS NULL mailto:sage [2007/07/06(金) 00:13:04 ID:???]
>>446

突っ込みどころはいろいろあるけど、

SELECT *
FROM A
LEFT OUTER JOIN B
USING(列1)
WHERE A.列1 = 100

これで出てきた結果セット全てのsum()がとられていると言えば、
なぜおかしい結果になってるかを理解する一番早い方法かと。

基本的に、一意じゃない列同士をjoinすべきではない。
本当にm×nの総当りな結果セットが欲しいときくらい。

448 名前:NAME IS NULL mailto:sage [2007/07/06(金) 11:20:45 ID:???]
こんなん書くの恥ずかしいんですが。。。どなたかお力を。
普段マイナー言語で開発やってて、sql使う機会があまり無い物で。

趣旨は、重複するレコードがあった場合、先頭レコードだけ抽出をしたい。

とあるテーブルに下記の様に4項目持ってたとして、項目1と項目2の値が重複していたら先頭レコードを抽出。

項目1、項目2、項目3、項目4
010,AAA,1000,1
010,AAA,2000,2
010,AAA,3000,3
020,BBB,1000,2
020,CCC,2000,2
030,AAA,2000,3
030,AAA,2000,4
030,AAA,2000,5

上記の様なデータから下記のデータを抜き出したい。
010,AAA,1000,1
020,BBB,1000,2
020,CCC,2000,2
030,AAA,2000,3

SELECT DISTINCT 項目1, 項目2 FROM テーブル
上の様なsql一度書いたのですが、これだと項目1と2しか結果に表示されなくて困ってます。

どなたかお手すきの方ご教授願えれば幸いです。


449 名前:NAME IS NULL mailto:sage [2007/07/06(金) 11:27:36 ID:???]
>>448
先頭レコードの定義は?
ORDER BY 項目3,項目4
の先頭でいいのかな?

450 名前:NAME IS NULL [2007/07/06(金) 12:16:57 ID:KwXXH4Ws]
すみませんがちょっと思いつかないので力を貸してください。

メインはDBはポスグレで後でファイアバードにも対応させなければいけないんですが
とりあえずポスグレターゲットでお願いします。

あるテーブルAがありそのカラムは
YMD Charactor(8) --YYYYMMDD形式で日付を保存
HMS charactor(6) --HHMMSS形式で時間を保存
KEY integer-- Key情報を保存

というテーブルがありこの3つでPrimaryKeyとなります。
このような形式のテーブルで
開始年月日〜終了年月日を指定してKEYをとってきたいのですが BETWEEN 開始日 AND 終了日 を使うのはわかっても
変換の方法がわかりません
たぶんこうなるであろうよそうですが、これでは怒られてしまいました

to_timestamp(YMD + ' ' + HMS ,'YYYY/MM/DD HH:MM:SS') BETWEEN  '#2007/1/1 06:00:00#' AND '#2007/1/1 12:00:00#' 

もしお判りになる方がいらっしゃいましたらご教授願えませんか?



451 名前:448 mailto:sage [2007/07/06(金) 12:41:48 ID:???]
>>449
失礼しました。
項目1と項目2が主キーです。
なので項目3と項目4の内容は問いません。

452 名前:NAME IS NULL mailto:sage [2007/07/06(金) 13:17:52 ID:???]
>>448

テキトーでいいなら
SELECT 項目1, 項目2, min(項目3), min(項目4) FROM テーブル group by 項目1, 項目2

問題がありそうなら
SELECT distinct 項目1, 項目2,
(select top 1 項目3 from テーブル where 項目1 = a.項目1 and 項目2 = a.項目2),
(select top 1 項目4 from テーブル where 項目1 = a.項目1 and 項目2 = a.項目2)
FROM テーブル as a

「top 1」はMSSQLの方言だが、mysqlなら「limit 1」に書き換えるべし。

453 名前:NAME IS NULL mailto:sage [2007/07/06(金) 14:10:06 ID:???]
>>448
PostgreSQL限定(だと思う)でよければ、
SELECT DISTINCT ON (項目1, 項目2) 項目1,項目2,項目3,項目4 FROM テーブル ORDER BY 項目1,項目2,項目3,項目4
とかも使える

454 名前:NAME IS NULL mailto:sage [2007/07/06(金) 14:15:45 ID:???]
>>450
試してないけど、それでto_timestampでTIMESTAMP型にするなら
to_timestamp(YMD || ' ' || HMS ,'YYYYMMDD HH24MMSS')
じゃない?

455 名前:454 mailto:sage [2007/07/06(金) 14:21:52 ID:???]
ごめん、こうだな。
to_timestamp(YMD || ' ' || HMS ,'YYYYMMDD HH24MISS')

456 名前:NAME IS NULL [2007/07/06(金) 14:44:14 ID:KwXXH4Ws]
>>455
理想通りの動作が来ました
単純に+じゃなく || 、日付の指定形式を間違えていたんですね・・・・
ありがとうございました!


457 名前:448 mailto:sage [2007/07/06(金) 16:29:39 ID:???]
いまさらですがDB2です。すいません。
FETCHとか使うって事ですかね?
アドバイス参考にやってみます。
ありがとうございます。

458 名前:NAME IS NULL mailto:sage [2007/07/06(金) 17:08:20 ID:???]
>>457

まぁ、カーソルへのfetchを扱えるというのなら、
それが一番スマートで確実なやり方だろうな。

>sql使う機会があまり無い
と言うから、できるだけ簡単な方法を提示してみたのだが。
ちなみにfetchは、ストアドでやるって意味だよな?
クライアントサイドから全件fetchやろうとしてるなら、
いずれパフォーマンスで泣きを見るぞ。

別解として、更新時の処理をいじる余地があるのならば、
項目1と項目2が複合主キーな別テーブルを用意して、
トリガで1件目のときだけそっちにinsertするという方法もある。


459 名前:NAME IS NULL [2007/07/06(金) 20:20:25 ID:EkGmqGMy]
以下のようなデータが入ってるtestというテーブルがあります。
+-------+------+-------+
| CLASS | NAME | COUNT |
+-------+------+-------+
| 1 | a | 1 |
| 1 | b | 2 |
| 3 | c | 10 |
+-------+------+-------+

CLASS別に最大のCOUNTを持つ行を取得したいと思います。
select CLASS,
NAME,
max(COUNT)
from test
group by CLASS;
というSQLを流した結果以下のようになってしまいました。
+-------+------+------------+
| CLASS | NAME | max(COUNT) |
+-------+------+------------+
| 1 | a | 2 |
| 3 | c | 10 |
+-------+------+------------+

期待していた結果は
+-------+------+------------+
| CLASS | NAME | max(COUNT) |
+-------+------+------------+
| 1 | b | 2 |
| 3 | c | 10 |
+-------+------+------------+
なのですが、どうしたらこのような結果を取得できますか?

すいませんがご指導よろしくお願いします。

460 名前:NAME IS NULL mailto:sage [2007/07/06(金) 20:29:54 ID:???]
>> 459
問題の性質は、>>448 とほとんど同じだな。
解決法も似たようなものになる。



461 名前:NAME IS NULL mailto:sage [2007/07/06(金) 20:53:50 ID:???]
>>459
例に出してるデータに
| 1 | d | 2 |
というレコードが加わったらどう出したいんだ?
話はそれからだ。

462 名前:459 [2007/07/06(金) 21:00:15 ID:EkGmqGMy]
レスありがとうございます。
>>460
order by をかけて一番大きい値順に出すと言う事でしょうか?
>>461
bでもdでも良いので1レコードだけ出てほしいです。

maxとgroupを使えば最大値の含まれる行が出ると思っていたのですがそうではなかったんですね。



463 名前:NAME IS NULL mailto:sage [2007/07/06(金) 21:59:55 ID:???]
>>462
>order by をかけて一番大きい値順に出すと言う事でしょうか?
>>453 やFETCHするやり方ならそうなるかな。

仕事忙しいはずなのに、ほっとけなくなって回答例作ってみた。
select
class,
(select name from test where class = grouped.class and count = grouped.max_count),
max_count
from
(
select
class,
max(count) as max_count
from
test
group by
class
) as grouped

ただしこれだと >>461 の場合にエラー出るから、使ってるDBMSに応じて
top 1なりlimit 1なり付けるべし。

464 名前:NAME IS NULL mailto:sage [2007/07/06(金) 22:37:22 ID:???]
スレが伸びてると思ったら…
われなべにとじぶたの品評会ですか?

465 名前:456 mailto:sage [2007/07/06(金) 23:51:36 ID:???]
>>463
お忙しい中ご回答ありがとうございました。

select class,
(select name from test where class = grouped.class and count = grouped.max_count limit 1),
max_count
from
(
select class,
max(count) as max_count
from test
group by class
) as grouped

とする事で解決しました。

本当にどうもありがとうございます。

466 名前:NAME IS NULL mailto:sage [2007/07/07(土) 13:19:44 ID:???]
MSアクセスで同僚のためにクエリを書いたのですが、いくつものクエリを順番に実行するというスマートではないものになってしまいました。
一発でできないかご教授願います。

テーブルが2つあり、それぞれに品番と数量のフィールドがあります。
品番の重複がそれぞれのテーブル内であるので、品番ごとに数量を集計して2つのテーブルで品番ごとに数量の合計の差異があるか
どうか、また品番のマッチングがないものを調べたいのですが、集計した後にうまくJoinで合体できません。

仕方がないので、集計したテーブルをそれぞれSelect Into で別個に作成してからJoinを行っています。
できればこのステップを排除したいのですが、どうしたらよいのでしょうか?

今はこんな感じです。

Select 品番, SUM(数量) into temp_TableA
From TableA
Group By 品番

同様にTableB

その後

Select A.品番, A.数量-B.数量 From temp_TableA A
Join temp_TableB B
On A.品番 = B.品番
Where A.数量-B.数量 <>0


467 名前:NAME IS NULL mailto:sage [2007/07/07(土) 14:52:04 ID:???]
select coalesce(A.品番, B.品番), A.数量小計, B.数量小計
from (select 品番, sum(数量) as 数量小計 from TableA group by 品番) as A
   full outer join
   (select 品番, sum(数量) as 数量小計 from TableB group by 品番) as B
   on A.品番 = B.品番
where A.数量小計 <> B.数量小計
or   A.数量小計 is null
or   B.数量小計 is null

とか。
MS Accessで書けるかどうかはシラネ。

468 名前:NAME IS NULL mailto:sage [2007/07/07(土) 20:58:16 ID:???]
こんな感じの2つテーブルがあったとき

items
+---------+
| name |
+---------+
| folder0 |
| file-a1 |
| file-b1 |
| folder1 |
| file-c2 |
| file-d2 |
| file-e1 |
+---------+
consist
+---------+---------+
| parent | child |
+---------+---------+
| folder0 | file-a1 |
| folder0 | file-b1 |
| folder0 | folder1 |
| folder0 | file-e1 |
| folder1 | file-c2 |
| folder1 | file-d2 |
+---------+---------+

子のあるfolder1を再帰的に処理して、こんな結果を得たいのですが、どうすればいいでしょうか?
folder0
 file-a1
 file-b1
 folder1
  file-c2
  file-d2
 file-e1


469 名前:NAME IS NULL mailto:sage [2007/07/08(日) 09:17:55 ID:???]
>>467
見たことのないコマンドがいきなり…
オラクルでしょうか? 似たようなのがSQLサーバやMSアクセスでないかどうか調べてみます。
ありがとうございました。

月曜日に早速試してみます。

470 名前:NAME IS NULL mailto:sage [2007/07/08(日) 10:27:05 ID:???]
見たことないコマンドって... おいおい...

同僚のためにクエリ書くのもいいけど、もう少し本とかマニュアルとか
読んだほうがいいと思うよ。



471 名前:NAME IS NULL mailto:sage [2007/07/08(日) 11:14:03 ID:???]
>>468
WITH RECURSIVE とか使うんだろうな。
でも俺は書いたことないから回答は書けない。

472 名前:468 mailto:sage [2007/07/08(日) 11:36:50 ID:???]
>>471 ご教示ありがとうございます。
WITH RECURSIVEをキーワードにググったところ、ヒントになりそうな情報
が見つかりました。
ちなみに、使用データベースは、postgresqlです。

473 名前:NAME IS NULL mailto:sage [2007/07/08(日) 13:45:40 ID:???]
おお、俺もはじめて知ったよ WITH 句

サンクス ⇒ >>471

474 名前:NAME IS NULL mailto:sage [2007/07/08(日) 16:29:55 ID:???]
PostgreSQLはRECURSIVEをまだサポートしてないだろ。
標準では入らないけど、用意されているconnectbyだったかを
加えればそれでできる。

475 名前:468 mailto:sage [2007/07/08(日) 18:28:32 ID:???]
>>474
再帰問い合わせは8.2でもできないとのことですが、CREATE FUNCITONを使って
同様のことができることを見つけたのですが、connectby(contrib/tablefunc
モジュール)の方法もわかりました。ご教示ありがとうございます。

476 名前:NAME IS NULL [2007/07/09(月) 14:46:41 ID:WLR34h5u]
質問です
Postgresで以下のようなテーブルがあります。

ID,StartDay,EndDay,Name,その他のカラム........
1,2006/1/1,2006/12/31,AAAA(2006),
1,2007/1/1 ,9999/12/31,AAAA(2007),
2,2006/1/1,2006/12/31,BBBB,
2,2007/1/1 ,2007/12/31,BBBB,

このようなデータの時に 
指定された日付が開始、終了の範囲内のあるもので使用するのですが、今回は
一番新しいIDと名前の組み合わせを取得したいのです。
何とかして1激で取ってこれるような良い案はないでしょうか?
終了データは必ず9999/12/31で終わるようにはなっていないので 単純にWHERE条件で指定できない状態です。


477 名前:NAME IS NULL mailto:sage [2007/07/09(月) 14:55:50 ID:???]
>>476

select * from table_name where cast('2007-07-09' as date)
between StartDay and EndDay order by ID limit 1

478 名前:NAME IS NULL [2007/07/09(月) 15:30:38 ID:WLR34h5u]
>>477
すません、せっかく考えてくださったのに説明がうまく出来ておらず伝わっていなかったようで

日付関係なしに取ってきても現在あるデータの中で
EndDayが最高の値を持つ各ID列の一覧を取得したいんです。

上のたとえで言えば いつどんな日にデータを取得してきたとしても
1,2007/1/1 ,9999/12/31,AAAA(2007),
2,2007/1/1 ,2007/12/31,BBBB,
を抽出できるということです。


479 名前:NAME IS NULL mailto:sage [2007/07/09(月) 16:18:06 ID:???]
そんな条件、>>476のどこにも見えないが・・・

GROUP BY IDと、MAX(date) でこの2つが出ると思うが、
それを元にSELECTしては。同じ値があったときどうするかとか
書いて無いので、このくらいしか書けないけど。

480 名前:NAME IS NULL mailto:sage [2007/07/09(月) 18:23:29 ID:???]
PostgreSQL依存だが
SELECT DISTINCT ON (ID) * FROM Table ORDER BY ID,EndDay DESC ;



481 名前:NAME IS NULL [2007/07/09(月) 18:32:20 ID:y+tFWW+2]
MySQL 4.1.20 を使っています。
>>482のようなテーブルとデータがあります。
2007年の当月分のデータだけを取得するため以下のSQLを実行しました。
(またラベルとして利用するために「日」を取得しています)

SELECT
dt,
DAY(dt)
AS d
FROM TEST
GROUP BY d
HAVING MONTH(dt) = MONTH('2007-07-01')
;

そうするとなぜか 2007-07-07 と 2007-07-08 のデータが出力されません。
ためしに (1, '2007-06-07 00:00:00') のレコードを削除してみると、
2007-07-07 のデータは出力されるようになりました。
全然理由がわかりませんが、なぜなんでしょうか?

482 名前:NAME IS NULL [2007/07/09(月) 18:33:27 ID:y+tFWW+2]
CREATE TABLE `TEST` (
`id` int(10) unsigned NOT NULL auto_increment,
`dt` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=ujis AUTO_INCREMENT=33 ;

INSERT INTO `TEST` (`id`, `dt`) VALUES
(1, '2007-06-07 00:00:00'),
(2, '2007-06-08 00:00:00'),
(3, '2007-06-09 00:00:00'),
(4, '2007-06-10 00:00:00'),
(5, '2007-06-11 00:00:00'),
(6, '2007-06-12 00:00:00'),
(7, '2007-06-13 00:00:00'),
(8, '2007-06-14 00:00:00'),
(9, '2007-06-15 00:00:00'),
(10, '2007-06-16 00:00:00'),
(11, '2007-06-17 00:00:00'),
(12, '2007-06-18 00:00:00'),
(13, '2007-06-19 00:00:00'),
(14, '2007-06-20 00:00:00'),
(15, '2007-06-21 00:00:00'),
(16, '2007-06-22 00:00:00'),
(17, '2007-06-23 00:00:00'),
(18, '2007-06-24 00:00:00'),
(19, '2007-06-25 00:00:00'),
(20, '2007-06-26 00:00:00'),
(21, '2007-06-27 00:00:00'),
(22, '2007-06-28 00:00:00'),
(23, '2007-06-29 00:00:00'),
(24, '2007-06-30 00:00:00'),
(25, '2007-07-01 00:00:00'),
(26, '2007-07-02 00:00:00'),
(27, '2007-07-03 00:00:00'),
(28, '2007-07-04 00:00:00'),
(29, '2007-07-05 00:00:00'),
(30, '2007-07-06 00:00:00'),
(31, '2007-07-07 00:00:00'),
(32, '2007-07-08 00:00:00');

483 名前:NAME IS NULL mailto:sage [2007/07/09(月) 18:42:40 ID:???]
>>478
普通に
select A.ID, A.StartDay, A.EndDay, A.Name, A.その他のカラム
from TABLE_NAME A
   inner join
   (select ID, max(EndDay) as MaxEndDay from TABLE_NAME group by ID) B
   on A.ID = B.ID
   and A.EndDay = B.MaxEndDay
;
じゃないの?
IDとEndDayの組合せで一意になるという前提だが。

484 名前:NAME IS NULL mailto:sage [2007/07/09(月) 18:44:49 ID:???]
>>482

まず
SELECT
dt,
DAY(dt)
AS d
FROM TEST
GROUP BY d;
だけを実行してみなよ。
その結果にhavingの条件が適用されることを考えれば、
なぜそうなるのかわかるはず。

485 名前:NAME IS NULL [2007/07/09(月) 18:53:50 ID:WLR34h5u]
>>479,>>480,>>483
レス遅くなってすみません。
あれから夢中になっていろいろ試してみてました
どうも>>483さんの方法でできそうな気がします。
ちょっとこれから試してみようかと。

下手糞な質問の仕方でご迷惑をおかけしました。

486 名前:NAME IS NULL mailto:sage [2007/07/09(月) 19:06:30 ID:???]
>>484
ありがとうございます。
そうか、日だけでGROUP BYしてたから、6月と7月で同じ日の
データがグループ化されてしまっていたんですね。
ありがとうございました。

487 名前:NAME IS NULL mailto:sage [2007/07/09(月) 19:20:36 ID:???]
>>486
そもそもGROUP BYの使い方を間違ってるような。
単にWHERE句で日付範囲を指定すればいいだけでは?

488 名前:NAME IS NULL mailto:sage [2007/07/10(火) 03:02:44 ID:???]
mysql5でtypeが重複しているものはtimeが最も新しいレコードを表示する
という処理をしたいと思っています。

id   type value time
1   a   12   12:38
2   b    8    9:12
3   a   14   13:22
4   a   10   11;21
5   b   13    7:35

期待する表示は
3   a   14   13:22
2   b    8    9:12
です。

現在
SELECT *
FROM (
 SELECT *
 FROM test
 ORDER BY time DESC
) temp
GROUP BY temp.type

で実現できているのですが件数が増えるにつれパフォーマンスに問題が出てきます。
このSQL文より速度が出る書き方はありませんでしょうか。

489 名前:NAME IS NULL mailto:sage [2007/07/10(火) 03:52:08 ID:???]
>>488
新しいという意味が最大値ということでいいのなら、
select
type,value,max(time) as mt
from test
group by type
order by mt desc;

490 名前:NAME IS NULL mailto:sage [2007/07/10(火) 04:11:01 ID:???]
>>489
スマンvalueが、、、

select * from test where time in
(select max(time) from test group by type)
でとりあえずとれるけど、あんまり速くないか、、



491 名前:NAME IS NULL mailto:sage [2007/07/10(火) 04:37:58 ID:???]
>>490
すまん、何度も間違えた、アホな俺

select t.* from test as t, (select type,max(time) as mt from test group by type) as t2
where
t.type=t2.type
and
t.time=t2.mt;

492 名前:NAME IS NULL mailto:sage [2007/07/10(火) 05:32:41 ID:???]
>>489 さん
ありがとうございます。実環境で計測したところ3倍程高速になりましたヽ( ´¬`)ノ

493 名前:NAME IS NULL mailto:sage [2007/07/10(火) 06:20:58 ID:???]
もし、typeとtimeを複合インデックスにしてなかったら
alter table test add index(type, time);
analyze table test;
した後の計測結果を教えてほすぃ
もちろん無理だったらいいです

494 名前:NAME IS NULL mailto:sage [2007/07/10(火) 06:46:28 ID:???]
スレ違いかもしれんが、SQL実装時の効率のためにということで質問させて
ください。というか、この手のスレが閑散としているので。

[Company]
- ID
- Name
- Address

のような表があったとして、その会社の役割を表すのに、

- CustomerFlag
- VendorFlag
のような属性を[Company]に追加するか?

[Customer]
-CompanyID (FK)
[Vendor]
-CompanyID (FK)
のようにラッパー表を作るか?
のどちらがいいでしょうか?
簡単な問い合わせは前者の方が楽ですが、例えば、Customer固有の属性を追加
するときなどは後者の方がきれいにできるかと思います。
ご教示いただければ、ありがたく思います。よろしくお願いします。

495 名前:NAME IS NULL mailto:sage [2007/07/10(火) 06:58:07 ID:???]
>>494
固有属性がたくさんあるなら後者だろうが、
最終的にはパフォーマンスと相談じゃないか?

496 名前:NAME IS NULL mailto:sage [2007/07/10(火) 23:16:16 ID:???]
>>494
自分で答え書いてる気が...

> 簡単な問い合わせは前者
> Customer固有の属性を追加するときなどは後者

どっちのケースがどれぐらいあるかは君にしかわからないよ。

497 名前:NAME IS NULL [2007/07/11(水) 15:51:57 ID:tW1Thc0z]
論文(年度,論文番号,論文名) ※主キー;年度,論文番号
著者(年度,論文番号,著者順位,著者名) ※主キー;年度,論文番号,著者順位
というテーブルがあり,
【年度,論文番号,著者1,著者2,著者3,著者4,著者5】という結果を出すSQL文を
作成しましたが,(著者順位は最大5まで),クエリ式の構文エラー;演算子がありません
とプログラムから怒られました.どこが間違っているのでしょうか教えて下さい.

SELECT R.年度,R.論文番号,R.論文名,A.著者名 AS 著者1 ,B.著者名 AS 著者2,C.著者名 AS 著者3,D.著者名 AS 著者4,E.著者名 AS 著者5
FROM 論文 R LEFT JOIN (SELECT * FROM 著者 WHERE 著者順位=1) AS A ON R.年度=A.年度 AND R.論文番号=A.論文番号
LEFT JOIN (SELECT * FROM 著者 WHERE 著者順位=2) AS B ON R.年度=B.年度 AND R.論文番号=B.論文番号
LEFT JOIN (SELECT * FROM 著者 WHERE 著者順位=3) AS C ON R.年度=C.年度 AND R.論文番号=C.論文番号
LEFT JOIN (SELECT * FROM 著者 WHERE 著者順位=4) AS D ON R.年度=D.年度 AND R.論文番号=D.論文番号
LEFT JOIN (SELECT * FROM 著者 WHERE 著者順位=5) AS E ON R.年度=E.年度 AND R.論文番号=E.論文番号
ORDER BY R.年度,R.論文番号

498 名前:NAME IS NULL mailto:sage [2007/07/11(水) 16:39:53 ID:???]
>>497
本当にちゃんと回答してもらいたいなら、使用してるDBMS書こうぜ・・・

見た感じ、Accessだろうと推測できるが、その前提ならば、
Accessのjoin句はややクセがあって、他のDBMSのように
複数の結合対象テーブルを並列に記述できない。
サブクエリでネストする感じで書くしかない。

SQLというよりはAccessの方言の問題だから、Accessを使って
3つ以上のテーブルをjoinしてるSQLのサンプルを探してみな。

499 名前:497 [2007/07/11(水) 17:16:59 ID:tW1Thc0z]
すみません.お察しの通りDBはAccessです.
ちょっと調べてみます.

500 名前:NAME IS NULL mailto:sage [2007/07/11(水) 22:57:58 ID:???]
select A,B from hogeTable where ・・・
って文をSQLExecDirectで実行した結果取得できた行数を、
取得するVCの関数or方法ってありませんか?

SQLRowCount関数を試したところ、
全結果セットをSQLFetchした後にしか正しい値が帰ってきません。

whereのあとに続く条件が多いため
select count(A) from hogeTable where ・・・
という同じようなSQL文を2回も発行したくないんですよね。

ちなみに何がしたいかっていうと、実行したSQLで取れるレコード数の
領域を確保して、結果セットを全てメモリに入れたいのです。



501 名前:NAME IS NULL mailto:sage [2007/07/11(水) 23:46:25 ID:???]
>>500
たぶんSQLRowCountの仕様じゃないかな。

その要求を聞くに、ADOで言うところのGetRows()が最も適切なんだろうけど、
これに相当するODBC APIが何なのか、あるいはあるのかはわからん。

あと、レコード数わからなくても、メモリを動的に確保する方法はあると思うが。
C++なら、STLのコンテナクラス使ってレコードなくなるまでpushとか。
Cだったら・・・自作listとかでガンガれ。

502 名前:NAME IS NULL mailto:sage [2007/07/12(木) 11:36:17 ID:???]
SQL SERVERを使用しているのですが、
数値データを取得する時に書式を指定するには
どうすれば良いのでしょうか?

503 名前:NAME IS NULL mailto:sage [2007/07/12(木) 13:02:45 ID:???]
>>502
3桁ごとのコンマの付与なら、money型をconvert(case)するときに
styleに1を指定することでできるっぽいが、
アプリケーション側で変換した方がいいと思うけどなあ。

504 名前:NAME IS NULL mailto:sage [2007/07/12(木) 13:12:40 ID:???]
>>503
なるほど、ありがとう!
試してみます。

505 名前:NAME IS NULL mailto:sage [2007/07/12(木) 23:31:50 ID:???]
2005で.NET使ってるならアプリ側でやるよりCLR関数作ったほうがいいんじゃね?
2〜3パターンならめんどうだけどT-SQL関数でも作れない事はないし
実際そうしてる

506 名前:506 mailto:sage [2007/07/12(木) 23:48:01 ID:???]
>>505
俺がアプリ側の方が好ましいと言ったのは、
例えば「カンマ編集するかどうかを出力オプションで設定できる」みたいな
要求が出てきたときに、柔軟に対応できる余地を残したいからだったんだけどね。
まーその辺のバランス加減は質問者に委ねるよ。

507 名前:503 mailto:sage [2007/07/12(木) 23:49:59 ID:???]
>>506
名前欄間違えた。503=506ね。

508 名前:NAME IS NULL mailto:sage [2007/07/12(木) 23:53:54 ID:???]
sqlについて質問です。
selectの結果セットに固定のデータを潜りこませたい場合

( select "aaa", "bbb" ) union ( select f1, f2 from t1 )

こんな感じで考えて実際に動作はしているようですが
もう少しスマートな書き方はありますでしょうか。

環境はmysql5を使用しております。

509 名前:NAME IS NULL mailto:sage [2007/07/13(金) 00:06:13 ID:???]
>>508
そんなスマートじゃない要求にスマートに応える方法などないと思うが。

蛇足ながらUNIONよりはUNION ALLのほうが多少速いかもね。

510 名前:NAME IS NULL mailto:sage [2007/07/13(金) 00:09:51 ID:???]
>selectの結果セットに固定のデータを潜りこませたい場合
この時点ですでに泥臭いとオモ



511 名前:NAME IS NULL mailto:sage [2007/07/13(金) 00:18:10 ID:???]
やはり無いですか
マスタテーブルを作って、そこに固定データを置いてjoinするのが正しいとは思うんですけどね

512 名前:NAME IS NULL mailto:sage [2007/07/13(金) 10:15:12 ID:???]
それこそ泥臭い

513 名前:492 mailto:sage [2007/07/15(日) 11:28:23 ID:???]
>>493 さん
大分遅れましたが><
うろ覚え+実環境ではもっと複雑なため目安程度ですが
インデックス無し 旧:13s 新:100s以上(計測不能)
typeにインデックス 旧:12s 新:8.5s
type,time個別インデックス 旧:12s 新:4.7s
type+time複合インデックス 旧:11.7s 新:4.6s

旧SQLでは一度全件取得するため安定して遅く
type,timeをそれぞれ別々にインデックスと複合インデックスでは
速度的にはほとんど変わらないという結果が出ました。
その後、サブクエリの中で結合していたのを外に出したりして
最適化した結果1s以下で表示出来るようになりましたm(_ _)m

514 名前:NAME IS NULL [2007/07/17(火) 09:23:21 ID:2WDZRR0w]
id, type というフィールドがあるテーブルで、
id は UNIQUE かつ type は UNIQUE でないとする。
このとき、それぞれの type から、1つだけレコードを取り出すには
どうしたらよいでしょうか。

つまり、
id=1, type=100
id=2, type=100
id=3, type=200
id=4, type=200
id=5, type=200
とあったとき、たとえば、
id=1, type=100
id=3, type=200
だけを選択するような SQL ってできますか?
SELECT DISTINCT type FROM table1;
までは分かったのですが、その後、各 type から
1つだけレコードを抜き出してくる方法がわからない。


515 名前:NAME IS NULL mailto:sage [2007/07/17(火) 09:30:03 ID:???]
>>514

select min(id), type
from table1
group by type

516 名前:NAME IS NULL mailto:sage [2007/07/17(火) 09:50:00 ID:???]
>>515 ありがとう!助かった。

517 名前:NAME IS NULL mailto:sage [2007/07/18(水) 16:28:20 ID:???]
month, id, scoreの3つのカラムがあるテーブルがあります。
month毎にscoreが最大になる行をselectしたいのですが、
いい方法はないですか。idがいらなければgroup byとmaxで
いけるんですが、それだとidがわからなくなっちゃうの
ですよね。monthとmax(score)でもういちど探すのもなんか
馬鹿みたいだし...



518 名前:NAME IS NULL mailto:sage [2007/07/18(水) 16:38:12 ID:???]
>>517
同一monthで最大scoreのidが複数存在するときの扱いは?

519 名前:NAME IS NULL mailto:sage [2007/07/18(水) 16:56:18 ID:???]
postgresに関する質問です。
connectbyで階層問い合わせを実行すると、階層がカンマ区切りで表示されます。

------------
親キー ans
------------
1    1,2,3,4

これを次のようにカンマ区切りで複数行に分割するにはどうすればいいですか?

------------
親キー ans
------------
1    1
1    2
1    3
1    4

520 名前:NAME IS NULL mailto:sage [2007/07/18(水) 17:05:47 ID:???]
>>518
idのもっとも小さい奴ということにします。可能?



521 名前:NAME IS NULL mailto:sage [2007/07/18(水) 17:59:17 ID:???]
>>518
なんか、このスレではFAQ化してきてる内容だな。

select
month, max_score,
(select id from table where month = grouped.month and score = max_score order by id limit 1)
from
(
select
month, max(score) as max_score
from
table
group by
month
) as grouped

522 名前:NAME IS NULL mailto:sage [2007/07/18(水) 18:09:51 ID:???]
>>521
副問い合わせで見かけ上はひとつのselectになってるとはいえ、結局のところ
monthとmax(score)でもう一度ひきなおすしかないんですね。SQLっていまいち
だなぁ... それとも超高度なオプティマイザが全部解析してmaxもとめたときの
行をおぼえて内部的には余計なqueryはせずに返してたりするんだろうか?


523 名前:NAME IS NULL mailto:sage [2007/07/18(水) 18:51:15 ID:???]
>>522
mysql4.1.15では

EXPLAIN実行結果>
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system 1
3 DERIVED table9 ALL 2 Using temporary; Using filesort
2 DEPENDENT SUBQUERY table9 ALL 2 Using where; Using filesort

内部的にselectは2回されてるね。インデックスつけても1回にはならなかった。

524 名前:NAME IS NULL mailto:sage [2007/07/18(水) 20:20:39 ID:???]
>>522

select month, id, score
from table A
where not exists (
select * from table B
where B.month = A.month
and ( B.score > A.score or ( B.score = A.score and B.id > A.id ))
)

相関サブクエリはほとんどのDBMSで適切に最適化されるので、
(month,score,id)というindexがあればデータの偏りによらず
これが安定して速いし、(month,score)や(month)だけのindexしか
なかったとしてもそれなりのパフォーマンスが期待できる。

scoreもidも同じレコードがあったら両方出ちゃうけどね。

525 名前:NAME IS NULL mailto:sage [2007/07/18(水) 21:14:50 ID:???]
PL/SQLの質問です

クエリ実行→結果を引数にして同じクエリ実行→・・・値がとれなくなるまでループ
のようなファンクションを作りたいのですが
やり方がよくわかりません

FUNCTION HOGE(A in number,B in number) RETURN VARCHAR2
IS
ZZ VARCHAR2(10);
CURSOR CC(AA in number,BB in number)
IS
SELECT DD||EE FROM FF WHERE GG = AA AND HH = BB;
BEGIN
OPEN CC(A,B);
FETCH CC INTO ZZ;
CLOSE CC;
RETURN ZZ;
END;

↑これは1回分だけです

引数はクエリ実行結果の値をAとBに分解するつもりですが
ループのところはどのような記述をすればいいのでしょうか?

526 名前:NAME IS NULL mailto:sage [2007/07/18(水) 21:54:30 ID:???]
>>525
その質問内容では、どこでつまづいているのか理解できる人は少ないと思う。
ファンクションからファンクションを呼ぶ方法がわからんのか、
終了条件の分岐のロジックがわからないのか、そもそも再帰の概念自体わからないのか。

527 名前:NAME IS NULL mailto:sage [2007/07/18(水) 22:23:16 ID:???]
>>525-526
「再帰呼び出し」でぐぐれ。でいいような。

528 名前:NAME IS NULL [2007/07/20(金) 14:24:37 ID:5xOFcdu1]
COL_A COL_B COL_C
1、1、AAA1
1、2、AAA2
1、3、AAA3
1、4、AAA4
2、1、BBB1
2、3、BBB3
3、1、CCC1
3、2、CCC2
3、3、CCC3
4、1、DDD4

というデータがあり

1、4、AAA4
2、3、BBB3
3、3、CCC3
4、1、DDD4
このような感じで
COL_Aで重複があればCOL_Bが最大のもの
COL_Aで重複しないものであればそのまま
という結果を得たいのですが

SELECT COL_A, COL_.B, COL_C FROM テーブル名
GROUP BY COL_A, COL_.B;
こんな感じになるのでしょうがココから
どのようにSQLをくっつけていいか思いつかなくて手が止まっています。
どのような感じにすればいいんでしょうか?

ACCESS2000を使用しています。

529 名前:NAME IS NULL mailto:sage [2007/07/20(金) 15:10:56 ID:???]
>>528

マジでw「重複してるときは一行だけ取り出す」関連の質問多すぎwwwww
質問者が全部同一人物なのかと疑ってしまうくらいにwwwwうはwwおkwwww
誰が教えてやるもんかwwwwwwwwwww





























SELECT COL_A, COL_B_MAX,
(SELECT TOP 1 COL_C FROM テーブル名 WHERE COL_A = GROUPED.COL_A AND COL_B = COL_B_MAX)
FROM (
SELECT COL_A, MAX(COL_B) AS COL_B_MAX FROM テーブル名
GROUP BY COL_A) AS GROUPED;

530 名前:NAME IS NULL [2007/07/20(金) 15:19:55 ID:5xOFcdu1]
>>529
そのツンデレぶりにはたいへん驚かされましたが…

なるほど!
FROM のテーブルをサブクエリで一意に取ってきたデータに置き換えるんですね
で、名前はそのキーから取得すると・・・

目から鱗です!
ありがとうございました



531 名前:NAME IS NULL [2007/07/20(金) 21:53:50 ID:ZGZ4CJa3]
psqlについて質問です
psqlでDBを作りたいのですが
データを入力する際に、invalid byte sequence for encoding "EUC_JP"というエラーが出て日本語の入力ができません。

使用しているOSは Fedora Coreで
文字コードを UTP-8を変換しようとしています

よろしくお願いします。

532 名前:NAME IS NULL mailto:sage [2007/07/21(土) 01:00:47 ID:???]
どういう環境かよくわからんが、
クライアントの文字コードにあわせて、set client_encoding TO 'UTF-8'; とかやってみそ
つーか、PostgreSQLのスレで聞いたほうがいいと思うぞ

533 名前:NAME IS NULL mailto:sage [2007/07/21(土) 04:02:10 ID:???]
以下のようなSQLを作成しようとして途方に暮れています。
・カテゴリごとに最古のn個(ここでは2個としておきます)のレコードを含む結果を1回のSQL文で取得したい。
・結果レコードの総数は最大で(カテゴリの数xn)になる。
・結果はカテゴリ、日付順で返す
・MySQL5.0用 できれば汎用

テーブルはたとえばこんな感じ
id category tm(日付)
1 1 4/ 1
2 1 3/10
3 1 10/ 1
4 2 6/ 1

得たい結果はこんなかんじ
(カテゴリー1の第3位となるid=3が除外される)
2 1 3/10
1 1 4/ 1
4 2 6/ 1

SELECT * FROM timetest TX WHERE tm<=
(SELECT MAX(T.tm) FROM
(SELECT tm FROM timetest T1
WHERE T1.category = TX.category
ORDER BY tm LIMIT 2
) AS T)
ORDER BY category, tm

とりあえず上記のようなSQL文で試してみたのですが、
サブSELECTのWHEREのところでTXを参照できないようです。

グループごとの第2位の日付がわかる表ができれば、
後はJOINとかでなんとかなりそうなのですが、
MAX,GROUP BY,LIMITを併用すると、グループごとにLIMITが効いてくれず、方法がわかりません。
お願いしますm(_ _)m


534 名前:NAME IS NULL mailto:sage [2007/07/21(土) 04:21:18 ID:???]
>>533
SELECT * FROM
(SELECT (SELECT count(*) FROM timetest WHERE category=T1.category AND tm<=T1.tm) AS num,category ,tm FROM timetest AS T1 ) AS T2
WHERE num <= 2;

DBによってはWHERE句をもうひとつ中に入れて、
大外のSELECTは要らないけどな。

535 名前:533 mailto:sage [2007/07/21(土) 04:43:46 ID:???]
>>534
おお、ありがとうございます!
たしかに期待通りの結果になりました。結構びっくりです。

ところで、解釈上やや複雑そうに見えるのですが、
この方法はDB内部でうまく最適化されてくれるのでしょうか?

カテゴリごとに分けてSELECTを呼ぶ場合より時間がかかったりしなければ問題はないのですが。
(カテゴリの数は10程度として)

何にせよありがとうございます。COUNTを使うというのは、目から鱗です。

536 名前:525 mailto:sage [2007/07/21(土) 19:57:22 ID:???]
事故解決しますた
文法ミスでした

>>526
すんません、切羽詰ってて説明不足でした

PL/SQLの文法解説してるサイトってあまりないですね

Oracleのマニュアルが凄い充実してることに驚いたのですが
初級者には全体的に理解し難い感じです

これを読みやすくしたような書籍無いでしょうか?
使用例も多いと助かります

>>527
再帰は知ってたけど、文法がわからんかったのです

537 名前:NAME IS NULL mailto:sage [2007/07/21(土) 20:25:23 ID:???]
なんかDB2で仕事しているとOracleの書籍の多さには羨ましい限りなのだが・・・。

しかし回答者はエスパーじゃないんだからテメエで本屋逝って探せよ。

538 名前:sage [2007/07/22(日) 21:13:07 ID:FhbbgWhN]
SQLでプログラム言語でいうところのif文の命令あるの?

例えば、もしAというカラムの値が1なら0を出力する。
もしAというカラムの値が2なら1を出力する。。みたいな

539 名前:NAME IS NULL mailto:sage [2007/07/22(日) 21:20:20 ID:???]
>>538
CASE(SQL-92)

540 名前:NAME IS NULL mailto:sage [2007/07/22(日) 22:45:53 ID:???]
>>538
DECODE



541 名前:NAME IS NULL [2007/07/22(日) 22:50:18 ID:CkTSSgqR]
只今勉強中の初心者です。教えて下さい。
下のような表があって、それぞれの点数の部分を
選択している科目には点数を、選択していない部分は
NULLを表示したいのですが、どうしたらよいのでしょうか?

↓この表を      ↓このように表示したいのです

氏名 科目 化学 生物  氏名 科目 化学 生物
-- -- -- --      -- -- -- --
AAA 化学 30  30   AAA 化学 30 NULL
BBB 物理 50  50   BBB 物理 NULL 50
CCC 化学 90  90   ・・・
DDD 化学 80  80
EEE 物理 70  70

542 名前:NAME IS NULL mailto:sage [2007/07/22(日) 22:56:39 ID:???]
select
氏名, 科目,
case 科目 when '化学' then 化学 else null end as 化学,
case 科目 when '生物' then 生物 else null end as 生物
from 表
order by 氏名;

typo あったらすまん。

543 名前:538 [2007/07/22(日) 23:18:33 ID:FhbbgWhN]
>>539,540
dクス

544 名前:NAME IS NULL mailto:sage [2007/07/22(日) 23:42:32 ID:???]
>>542
group by しないと無理じゃね?

545 名前:NAME IS NULL mailto:sage [2007/07/23(月) 00:45:53 ID:???]
取扱商品
品番 品名 売価
----
1 ペン 100
2 消しゴム 100
3 鉛筆 50
4 ノート 150

売上
店舗番号 品番 個数
------- ----
1 1 1
1 2 1
1 3 2
1 4 1
2 1 1
2 4 5
3 1 3

↑のテーブルから商演算を用いて、全種類の商品を売った店舗番号を抽出したいのですが
旨くいきません・・・・どなたかご教授お願いします。
代数演算は分かりづらい。。

546 名前:NAME IS NULL mailto:sage [2007/07/23(月) 01:01:36 ID:???]
select 店舗番号
 from (select 店舗番号, 品番
    group by 店舗番号, 品番)
group by 店舗番号
having count(店舗番号) = (select count(*) from 取扱商品)


547 名前:NAME IS NULL mailto:sage [2007/07/23(月) 01:17:34 ID:???]
俺の場合商演算はNOT EXISTSのネストでやってるなぁ。

select distinct 店舗番号 from 売上 AS 売上A
where not exists(
 select * from 取扱商品
 where not exists
 (select * from 売上 where 店舗番号=売上A.店舗番号 AND 品番=取扱商品.品番)
)


548 名前:NAME IS NULL mailto:sage [2007/07/23(月) 01:37:46 ID:???]
>>546,547
ありがとうございます。
教科書もNOT EXISTS を使ってるみたいなんですけど
どうも分かりづらいです。。。
何か作り方の手順があればやりやすいのに・・

549 名前:541 [2007/07/23(月) 12:06:02 ID:RqjUNL36]
>>542さん
>>544さん遅くなりまして申し訳ございません
CASE〜でできました。ありがとうございました。

550 名前:533 mailto:sage [2007/07/24(火) 04:58:39 ID:???]
>>534-535 について続報。
速度テストしてみましたが、
レコード1万ぐらい入れて、カテゴリあたりのレコードが十分多い状況だと、
実行に10秒程度かかるようです。(MySQL5.0 ノートPC)

一応インデックスはちゃんと張ってるつもり。
多分内部処理でレコードごとにループしちゃってる?

#もし同じ事を行う高速な手法(外部でループする以外)があれば教えてください・・・

いずれにしても参考になりました。ありがとうございましたm(_ _)m



551 名前:NAME IS NULL mailto:sage [2007/07/24(火) 06:44:51 ID:???]
>>550
select t1.id, t1.category, t1.tm
from timetest t1, timetest t2
where t1.category = t2.category
and t1.tm >= t2.tm
group by t1.id, t1.category, t1.tm
having count(*) <= 2
とか。
脳内で書き方変えただけで、テストしてないけど。

552 名前:NAME IS NULL mailto:sage [2007/07/24(火) 07:08:24 ID:???]
row_number partition が使える処理系なら効率よく処理できるのだが、
そうじゃない処理系でデータ数が多いなら、シーケンシャルに全件順に読んで
ユーザープログラムで読み飛ばしたほうが速いケースもある。

553 名前:533 mailto:sage [2007/07/24(火) 15:31:17 ID:???]
>>551
ありがとうございます。
例の1万件でテストしてみますと、ほぼ >>534 と同等の結果でした。
MySQLの内部処理的には似た感じなのかも。

>>552
この処理を1回で高速に処理するにはMySQLの機能不足という感じでしょうか。

DBにはできるだけ負荷をかけたくない処理ですので、
今のところ カテゴリ抽出→カテゴリごとにORDER BY&LIMIT とかでなんとかしようと思っています。

554 名前:NAME IS NULL mailto:sage [2007/07/24(火) 15:52:16 ID:???]
>>553
念のため確認だが、
>一応インデックスはちゃんと張ってるつもり。
とのことだけど、(category, tm)の複合インデックスだよね?
このインデックスがあれば、1万レコードでも10秒てのは
遅すぎるような気がするのだが。
ちなみにDBMSによっては、(category, tm, id)でさらにselectが速くなる場合もあるけど
ほとんどの場合は大差ないかな。

555 名前:533 mailto:sage [2007/07/24(火) 17:01:17 ID:???]
>>554
実際の問題ではカテゴリが2つあり、
(category1, category2, tm) の複合インデックスを作っています。
このため、テーブルが多少違う部分はSQLも書き換えていますが、ストレートな変換のみです。

ためしにこのインデックスを外してみると >>534 の実行に72秒かかったので、効いているようです。
>>551 のほうは87秒でした。
ただしテスト環境は3年前のノートPC(1.3GHz)です。最近のPCでやってみると時間は半分ぐらいです。

作成したデータは、カテゴリの組(category1, category2)ごとにtmの異なるレコードが1000件あるデータです。
カテゴリの組は全部で9組なので合計9000件です。

556 名前:NAME IS NULL mailto:sage [2007/07/24(火) 17:52:40 ID:???]
>>555
そっか、余計な心配だったか。
お詫びというわけではないが、別解を書いてみた。
まーかなりネタも混ざってるし、仕事でこんなSQL書いてるやついたら
俺は殴るかもしれんが。

select id, timetest.category, timetest.tm
from timetest
inner join
(select category, min(tm) as min_tm from timetest group by category) t1
on
t1.category = timetest.category and t1.min_tm = timetest.tm
union all
select id, timetest.category, timetest.tm
from timetest
inner join
(select category, min(tm) as min_tm
from timetest
where id not in
(
select id
from timetest
inner join
(
select category, min(tm) as min_tm
from timetest
group by category
) t1
on t1.category = timetest.category and t1.min_tm = timetest.tm
)
group by category
) t2
on t2.category = timetest.category and t2.min_tm = timetest.tm
order by category, tm

557 名前:533 mailto:sage [2007/07/24(火) 18:35:33 ID:???]
>>556
なんかすごいのきた^^;

後で読み解いてみます。
ありがとうございますm(_ _)m

558 名前:NAME IS NULL [2007/07/25(水) 22:36:43 ID:oJzPaskR]
今仕事で複数テーブルから結果を求めるSQLを作っているのですが07年合計金額の結合部分でよく分からないのでご教授ください。

欲しい結果
大分類名 小分類名 06年合計金額 07年合計金額
-------- -------- ------------ ------------
 AAA     A     20000    30000
 AAA     B     30000    10000
 BBB     A     15000    20000

参照元テーブル
テーブル1
大分類コード 小分類コード 年度 金額

テーブル2
年度 大分類コード 大分類名

テーブル3
年度 小分類コード 小分類名

select a.大分類名,b.小分類名,sum(DISTINCT c.金額)

from
(テーブル1 c INNER JOIN テーブル2 a on c.年度 = a.年度 AND
c.大分類コード = a.大分類コード)
INNER JOIN テーブル3 b on c.年度 = b.年度 AND
c.小分類コード = b.小分類コード

where
c.年度 = 2006
GROUP BY
a.大分類名,b.小分類名,c.年度,a.大分類コード,b.小分類コード

ORDER BY
a.大分類コード,b.小分類コード ASC


大分類名 小分類名 06年合計金額
-------- -------- ------------
 AA    A     20000
 AA    B     30000
 BB    A     15000

↑のSQLで↑までは出せたのですが再度テーブル1から07年合計金額を出す方法が分かりません。
UNIONを使った方法でやりたいのですが分からなかったので申し訳ありませんがご教授お願いいたします。

559 名前:558 [2007/07/25(水) 22:37:51 ID:oJzPaskR]
SQL言語はOracleです。

560 名前:NAME IS NULL mailto:sage [2007/07/25(水) 23:06:14 ID:???]
>>558
テーブル2とテーブル3のデータの保持形式がよーわからん。

テーブル2
年度 大分類コード 大分類名
2006 AAA 2006年のときの名前
2007 AAA 2007年のときの名前

みたいになってるってことか?
なら、今回は2007年のときの名前を表示したいと勝手に決め付けて書くとこうなる。

select 大分類名, 小分類名,
(select sum(金額) from テーブル1 where 大分類コード = t1.大分類コード and
小分類コード = t1.小分類コード and 年度 = 2006),
(select sum(金額) from テーブル1 where 大分類コード = t1.大分類コード and
小分類コード = t1.小分類コード and 年度 = 2007)
from (select distinct 大分類コード, 小分類コード from テーブル1) t1
inner join テーブル2
on テーブル2.大分類コード = t1.大分類コード
and テーブル2.年度 = 2007
inner join テーブル3
on テーブル3.小分類コード = t1.小分類コード
and テーブル3.年度 = 2007

履歴がないものはnullじゃなくて0を表示したいならnvl関数。



561 名前:558 [2007/07/25(水) 23:24:16 ID:oJzPaskR]
>>560
さっそくレスありがとうございます。
データを書いた方が分かりやすかったですね。申し訳ありません。
テーブル2
年度 大分類コード 大分類名
---- ------------ --------
2006    10000  AAA
2006    20000  BBB
2007    10000  AAA
2007    20000  BBB

テーブル3
年度 小分類コード 小分類名
---- ------------ --------
2006    10000  A
2006    20000  B
2007    10000  A
2007    20000  B

先ほど書いた現段階の出力の部分に誤りがありました。性格には下記のようです。
大分類名 小分類名 06年合計金額
-------- -------- ------------
 AAA    A     20000
 AAA    B     30000
 BBB    A     15000


562 名前:NAME IS NULL mailto:sage [2007/07/25(水) 23:29:17 ID:???]
>>561
推測したとおりで大丈夫だったってことかな。
なら、>>560 でいけると思うんだが。
unionを絶対に使わないといけないわけじゃないんでしょ?

563 名前:558 [2007/07/25(水) 23:36:24 ID:oJzPaskR]
>>562
多分大丈夫だと思います。明日さっそく試してみます。
それと申し訳ないのですがunionを使った方法も教えていただけないでしょうか?

564 名前:NAME IS NULL mailto:sage [2007/07/25(水) 23:45:09 ID:???]
>>563
出したい結果を考えると、unionを使う意味、というか使う余地はないのだが。
2006年と2007年を縦に並べるなら使うこともできるだろうけど。
横に並べたいのなら、サブクエリやファンクションで実現するのが一般的。

565 名前:558 [2007/07/26(木) 07:12:29 ID:sS8BKlCY]
>>564
上司に昨日尋ねたらunionで出来るという事なので参考までに聞いたのですが横だと意味がないんですね。
勉強になります。
教えていただき助かりました。ありがとうございました。

566 名前:NAME IS NULL [2007/07/26(木) 12:15:13 ID:XmvrlBD0]
テーブルAの項目をテーブルBの項目でUpdateしたいのですがどうすればいいのでしょうか。
AとBはジョインできますが両テーブル共に複数レコード存在します。

567 名前:NAME IS NULL mailto:sage [2007/07/26(木) 13:33:35 ID:???]
>>566
update...from句

568 名前:566 mailto:sage [2007/07/26(木) 14:34:42 ID:???]
>>567
できました。
ありがとうございました。

569 名前:NAME IS NULL mailto:sage [2007/07/26(木) 21:17:38 ID:???]
項目1 項目2 金額1 金額2
------ ------ ------ ------
 0001 合計  6000  600
 0001  01  1000  100
 0001  02  2000  200
 0001  03  3000  300
 0002 合計  15000 1500
 0002  01  4000  400
 0002  02  5000  500
 0002  03  6000  600

上記のような結果をoracle10gで出したいのですが出せずに困っています。
GROUP BY でROLLUPを使用し出力をしようとすると

項目1 項目2 金額1 金額2
------ ------ ------ ------
 0001  01  1000  100
 0001  02  2000  200
 0001  03  3000  300
 0001 NULL   0  600
 NULL NULL   0   0
以下略

と上記のような形になってしまいます。金額1と金額2は同テーブルでサブクエリーを使用し出力しています。
申し訳ありませんがどなたが力をお貸しください。

570 名前:NAME IS NULL mailto:sage [2007/07/26(木) 21:34:14 ID:???]
>>569
元のクエリも書いた方がレスが付きやすそうだが



571 名前:NAME IS NULL mailto:sage [2007/07/26(木) 22:09:34 ID:???]
手元に元のクエリが無いので記憶的で簡単なものになりますが

Select 項目名1,項目名2,SUM(金額1),SUM(金額2)
FROM(
SELECT a.項目No AS 項目No,
    a.項目2No AS 項目No2,
    a.項目1 AS 項目名1,
    a.項目2 AS 項目名2,
    sum(a.金額) AS 金額1,
    0 AS 金額2,
from テーブル1 a,
   テーブル2 b,
   テーブル3 c
where
   a.項目No = b.項目No AND
   a.項目2No = c.項目2No
Group By
    a.項目No,a.項目2No,a.項目1,a.項目2

UNION

SELECT a.項目No AS 項目No,
    a.項目2No AS 項目No2,
    a.項目1 AS 項目名1,
    a.項目2 AS 項目名2,
    0 AS 金額1,
    sum(a.金額) AS 金額2
from テーブル1 a,
   テーブル2 b,
   テーブル3 c
where
   a.項目No = b.項目No AND
   a.項目2No = c.項目2No
Group By
    a.項目No,a.項目2No,a.項目1,a.項目2
)
Group By ROLLUP(項目No,項目2No),項目名1,項目名2
Order By 項目No,項目2No

大方このようなクエリだったと思います。

572 名前:NAME IS NULL mailto:sage [2007/07/26(木) 22:32:50 ID:???]
>>571
テーブル2と3が、joinしてるのに結果に使われていないのは謎。
まぁ、「キーが存在することが条件」てのならわかるけど。

でrollupについてだが、それをどう直せばいい、というよりは、まず
[項目No1 項目No2 金額1 金額2]
の結果を出力するクエリを作ってみることをお勧めする。
つまり、項目名1,項目名2を考えずにってことな。
なんかrollupがごちゃごちゃしてるのがまずいと思うんだ。
これがうまくいってから、項目名1,項目名2をもってくることを考えようぜ。

573 名前:NAME IS NULL mailto:sage [2007/07/26(木) 22:35:45 ID:???]
>>572
さっそくありがとうございます。
実際は項目1と項目2の部分に該当した名前が入るんですけど分かりやすいようにコードとして表記させていただきました。

574 名前:NAME IS NULL mailto:sage [2007/07/26(木) 23:02:35 ID:???]
>>571
それじゃあfrom句の中の一個目のselectでの「金額1」と
二個目のselectでの「金額2」が同じじゃん。

>>569の結果を出したいときのテーブル1のデータ内容はどんなん?

575 名前:NAME IS NULL mailto:sage [2007/07/26(木) 23:11:52 ID:???]
>>574
Where句の条件が足りなかったですね。
上のWhere句に
a.toshi = 2006
下のWhere句に
a.toshi = 2007
という感じです。
金額1には前年度、金額2には今年度という感じです。

テーブル1としては

項目No 項目2No 年 金額

必要なフィールドだけを取り出すと上記の形になります。

576 名前:NAME IS NULL mailto:sage [2007/07/26(木) 23:30:15 ID:???]
>>575
つまりテーブル2とテーブル3はそれぞれ項目Noから名前をとってくるだけか。
だったらこんな(↓)感じのやつに後から名前をくっつけたら?
>>572 もそういうことを言っているんだと思うけど。

select 項目No,
    項目2No,
    sum(case when 年 = 2006 then 金額 else 0 end) as 金額1,
    sum(case when 年 = 2007 then 金額 else 0 end) as 金額2
from テーブル1
group by rollup(項目No, 項目2No)
order by 項目No, 項目2No

577 名前:NAME IS NULL [2007/07/27(金) 17:57:43 ID:SeTyNiJf]
すいません。質問です。宜しくお願いします。
ID CODE フラグ
1  1 0
1 2 0
1 3 1
2 1 0
2 2 0
3 1 0
3 2 1
上記のようなテーブルからIDでグループ化して
フラグが1のデータがあった場合はONを全部0だったらOFFをだして
ID 結果
1 ON
2 OFF
3 ON
のような結果をだすにはSQLをどのように書いたらいいでしょうか?
お願いします


578 名前:NAME IS NULL [2007/07/27(金) 18:00:40 ID:SeTyNiJf]
あ、MAXもってくればいいのか。

579 名前:NAME IS NULL mailto:sage [2007/07/27(金) 18:10:26 ID:???]
ハヤ!

580 名前:NAME IS NULL [2007/07/28(土) 09:22:39 ID:eFtPhvG6]
MySQLを利用しています。gidごとに値を積算して積算順にソートを
掛けたいのですが、下記だとgidごとにソートかかかってしまいます。
descと組み合わせるとエラーになるし、どうすればいいんでしょう。

select sum(data),gid from user_tp group by gid;




581 名前:NAME IS NULL mailto:sage [2007/07/28(土) 12:04:59 ID:???]
>>580
select sum(data),gid from user_tp group by gid order by sum(data) desc;

582 名前:NAME IS NULL mailto:sage [2007/07/28(土) 12:24:35 ID:???]
>>581
アドバイスありがとうございます。
ただ、上記実行してみましたが

ERROR 1111 (HY000): Invalid use of group function

となってしまいます。もしかして、MySQLのバージョンが古い!?(T.T)
ちなみにバージョンは、4.1.20です。

583 名前:NAME IS NULL mailto:sage [2007/07/28(土) 12:33:25 ID:???]
>>581
解決しました!

select sum(data) as sum,gid from user_tp group by gid order by sum desc;

で関数値にエイリアスを切ったら解決でした!
本当にありがとうございました。助かりました。感謝です!

584 名前:NAME IS NULL mailto:sage [2007/07/28(土) 12:39:24 ID:???]
>>582
それは4.xのバグらしい。
回避策は>>583

585 名前:NAME IS NULLPO [2007/07/28(土) 17:38:07 ID:crv3ux+p]
オラクルを利用しています。質問があります。

以下の通り実行する場合にテーブルをロック、アンロックする方法を教えて下さい。

1.テーブルAをロック

2.テーブルBを更新(UPDATE)

3.テーブルAにSELECT文を実施

4.テーブルAのロックを解除。

586 名前:NAME IS NULL mailto:sage [2007/07/28(土) 18:53:52 ID:???]
>>585
テーブルロックは LOCK TABLE 文。
アンロックは COMMIT または ROLLBACK。

しかしテーブル全体をロックしなければならないっていう設計はちょっとどうかと。
せめて 1. の代わりに SELECT 〜 FOR UPDATE ぐらいにしたほうがマシかも。
まあ詳しい要件が分からんので何とも言えんけど。

587 名前:NAME IS NULL mailto:sage [2007/07/28(土) 20:05:45 ID:???]
SP実行開始時には、更新を行うテーブルは必ずテーブルロックを行う事。

という共通規約が存在する漏れのプロジェクト・・・

588 名前:NAME IS NULL mailto:sage [2007/07/28(土) 20:31:54 ID:???]
>>587
かかわりたくない池沼なプロジェクトだな。

589 名前:NAME IS NULL mailto:sage [2007/07/28(土) 20:37:39 ID:???]
あまり優秀じゃないプログラマを何人も使うようなプロジェクトじゃよくあること。

590 名前:NAME IS NULL mailto:sage [2007/07/28(土) 22:33:37 ID:???]
それはあまり優秀どころか、ロックの存在をしらなくて、バッチ処理しか経験のない
元COBOLerの素人集団では・・・。



591 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 07:47:30 ID:???]
>>587のところがそうなのかは知らないが、デッドロックを防ぐために
トランザクションの最初に特定の順序でテーブルロックするのは
普通だろ。

592 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 08:11:36 ID:???]
>>591
「必ずテーブルロックを行う事」っていう前提があればそうするかもしれないけど
その前提がそもそもバッチ志向から抜け出せていないっていう話では?

593 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 09:15:41 ID:???]
>>592
なぜここでバッチが出てくるのかわからないが、テーブルロックでなければならない
理由は、単にリソースのロック獲得順を明示的に制御できるのがテーブル単位だからだろ。

594 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 09:22:15 ID:???]
>>593
Oracleとかなら行単位でもロックできるけどね。

てかスレ違いだな。

595 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 09:47:50 ID:???]
ここで言ってるストアドプロシージャが、全件カーソルをまわして
1件ずつ更新して行くようなバッチ処理を想定してるのだろうな。
こういう処理が頻発するようならシステムの基本設計に問題があるとしかいえないな。

596 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 09:53:39 ID:???]
あー、なんか根本的に理解されていないみたいだけど、そういう理屈を全員に
教え込むのは大変だから、「更新するテーブルは最初にこの順番でロックすること。
これが決まりだ。」ってなるわけよ。

597 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 09:57:44 ID:???]
>>596
いや、それは分かるよ。
でも、そんなルールを作らなければならないようなプロジェクトには
できれば関わりたくないよね、と。

598 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 12:33:19 ID:???]
あ、>>596>>594宛ね。
この場合、明示的行ロックの機能があるかどうかってのは関係ないわけなんで、
そういうセリフが出てくるということは、まさにそういうプロジェクトで想定している
人材なのではないかと。

599 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 13:50:21 ID:???]
>>598
えと、俺は>>592=>>594=>>597なんだけど、
このスレにも「そういう人」がいることが分かって、
かと言ってこのスレ違いな議論をこれ以上続けるのもどうかと思って、
やや強引に議論を終わらせようとしただけなんだ。

600 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 15:33:35 ID:???]
MySQL4.1を利用しています。教えてください。

ある問題の過去問で

Q:
月間の残業時間が75時間以上の社員の社員コードと氏名を求めるSQLを実行したところ、
エラーで返された。
なぜエラーになったのか、20文字以内で記せ。

入力SQL文:
select 社員コード,氏名 from 社員テーブル where 社員コード = (select 社員コード from 勤務実績テーブル group by 社員コード having sum(残業時間) >=75);


なお、社員テーブルには
社員コード,氏名,課コード

勤務実績テーブルには
社員コード,年月日,所定労働時間,残業時間であり
各社員の1日ごとの所定労働時間,残業時間が1レコードとして1か月分入っている。

課テーブルには
課コード,課名

が入っている。

***
このとき、正しいSQL文はどうなるのでしょうか?
お願いします。



601 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 15:56:20 ID:???]
>>600
= を in に変えればとりあえず動くには動くだろうな。

602 名前:名無しさん@そうだ選挙に行こう mailto:sage [2007/07/29(日) 16:00:50 ID:???]
>>600
=をINにする。理由くらい自分で調べろ。

603 名前:NAME IS NULL mailto:sage [2007/07/30(月) 11:34:34 ID:???]
すいません。
顧客情報管理のDBを作成していて、
文字列の結合でつまってしまいました。。

Name Hobby
--------------------
aaaa 読書
aaaa 映画
bbbb 水泳
--------------------

上記のようなDBが有った場合に、

Name Hobby
--------------------
aaaa 読書、映画
bbbb 水泳
--------------------

と、表示させるSQLを教えてください。
異なるレコードの文字列結合が、うまく出来ない・・・


604 名前:NAME IS NULL mailto:sage [2007/07/30(月) 12:00:08 ID:???]
>>603
普通にName別にHobbyの内容を取得した後、
アプリケーション側で処理した方が楽だと思われ。
つ〜か、Nameが同一のレコードが1億件存在したら、
それだけ繋ぐ、って事だろ?正気の沙汰じゃないwww

俺なら
aaaa 読書 
bbbb 水泳 
が既存データとして存在していて、
そこに
aaaa 映画
を追加する必要が生じたら、
aaaa 読書、映画 
となるように最初からデータ操作するが。


605 名前:NAME IS NULL mailto:sage [2007/07/30(月) 12:10:30 ID:???]
>>604
おっしゃる事は、ごもっともなのですが、
どうやら仕様上そういう風にSQLを練らないといけないようで。。。
(HOBBYを個々に扱う場所も有るから、まとめて登録も不可のようです)
CONCATをうまく使って、レコード間の結合なんて出来ないかしら?と、思って
調べているのですが、自分の技術力ではサッパリです。

ご回答、ありがとうございます。

606 名前:NAME IS NULL mailto:sage [2007/07/30(月) 12:42:19 ID:???]
group_concat(Hobby separator '、')

607 名前:606 mailto:sage [2007/07/30(月) 13:13:46 ID:???]
ゴメン、MySQLスレと勘違いしてた
group_concatとRDBMS名でググればヒントあるかも

608 名前:NAME IS NULL mailto:sage [2007/07/30(月) 14:04:48 ID:???]
>>606
調べてみました。
残念ながら、当方、postgresなので使えない様子。
DBの種類は最初に書くべきでした。
申し訳ないです。

ひきつづき、調べます。
ヒント、ありがとうございます。

609 名前:NAME IS NULL mailto:sage [2007/07/30(月) 16:31:56 ID:???]
PostgreSQLでは複数行の文字列連結はなかったはず。
PL/pgSQLなどで関数自作するしかないな。

610 名前:NAME IS NULL [2007/07/30(月) 16:33:46 ID:w7x3AyYR]
>>198とよく似た疑問なんですが
1列目…2つの日付の差を表示
2列目…それが7日以上差があれば○と表示
というSQL文で(DBMSはOracleです)

SELECT TO_DATE(DATE1,'YYYYMMDD')-TO_DATE(DATE2,'YYYYMMDD'),
CASE WHEN TO_DATE(DATE1,'YYYYMMDD')-TO_DATE(DATE2,'YYYYMMDD') >= 7
THEN '○' ELSE NULL END FROM TABLE1 ...

この重複しているTO_DATE〜の2回目をもっと簡潔に書く方法は
やっぱりないんでしょうか?



611 名前:NAME IS NULL mailto:sage [2007/07/30(月) 17:53:56 ID:???]
>>610
Oracleで動くかどうか知らんが、FROM句のない相関クエリで多少短くなる。

SELECT TO_DATE(DATE1,'YYYYMMDD')-TO_DATE(DATE2,'YYYYMMDD') AS ITV,
(SELECT CASE WHEN T1.ITV >= THEN '○' ELSE NULL END) FROM Table1 AS T1;

612 名前:NAME IS NULL mailto:sage [2007/07/30(月) 17:56:02 ID:???]
あ、うそ。T1.ITVってないな。
ゴメソ。

613 名前:NAME IS NULL mailto:sage [2007/07/30(月) 19:27:36 ID:???]
>>610
サブクエリにして別名つけるとか。

SELLECT ITV, CASE WHEN ITV >= 7 THEN '○' ELSE NULL END
FROM (SELECT TO_DATE(DATE1,'YYYYMMDD')-TO_DATE(DATE2,'YYYYMMDD') AS ITV FROM TABLE1 ... )

614 名前:NAME IS NULL mailto:sage [2007/07/30(月) 20:07:51 ID:???]
>>610
システム内でその演算の出現頻度が高いなら、ファンクション化。

615 名前:NAME IS NULL [2007/07/31(火) 12:22:42 ID:JPI88QGA]
SQL文に現在時刻を使う場合、
アプリ側かSQL側(CURRENT_DATEなど)、どちらで取るほうがよいでしょうか?

ちなみに私の環境は、アプリ側はPHP5、MYSQL5で、
WEB、DBとサーバーが別です。

私の環境において、一般的に、どちらでも構いません。
理由をつけてご回答頂けると幸いです。
よろしくお願いします。

616 名前:NAME IS NULL mailto:sage [2007/07/31(火) 12:31:54 ID:???]
>>615
おれはサーバー側で取るようにしてる。理由は、クライアントの時間が信用できないから。
ま、Web サーバーがひとつだけなら大丈夫なんだろうけど。

617 名前:NAME IS NULL mailto:sage [2007/07/31(火) 14:02:11 ID:???]
>>615
何を重視するかによるかな。
DBに対してアクセスするクライアントが複数ある場合は、
DBの時刻関数を使うことで一貫性が保てる。

逆にアプリで時刻を取得した方がいいケースとしては、
複数のクエリを発行するときにその中で現在時刻が要求され、
それぞれが同じである必要がある場合など。
動的に時刻を取得すると、毎回違う時刻になっちゃうからな。

618 名前:NAME IS NULL mailto:sage [2007/07/31(火) 15:13:45 ID:???]
Oracle10gです。

カーソル定義の際に 複数テーブル(5つ位)をJOINで結合させたカーソルに対
して "FOR UPDATE" 句を使用し、カーソル内で CURRENT行 に対する UPDATEを
行いたいんですが。

UPDATE出来るテーブル、出来ないテーブルの違いは何でしょうか。
例えばこれが2つのテーブルA・Bで、結合結果がA:1対B:多となるような場合に
テーブルAに対して CURRENT OF cur でUPDATE出来ないのは分かるんですが。

単純に「UPDATEしたら複数行が更新されそう」なTBLはUPDATE不可、と考えて
大丈夫でしょうか?


619 名前:615 mailto:sage [2007/07/31(火) 17:18:25 ID:???]
>>616,617
ありがとうございます。
環境により使い分けるってことですね。ごもっともです。
私の場合、特にMYSQLのNOW()や型のTIMESTAMPなどは便利なので、
何とかSQL側で使ってやりたいというのが本音ですが、
逆にログに出したときに分かりにくい、保守性も少し下がるというのが
懸念点です。

620 名前:NAME IS NULL mailto:sage [2007/07/31(火) 17:24:26 ID:???]
>逆にログに出したときに分かりにくい、保守性も少し下がるというのが
kwsk



621 名前:615 mailto:sage [2007/07/31(火) 17:46:17 ID:???]
>>620
アプリ側で時間を取得して実行した場合には、ログには
 SELECT * FROM TABLE WHERE time > '2007-07-31 17:42:00'
のように出ますが、SQL側で取得した場合には
 SELECT * FROM TABLE WHERE time > NOW()
のように、これを見ただけではどのようなデータが出たのか分かりくいと思いまして。
まあ、そのログの時間を考えれば分かるのですけど。

また、保守性に関してですが、アプリ側だけで考えた場合には
何をしているのか読みにくいのかなぁと思いまして。
特にSQLはほとんど基本だけ押さえてそれ以上は勉強しない人が多いようですし。

ちょっと断定するほどの理由にはなりませんね、申し訳ないです。

622 名前:NAME IS NULL [2007/07/31(火) 20:17:31 ID:gWtvLAd+]
PostgreSQL8.2.3です。

lhs,rhs,result
---------------
1,3,0
4,1,0
1,0,0
8,8,0

というテーブルに以下のSQLを流してresultを一括更新しようと思っています。
UPDATE テーブル名 SET result = lhs / rhs;

しかし1行でもrhsに0が入っていると、division by zeroのエラーが出てしまいます。
その1行が更新されないのは仕方ありませんが、他の行まで更新されないので困っています。
なにか良い方法は無いでしょうか?

623 名前:NAME IS NULL mailto:sage [2007/07/31(火) 20:19:55 ID:???]
> UPDATE テーブル名 SET result = lhs / rhs;
where rhs <> 0

でいいやん

624 名前:NAME IS NULL [2007/07/31(火) 20:19:56 ID:NYEBxcjn]
access2000のMDBファイルにCreate文を投げて10進型のカラムを10桁&小数点3で作成したいのですが
decimal という型はないようなのです
numericだとどうもDoubleになっているようだし・・・
すみませんがご存知の方お教え願えませんか?

625 名前:NAME IS NULL mailto:sage [2007/07/31(火) 20:22:08 ID:???]
>>624
10進型なら、Currency になるはず。桁数の指定はできないよ。

626 名前:NAME IS NULL mailto:sage [2007/07/31(火) 20:33:57 ID:???]
>>618
更新可能な結合ビュー(↓)と同じ条件と思っていいんじゃない?知らんけど。
otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19215-02/schema.htm#5107

627 名前:624 [2007/07/31(火) 20:48:47 ID:NYEBxcjn]
>>625
レスありがとうございます。
やってみたんですが、どうも通貨型になっているようです。
説明の方法が悪かったような気がするのですが
10進型というのはACCESSのデザインでいうところの
数値型のカラムでフィールドサイズが10進型ということなのです・・・
説明悪くてごめんなさい

628 名前:NAME IS NULL mailto:sage [2007/08/01(水) 01:40:00 ID:???]
すいません。

date data
--------------------
7/24 aaa
7/25 bbb
7/26 ccc
--------------------

上記のようなDBが有った場合に、

date data
--------------------
7/25 bbb
7/26 ccc
7/27 ccc
--------------------

一番古いレコードを削除して、新しいレコードを
コピーしたあと、日付を+1したいのですが
削除は出来ても、dateがユニークであるため
コピーして更新が出来ません・・・。
どうしたら良いのでしょうか?

629 名前:NAME IS NULL mailto:sage [2007/08/01(水) 02:01:52 ID:???]
>>628
dateがDATE型かどうかわかんらが、こういうことかな?
INSERT INTO Table SELECT date+ interval'1 day' FROM Table WHERE date=(SELECT max(date) FROM Table);

630 名前:NAME IS NULL mailto:sage [2007/08/01(水) 16:52:16 ID:???]
628です。ごめんなさい。書いた後にすぐ落ちてました(汗
ふーむ、やっぱり、1つのコマンドで足りるんですね。
ありがとうございました。参考にさせて頂きます。



631 名前:NAME IS NULL [2007/08/03(金) 16:37:00 ID:dBeTviY8]
質問です。
DBはORACLE9iで下記SQLを実行すると
delete from
(select * from
(select rn ,id from
(select rownum rn ,id from
(select rowid id from AAAA order by update_time desc)))
BBBB, AAAA where AAAA.rowid = BBBB.id AND AAAA.rn > 3)

「SQL実行中に以下のエラーが発生しました。」
「ORA-01752: 複数表のビューから削除できません。」

のように表示されます。何か対処法はあるのでしょうか?
やりたいことはAAAAテーブルのupdate_timeが最新の項目を3項目残し、
残りは削除したい。

後、以下のようなSQLを実行すると

select count(*) from AAAA where itmcnt='05'

「ORA-00937: 単一グループのグループ関数ではありません。」

AAAAテーブル内のitmcnt=5のカウントを求めたいだけなんですけど。

以上、宜しく御願いします。

632 名前:NAME IS NULL mailto:sage [2007/08/03(金) 17:53:07 ID:???]
delete from の後ろに消したいテーブル名入れて、その後ろに条件入れる
あと、count(*) はgroup by itmcnt でどうか

633 名前:NAME IS NULL mailto:sage [2007/08/03(金) 18:15:40 ID:???]
こんな感じで。

delete AAAA
where rowid in (
select rowid from (
select rowid from AAAA order by update_time desc
) where rownum <=3);

後者はcounr(*)以外に何かはいってませんか?
グループ関数のみの場合はgroup by指定しないでもいけたとおもうんだけど。


634 名前:NAME IS NULL [2007/08/06(月) 04:46:21 ID:HzzUCyP6]
とりあえずMySQLです。

  あるフィールドが「NULLではなく、かつ 1 以上」だったら〜

という条件式は、比較的色んなところで使いそうな気がするのですが、
これをさくっと記述する方法はありませんか?

素直にANDで2つ書くしかないでしょうか。

635 名前:NAME IS NULL mailto:sage [2007/08/06(月) 04:51:35 ID:???]
>>634
単純に column >= 1 だけでいいんじゃないの?
IS NOT NULLは書かなくてもNULLは弾かれるだろうし。

636 名前:634 mailto:sage [2007/08/06(月) 05:21:22 ID:???]
ごめん。超ごめん。寝ボケてた。
NULLもしくは0のフィールドです。全くもって逆です。吊ってきます。

(column >= 1)=0 とかでイケるかな?とか思ったけどダメだった。

637 名前:NAME IS NULL mailto:sage [2007/08/06(月) 06:06:40 ID:???]
>>636
MySQLでは無理かもしれんが、それに近いのに
(column >= 0) IS NOT TRUE
がある。さくっと記述できるかどうかはナニだが。

他には COALESCE(column,0) = 0 とか。


638 名前:634 mailto:sage [2007/08/06(月) 06:12:07 ID:???]
>635>637
2人ともこんな時間にありがとう。色々試してみることにします。そして寝る。

639 名前:NAME IS NULL mailto:sage [2007/08/06(月) 06:13:27 ID:???]
補足。
(column >= 0) IS NOT TRUE と COALESCE(column,0) = 0 両方とも
インデックスが効かない可能性がある。その辺りはDBに依存するだろうけど、
現実的にはCOALESCEで関数インデックスかな。使えればの話だけど。

640 名前:NAME IS NULL mailto:sage [2007/08/06(月) 06:24:28 ID:???]
NULLをインデックスで引けるDBMSなんて存在するの?



641 名前:NAME IS NULL mailto:sage [2007/08/06(月) 06:41:15 ID:???]
>>640
あ、言われてみればそうだなw。
MS-SQL鯖なら引きそうな気もするが。

642 名前:NAME IS NULL mailto:sage [2007/08/06(月) 06:41:32 ID:???]
確かSQLServer
ただ、UNIQUEでNULLは1レコードのみって理解に苦しむ仕様だったような。

643 名前:NAME IS NULL [2007/08/06(月) 07:46:10 ID:zdKH8zBk]

www.leah-d.com/index412.php/?na=412


644 名前:NAME IS NULL mailto:sage [2007/08/09(木) 11:53:46 ID:???]
JOINってカッコで囲わなくても問題無いのは、もしかして常識?

今までずっと

((A JOIN B USING 〜) JOIN C USING 〜) JOIN D USING 〜

て書くのが当たり前だと思ってなんですが、ふと思って

A
JOIN B USING 〜
JOIN C USING 〜
JOIN D USING 〜

て書いてもなんらエラーにならなかったんで。これでいくつテーブルを
繋げてもそれなりに見やすいSQLになるかな

645 名前:NAME IS NULL mailto:sage [2007/08/09(木) 12:37:49 ID:???]
>>644
たぶんみんな知ってる。
でも、Accessだけは、ネストして書かないと通らない。

646 名前:NAME IS NULL [2007/08/09(木) 22:44:24 ID:xEU1tKZW]
minus
これはなんて読むんでしょう?

647 名前:NAME IS NULL [2007/08/09(木) 22:45:07 ID:xEU1tKZW]
マイナス?


648 名前:NAME IS NULL mailto:sage [2007/08/09(木) 22:50:27 ID:???]
マイナス。

649 名前:NAME IS NULL [2007/08/09(木) 22:53:00 ID:xEU1tKZW]
>>648
マイナスで合ってます?UNIONは読めたのですが、
こちらは一瞬わからなかったです(^▽^;)
ありがとうございました。

650 名前:NAME IS NULL [2007/08/09(木) 22:54:39 ID:xEU1tKZW]
教えてください。

所属A 所属B 所属C
A    B    C
B    C    D
C    D    E

この状態で、所属Cに、まだ登録されていない
所属A,所属Bの人間を集めたいのですが、、、
(最終的に、所属Cには(A,B,C,D,E)という状態にしたい)

この場合、NOT EXISTSを使った、INSERTが早いでしょうか?
MINUSを使った、INSERTが早いでしょうか?

アドバイスがありましたら、よろしくお願いいたします。




651 名前:NAME IS NULL mailto:sage [2007/08/09(木) 23:03:38 ID:???]
>>650
直感的にはNOT EXISTSだと思うけど
実データに近い形で実行計画とってみないと何とも。

652 名前:NAME IS NULL [2007/08/09(木) 23:13:35 ID:xEU1tKZW]
>>650 の続きです、、

1つのSQLで行う方法と、2つのSQLで行う方法は、
この場合、どちらが処理的に効率が良いでしょう?

@1つのSQLの場合
・所属A,所属BをUNIONしたあとで、MINUS(またはEXISTS) 所属C という方法と

A2つのSQLにわける場合
・所属A MINUS(またはEXISTS) 所属C
・所属B MINUS(またはEXISTS) 所属C


経験が浅く、SQLの知識があまりないもので、、
質問ばかりになってしまいましたが、お力をお貸し下さい。。


653 名前:NAME IS NULL [2007/08/09(木) 23:20:45 ID:xEU1tKZW]
>>651
やはりNOT EXISTの方が若干はやいでしょうか?
それとも、そんなに変わらなければ、気にしなくても良いのかななんて(^▽^;)

654 名前:NAME IS NULL mailto:sage [2007/08/09(木) 23:37:55 ID:???]
>>653
数百〜数千レコードの規模のデータ量なら、どれも大して変わらなそう。
パフォーマンスを気にするのは、その上のオーダーからかな。
1か2で選ぶなら、俺なら2の方。

極限のパフォーマンスを目指すなら、

- 一時テーブルDを作成
- Cにインデックス付与
- A-CをDにinsert
- B-CをDにinsert
- Cのインデックス除去
- Dにインデックス付与
- DのdistinctをCにinsert
- Dをdrop

でもここまでやる必要があるのは、数百万件クラスのバッチ処理くらいかと。

655 名前:NAME IS NULL [2007/08/10(金) 13:50:15 ID:nDGcrBFR]
>>654
処理レコードは数千レコードあって1万レコード
ですので、それほど意識しなくてもよさげですね
アドバイスありがとうございました。

656 名前:NAME IS NULL mailto:sage [2007/08/10(金) 21:11:29 ID:???]
>>654
それ何回 full scan かかるんだぁ?

657 名前:NAME IS NULL mailto:sage [2007/08/11(土) 18:37:34 ID:???]
簡単に極限とか言っちゃダメだよ

プラチナムより上のクラス(計測不能)の人がここ覗いてるんだからさ

658 名前:NAME IS NULL mailto:sage [2007/08/16(木) 03:25:21 ID:???]
MySQL をよく使っています。

二つのある特殊な検索エンジンからの検索結果の積集合をとれるような
アプリケーションを考えています。検索エンジンからの回答には、
スコアなどの付帯情報はありません。単に8文字の文書IDのみが返ってきます。
LOAD DATA を使って外部から回答をもらってくることを想像しています。

片方の検索結果は0から1000万件、片方の検索結果は0から1万件前後出てきます。
一度 MySQL にインポートする、というのもそもそも考えなければならないと思いますが、
これはいったいぜんたいどのように設計すればよいでしょうか。

Table: search_result_1
Create Table: CREATE TEMPORARY TABLE `search_result_1` (
`qid` int(11) NOT NULL,
`result` varchar(8) NOT NULL,
KEY `qid` (`qid`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1

Table: search_result_2
Create Table: CREATE TEMPORARY TABLE `search_result_2` (
`qid` int(11) NOT NULL,
`result` varchar(8) NOT NULL,
KEY `qid` (`qid`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1

Table: search_query
Create Table: CREATE TEMPORARY TABLE `search_query` (
`qid` int(11) NOT NULL,
`expression` varchar(255) NOT NULL,
`lastused` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`qid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

上記のような感じで手元で試してみました。

SELECT COUNT(*) FROM search_result_1 WHERE qid=1; -- 1995259件
SELECT COUNT(*) FROM search_result_2 WHERE qid=1; -- 147件
このような状況で、次のようなクエリを投げました。

SELECT search_result_1.result
FROM search_result_1, search_result_2
WHERE search_result_1.result = sarch_result_2.result
AND search_result_1.qid=1 AND search_result_2.qid=1;

一分半かかりました。CPUは100%使いきり、スワップは起こっていないようです。
ハードウェアに多少お金がかかってもいいのでもう少し高速に結果を得たいのですが
(願わくは1秒以内) 、なにかアドバイスをいただけませんか。

659 名前:658 mailto:sage [2007/08/16(木) 03:34:26 ID:???]
というかすいません、一分半で御の字のような気がしてきました。
それぞれの検索結果の取得でも何分もかかるわけですし。
むしろスケールアウトするような構成を考えなければならないような。
もう寝るべきですね。スレを汚してすいません。

660 名前:NAME IS NULL mailto:sage [2007/08/16(木) 07:18:01 ID:???]
>>658
書いた内容だと、やりたい事が完全に理解しきれない。

まず、search_queryは何に使うのか。

それと、LOAD DATAはエンドユーザからの検索に対して
毎度行われるのか、それともLOAD DATAがされた後に
そのデータが使いまわされて、それを高速にしたいのか。

後者の場合なら、search_result_1の内容をsearch_result_2に
存在するresultのものだけ残すようにすればレコード数は格段に減る。

メモリが潤沢なら、type=heapでのcreate tableも試してみたら?



661 名前:NAME IS NULL mailto:sage [2007/08/16(木) 07:21:57 ID:???]
>>660
すまん、ENGINE=MEMORYって書いてあるから、type=heapと
同じことは既に試してるんだね。この記述は無視して。

662 名前:NAME IS NULL mailto:sage [2007/08/16(木) 09:14:23 ID:???]
>>658-659
> 一分半で御の字のような気がしてきました。
> それぞれの検索結果の取得でも何分もかかるわけですし。
自分で答え書いてんじゃん。

それはともかく、検索エンジンからとってきた結果を一回しか使わないなら
そもそもDBに入れる意味が薄い。
DBに入れるオーバヘッドが余計にかかるだけ。
スケールアウトするって言ってもそのためのオーバヘッドもかかるし。
それよりはファイルに落としてsortしてcommしたほうが速いんじゃないの?
それか、ハッシュテーブル作るプログラムを自前で書くとか。

663 名前:NAME IS NULL mailto:sage [2007/08/16(木) 09:51:39 ID:???]
俺ならresult2のqid=1なresultでハッシュ作っておき、result1を
読みつつハッシュひいてあれば出力みたいにすると思う。result2は
8文字の文書IDが1万件までって条件だからハッシュはメモリに置いて
全く問題ない量だろ。これだけのことのためにDB使うのは無駄だな。


664 名前:NAME IS NULL [2007/08/16(木) 14:28:25 ID:rMjnc/Rn]
INSERT文で聞きたい。SQLServer2005を使用。

テーブル名:Table

ID 名前1 名前2
-----------------
1  山田  太郎
2  鈴木  一郎

このようなテーブルがあるとして

IDが「1」の情報をINSERT文で作りたい。
しかしID「1」の情報はわからず、
ID「1」の情報をコピーして、同じテーブル内で
新規作成したい。

結果として

テーブル名:Table

ID 名前1 名前2
-----------------
1  山田 太郎
2  鈴木 一郎
3  山田 太郎

このような結果にしたい。
どんなSQL文にしたらいいのか?



665 名前:NAME IS NULL mailto:sage [2007/08/16(木) 14:34:14 ID:???]
IDをどうやって生成するのかわからんけど
INSERT INTO の VALUES 以降を SELECT文にできるよ

666 名前:NAME IS NULL mailto:sage [2007/08/16(木) 14:34:30 ID:???]
insert into Table(名前1, 名前2) select 名前1, 名前2 from Table where ID = 1

667 名前:NAME IS NULL [2007/08/16(木) 15:50:36 ID:rMjnc/Rn]
>>665-666

やってみたんだが、IDがプライマリキーなのかもしれないが、
キーが重複している…というようなエラーがでてしまった。

原因はわかる?

668 名前:NAME IS NULL mailto:sage [2007/08/16(木) 15:57:47 ID:???]
>>667
666でやるならIDはIndentity属性(自動採番)になってる必要がある。
insert into table select * from tabel where なんてやってたら重複するのは当然。
新規IDはmax+1でも何とかなるが実務で使うのはやめとけ。

669 名前:NAME IS NULL mailto:sage [2007/08/16(木) 16:08:07 ID:???]
>>667
insert into Table
select A.max_ID + 1, B.名前1, B.名前2
from (select max(ID) as max_ID from Table) A,
   (select 名前1, 名前2 from Table where ID = 1) B

670 名前:NAME IS NULL mailto:sage [2007/08/16(木) 16:11:53 ID:???]
>>664の通りにやるなら
INSERT INTO table (ID,名前1, 名前2) SELECT 3, 名前1, 名前2 FROM table WHERE ID = 1
でいいけどなー



671 名前:NAME IS NULL [2007/08/16(木) 16:25:02 ID:rMjnc/Rn]
>>670

確かに。これだったらID「1」の情報がコピーされて
ID「3」として新規作成される。

でも、テーブルに今使えるIDがわからなかったとしたらどうだろうか?
MAX(ID)を試しに、SELECT文後のIDの所に入れてみたが
GROUP BY句…のようなエラーがでた。

672 名前:NAME IS NULL mailto:sage [2007/08/16(木) 16:30:55 ID:???]
>>671
単純にMAX(ID)と書けないから、結果的に >>669 のような書き方にならざるを得ない。
答えが書いてあるのに、なぜ試さない?

673 名前:NAME IS NULL [2007/08/16(木) 16:37:06 ID:rMjnc/Rn]
>>672
>>669

すまない。試してみるよ。
また何かあったら頼む。

674 名前:NAME IS NULL [2007/08/16(木) 16:53:48 ID:rMjnc/Rn]
>>673です。

>>672
>>669

やってみた。確かにきれいにテーブルに反映される。
答えてくれてありがとう。

しかし、自分はまだまだSQL初心者。
聞きたいことがあるんだが、
A・Bとか、あれはなんだろうか?

解説が聞きたい。意味も知らずに使いたくはないので
ご教授願いたい。

675 名前:NAME IS NULL mailto:sage [2007/08/16(木) 17:06:15 ID:???]
>>674
それは別名(Alias)で直前の括弧の中のSELECT分の結果をAという名前のテーブルに見立て、
外側のSQLからその名前で参照する。

>ご教授願いたい。 
普通に教えてくれとなぜ言わない。使い慣れない敬語使わんほうがいい。


676 名前:NAME IS NULL mailto:sage [2007/08/16(木) 17:37:47 ID:???]
そこかしこで見るから最近は 「か、漢だ…!」系ネタに見える <ご教授ください


677 名前:NAME IS NULL [2007/08/16(木) 17:37:52 ID:rMjnc/Rn]
>>675

教えてくれてありがとう。
なんとなくだがわかった。

また何かあったら頼む。

678 名前:NAME IS NULL [2007/08/16(木) 18:42:37 ID:ANt5VVpQ]
やり方があったら教えてください。

上位10件を取得するとき、Oracleだと
WHERE ROWNUM <= 10 ....
SQL Serverだと
SELECT TOP 10 ...
と書きますが、
Derbyだとどのように書けばいいのでしょうか。
調べた限りだとそのような物は準備されていないので、
そのやり方を教えてください。お願いします。

679 名前:NAME IS NULL mailto:sage [2007/08/17(金) 04:03:29 ID:???]
>>678
マニュアルに載ってなければないんじゃない?
無理やりやるなら>>551あたりを参照。

680 名前:NAME IS NULL mailto:sage [2007/08/17(金) 10:58:46 ID:???]
>>679
ありがとうございます。やっぱり無理そうですね。

素直にカーソルまわします。



681 名前:NAME IS NULL mailto:sage [2007/08/17(金) 11:36:49 ID:???]
DerbyはまだLIMIT OFFSET対応して無いのか・・

682 名前:NAME IS NULL [2007/08/17(金) 11:43:08 ID:H0kCuNJM]
おそらく初心者質問でありそうで悪いのですが、

SELECT *
 FROM T_TEST1
 INNER JOIN T_TEST2
  ON T_TEST1.ID = T_TEST2.ID

というSELECT文だとT_TEST1.IDがT_TEST2.IDに存在するものだけ抽出されますが、
逆にT_TEST1.IDがT_TEST2.IDに存在「しない」ものだけ抽出するにはどうすればよいですか?
T_TEST2.IDが拒否リストであるようなイメージです。

検索キーワードだけでも結構ですので、よろしくお願いします

683 名前:NAME IS NULL mailto:sage [2007/08/17(金) 12:08:17 ID:???]
ぱっと思いつくのはこんなんかな。
select * from T_TEST1 where T_TEST1.ID not in (select T_TEST2.ID from T_TEST2)
select * from T_TEST1 where not exists (select * from T_TEST2 where T_TEST1.ID = T_TEST2.ID)


684 名前:NAME IS NULL mailto:sage [2007/08/17(金) 14:54:21 ID:???]
SQL2000で教えてください

テーブルにint型の列A〜Zがあり、その合計値を新しく追加するint型の列Summaryに書きだす必要があります
列A〜ZにはNULL値が入る場合もあります
列A〜Zの合計値はint型で記憶できる範囲を超えることはありません(各列の値は-100〜100かNULL)

最初UPDATE文で Summary = A + B + ... + Z とやってみたのですが、途中にNULLが一つでもあると結果がNULLになってしまいます
全てNULLのときはNULLに、NULL以外の値があるときはその値の合計値にしたいです

とりあえず CASE WHEN A IS NULL AND ... AND Z IS NULL THEN NULL ELSE ISNULL(A, 0) + ... + ISNULL(Z, 0) END とかやってみましたが、スマートな感じがしません
何か良い方法はないでしょうか

685 名前:684 mailto:sage [2007/08/17(金) 14:57:38 ID:???]
書き忘れていました

対象は SQL Server 2000 Enterprise Edition (SP4) です

同じようなテーブルが100以上あり、それぞれ百万件単位のデータが日々入れ替わるので、できるだけ処理を軽くしたいです
SQLの自体はどんなに長くても構わないので、処理の速さを求めています。。。

686 名前:NAME IS NULL mailto:sage [2007/08/17(金) 15:03:05 ID:???]
CASEよりCOALESCEの方がちょっぴり短くなる。
>スマートな感じがしません 
>処理の速さを求めています
どっちを優先したいのよw

687 名前:NAME IS NULL mailto:sage [2007/08/17(金) 15:52:58 ID:???]
入力日、入力者、入力時刻、金額のフィールドーが有る仮定で、そのテーブル
から

日々の合計金額
一日の中で最後に入力された時刻
その時刻に入力した入力者

を取得したいんですが、SQL1発で取得する良い方法はありませんか?
サブクエリでmax(入力時刻)を求めた上で、その値に一致する行の入力者を求
める、という方法なら普通に分かるのですが、折角のOracle10gなんで
partition by?last?みたいな関数を使えばもしかするとすっきり書いたり
出来るんでしょうか?

688 名前:NAME IS NULL mailto:sage [2007/08/17(金) 16:14:05 ID:???]
>>686
情報ありがとございます、BOL見てみます

> どっちを優先したいのよw

自分で書いたのが無駄に長く遅いような感じがして、スマートじゃないと表現してしまいました
目的はあくまでも処理の速さです

689 名前:NAME IS NULL mailto:sage [2007/08/17(金) 16:19:53 ID:???]
>>684
case
when coalesce(a, b, c, ..., x, y, z) is null then null
else isnull(a, 0) + isnull(b, 0) + isnull(c, 0) + ... + isnull(z, 0)
end

> テーブルにint型の列A〜Zがあり
> 同じようなテーブルが100以上あり

ネタだと思うが、マジなら設計を見直した方がいいと思う。

690 名前:NAME IS NULL mailto:sage [2007/08/17(金) 16:20:22 ID:???]
>>688
じゃあえて反対を(笑)、スマートだけど処理速度は保証できない。
プランを確認して中間表を作ってないようなら使えるかもしれない。

select tt.id, sum(tt.sf) as total from 
 (select id, A as sf from table
  union all select id, B from table
   :
  union all select id, Z from table
) tt




691 名前:NAME IS NULL [2007/08/17(金) 17:16:15 ID:BRmKGHeD]
SQL ServerのSQLにて、日付型の表記を yyyy/MM/dd hh:mm:ss と
する事は出来ませんか?

Convertで120を設定すると yyyy-MM-dd hh:mm:ss になってしまいます。

692 名前:NAME IS NULL mailto:sage [2007/08/17(金) 17:33:00 ID:???]
>>691
111 は?

693 名前:691 mailto:sage [2007/08/17(金) 17:40:27 ID:???]
>>692
どうもです。

111 の場合、日付のみで、時間が入らないようです。

694 名前:NAME IS NULL mailto:sage [2007/08/17(金) 17:42:01 ID:???]
>>693
じゃ、120でやってREPLACE()で。

695 名前:691 mailto:sage [2007/08/17(金) 17:58:28 ID:???]
>>694
出来ました!
ありがとう御座います。

うーん、しかし、グリッドへの表示に置換までする価値が
あるのか自分の中で悩む。

表記は統一したいけど、余計な負荷が掛からない様にしたい。。
(まあ、3000件程度では、体感で何も変わりは無かったですが。)

696 名前:NAME IS NULL mailto:sage [2007/08/17(金) 22:15:15 ID:???]
>>691-695
convert(char(10), 日時, 111) + ' ' + convert(char(8), 日時 , 8) とかは?

697 名前:684 mailto:sage [2007/08/17(金) 22:28:51 ID:???]
>>689
情報ありがとうございます
686さんの情報を元に同じクエリを作ったところでした

>ネタだと思うが、マジなら設計を見直した方がいいと思う

ネタではなく本当なのです。。。
世界中の拠点からデータを集約しているのですが、各国で求められる情報が違い、設計当時(SQL Server 6.5の頃)はハードやインフラも貧弱で、論理的な対応ではなく物理的な対応でこなした名残だそうです
今は SQL Server 2008 を目指したリプレースの計画をしていて、1つのテーブルと、複数の変換パッケージで収まるようにするらしいです

>>690
そんな書き方もあるんですね
今回はもうテストに回してしまいましたが、個人的にチェックしてみようと思います
情報ありがとうございました

698 名前:NAME IS NULL mailto:sage [2007/08/18(土) 03:27:40 ID:???]
MySQL4で

SELECT COUNT(*) AS count したものを
WHERE count > 5 のように指定できないのですが仕様ということでいいですか?

他に同じことをする方法はありませんか?

699 名前:NAME IS NULL mailto:sage [2007/08/18(土) 04:05:20 ID:???]
>>698
MySQLに限らず仕様。
SELECTリストでの別名をWHERE句やHAVING句では使えない。
そもそもそこは、HAVING句じゃね。

SELECT c1,count(*) AS count FROM Table GROUP BY c1 HAVING count(*)>5;

700 名前:NAME IS NULL mailto:sage [2007/08/18(土) 08:08:19 ID:???]
>>699
で、できましたーーーーー!
ありがとうございます。

未だにWHEREとHAVINGの違いがわかってないようです



701 名前:NAME IS NULL mailto:sage [2007/08/19(日) 23:49:03 ID:???]


テーブル名:Table

番号 年月
-----------------
1   19230411   
1   19990621
1   20071211 ★
2   20011103
2   20060211 ★
3   20070222
3   20070413
3   20070802 ★

となっているとき
★マークのついた、各番号の最新の年月だけ抽出するには
どうすればよいでしょうか。よろしくお願いします><


702 名前:NAME IS NULL mailto:sage [2007/08/20(月) 00:20:53 ID:???]
>>701
過去スレをみればなんども出てくる質問だぞよ

703 名前:NAME IS NULL mailto:sage [2007/08/20(月) 06:33:13 ID:???]
さすがに初歩的すぎてレスつかないね。

select 番号, max(年月) from Table group by 番号

704 名前:NAME IS NULL mailto:sage [2007/08/20(月) 12:35:47 ID:???]
>>703
それじゃ駄目だろ。

705 名前:NAME IS NULL mailto:sage [2007/08/20(月) 13:54:54 ID:???]
703じゃないけど、何が駄目なの?

706 名前:704 mailto:sage [2007/08/20(月) 15:12:19 ID:???]
は?なに言っているんだよ。

と、思いましたが、すみません。
再度>>701を読み返したら、自分が勘違いしていました。
>>703であっています。

707 名前:NAME IS NULL mailto:sage [2007/08/20(月) 15:52:27 ID:???]
過去スレ、レスで何度も出てくるのは
カラムがそれより多いケースだよなw

>>701のはあまりにも基本的過ぎる

708 名前:NAME IS NULL mailto:sage [2007/08/20(月) 21:11:14 ID:???]
ここは「宿題は自力でやれ」ってレスすべきだったんじゃないのか?

709 名前:NAME IS NULL mailto:sage [2007/08/20(月) 23:26:52 ID:???]
まあ、それじゃあんまりだから、「group by と max を調べてみな。」ぐらいでどうか。

710 名前:NAME IS NULL [2007/08/21(火) 07:51:49 ID:hZSddUM6]
カラムにHTML形式のデータ100行ぐらい分まるごと放り込むって
バカな仕様でしょうか?
カラムに放り込むデータが大きすぎるとパフォーマンスは落ちますか?



711 名前:NAME IS NULL mailto:sage [2007/08/21(火) 09:32:18 ID:???]
それが必要ならそうすればいいと思うよ

712 名前:NAME IS NULL mailto:sage [2007/08/21(火) 10:54:22 ID:???]
>>710
経験的には、そういうシステムは何度か見てきた。
ファイルで保持するケースとで、一長一短だよ。
それぞれで実装した場合を見比べて、これから作ろうとしてる
システムではどっちが後々困らないか検討すべし。

713 名前:NAME IS NULL mailto:sage [2007/08/21(火) 20:16:27 ID:???]
postgreSQLで質問です
EXTRACT()ですが、下記の様なテーブルに対して
SELECT EXTRACT(MONTH FROM TIMESTAMP '日付') as date from テーブルA
というようなクエリは不可能なのでしょうか?

テーブルA
----------------
ID (integer)
名前(text)
日付(timestamp)
----------------

つまり、EXTRACTの”EXTRACT (field FROM source)”の
sourceの部分に既存カラム名を指定、という事です。
psqlから実行する限りでは
ERROR: invalid input syntax for type timestamp: "日付"
というエラーになりますが、なにかTipsでこういった事が実現できたらと思いまして…。

714 名前:NAME IS NULL mailto:sage [2007/08/21(火) 20:46:10 ID:???]
>>713
カラム名で指定する場合は、クォーテーションで囲む必要なし。

715 名前:713 mailto:sage [2007/08/21(火) 21:00:57 ID:???]
>>714
ありがとうございます
ERROR: syntax error at or near "日付" at character 37
のエラーとなりました。
*「日付」は実際にはシングルバイトのカラム名です

今、to_char(timestamp, text)も試してたんですが
やはり” timestamp”の所にカラム名を入れるとエラーになってしまいます…。
こちらの場合は
ERROR: function to_char(text, "unknown") does not exist
HINT: No function matches the given name and argument types. You may need to add explicit type casts.
のエラーだったんで::TIMESTAMPとか入れてキャストしてみようかと。

716 名前:713 mailto:sage [2007/08/21(火) 21:20:05 ID:???]
型キャストもどうにもダメで下記で解決しました

SELECT substr(日付,0,8) as date from テーブルA
SQLは色んな表現の仕方があっておもしろいです。

実行速度も計ってみたいんで引き続き
>>713
>>715
のような表現の正しい表記を教えて頂きたいです。

717 名前:710 mailto:sage [2007/08/21(火) 22:18:56 ID:???]
>>711 >>712
ありがとうございます。
HTML放り込みという使用もありなのですね。
ファイルで保持させようとも考えていたのですが
ページごとに必要でファイル数が5000を軽く超えてしまいそうなので・・
参考になりました。どうもありがとうございました。


718 名前:714 mailto:sage [2007/08/21(火) 22:37:47 ID:???]
>>715
あ、timestamp'...' が余計なんだよ。
SELECT EXTRACT(MONTH FROM 日付) AS date FROM TableA;
これでいけるはず。

719 名前:714 mailto:sage [2007/08/21(火) 22:45:49 ID:???]
>>715
> 今、to_char(timestamp, text)も試してたんですが
> やはり” timestamp”の所にカラム名を入れるとエラーになってしまいます…。
> こちらの場合は
> ERROR: function to_char(text, "unknown") does not exist

つーかさぁ、なんでto_charの第一引数がtext型と認識されてんの?
to_char(日付,'YYYY-MM-DD')としてて、同じエラーが出るのなら
日付カラムが本当にtimestamp型になっているのかと。

720 名前:713 mailto:sage [2007/08/21(火) 23:18:41 ID:???]
>>719
申し訳ないです、日付のカラムが複数あって、誤ってtext型のカラムを対象にしてしまっていました
下記、コピペなので正確ですが、calendar_dateカラムを対象にしてしてしまっていました。


Column | Type | Modifiers
---------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('public.blog_id_seq'::text)
category_id | integer |
title | text | not null
contents | text | not null
img | text |
calendar_date | text | not null
insert_date | timestamp without time zone | default ('now'::text)::timestamp(6) with time zone
last_update | timestamp without time zone | default ('now'::text)::timestamp(6) with time zone

お詫びに実行速度を…。



721 名前:713 mailto:sage [2007/08/21(火) 23:25:54 ID:???]
EXPLAIN SELECT EXTRACT(MONTH FROM insert_date) AS date FROM blog;
QUERY PLAN
----------------------------------------------------
Seq Scan on blog (cost=0.00..1.06 rows=5 width=8)
(1 row)

EXPLAIN select to_char(insert_date,'YYYY/MM') as date from blog ;
QUERY PLAN
----------------------------------------------------
Seq Scan on blog (cost=0.00..1.06 rows=5 width=8)
(1 row)

EXPLAIN SELECT substr(insert_date,0,8) as date from blog;
QUERY PLAN
----------------------------------------------------
Seq Scan on blog (cost=0.00..1.07 rows=5 width=8)
(1 row)


という事でsubstr()を使うのが一番コスト的には悪いようでした。
ケアレスミスでごめんなさい、ありがとうございました

722 名前:NAME IS NULL mailto:sage [2007/08/22(水) 14:59:38 ID:???]
ADO経由でAccessのmdbをいじってます

顧客テーブル
 顧客ID
 顧客名
 地域ID

地域テーブル
 地域ID
 地域名

購入テーブル
 購入ID
 顧客ID
 購入額

払込テーブル
 払込ID
 顧客ID
 払込額

こんなテーブル達があります
(購入額計)-(払込額計)が0以上の顧客数を地域別に勘定したいときは、どのようにすればいいでしょう?


723 名前:NAME IS NULL mailto:sage [2007/08/22(水) 15:28:12 ID:???]
>>722
購入テーブルから 顧客ID, sum(購入額) を求める。
払込テーブルから 顧客ID, sum(払込額) を求める。
上記2つの結果と顧客テーブルを全て顧客IDでJOINし、
where句にsum(購入額)-sum(払込額)>=0をつけた上で
地域IDでグループ化してcount(*)する。
(地域名が必要なら地域テーブルもJOINする。)

ってのを、SQLで書けばいいんじゃね?

724 名前:FOX [2007/08/22(水) 15:39:39 ID:h8h7Zigl]
2つのテーブルで同じ連番のレコードを一括削除したいのですがうまくいきません。
どなたかご教授よろしくお願いします。

725 名前:NAME IS NULL mailto:sage [2007/08/22(水) 15:42:12 ID:???]
>>724
質問に対する質問しかレスされなそうな質問だな。

726 名前:FOX [2007/08/22(水) 15:46:00 ID:h8h7Zigl]
すみません。
DELETE [Aテーブル][Bテーブル]
FROM [Aテーブル] INNER JOIN
[Bテーブル] ON [Aテーブル].連番 = [Bテーブル].連番
WHERE ([Aテーブル].連番 IN (00001, 00002))
にSQL文を書くとAテーブルしか削除できませんでした。

727 名前:NAME IS NULL mailto:sage [2007/08/22(水) 15:53:59 ID:???]
>>726
x: [Aテーブル][Bテーブル]
o: [Aテーブル], [Bテーブル]

というオチでは。

728 名前:FOX [2007/08/22(水) 16:01:59 ID:h8h7Zigl]
727さんありがとうございました。
,入れてみましたが実行できませんでした。

729 名前:NAME IS NULL mailto:sage [2007/08/22(水) 16:06:32 ID:???]
どのRDBMS?バージョンも

730 名前:FOX [2007/08/22(水) 16:20:57 ID:h8h7Zigl]
RDBMSはSQL Serverになります。



731 名前:NAME IS NULL mailto:sage [2007/08/22(水) 17:18:17 ID:???]
DELETE文の一般的な構文は
 DELETE FROM テーブル名 [WHERE句]
だと思うけど。

てかそもそもDELETE文で複数テーブルを対象にできるの?
外部キーでCASCADEにでもしてなきゃ無理じゃね?
それかSQL Serverではできるとか?

知らんならレスするなって?
はい、すみません。

732 名前:NAME IS NULL mailto:sage [2007/08/22(水) 17:43:45 ID:???]
一部のDBMSはできるみたい。
SQLServerは無理なんじゃかなー、知らんけど。
ビュー作ってトリガで消すかCASCADEにするのが自然か。

733 名前:NAME IS NULL mailto:sage [2007/08/22(水) 18:03:58 ID:???]
mysqlでは可能。
SQL Serverは、Books OnlineでDELETEのBNF見た限りでは
サポートされてないようだ(2000しか見てないが)。

734 名前:NAME IS NULL [2007/08/23(木) 09:57:44 ID:1Mq4cvM8]
インデックスってWHERE句で指定する条件が単一でない場合に作成すると
高速効果が期待できますよね?
WHERE句で指定する条件が単一の場合インデックス作成する意味はないですよね?

735 名前:734 [2007/08/23(木) 10:45:37 ID:1Mq4cvM8]
あぁなんか完全に勘違いしてますね。。
レコードが多く、更新度が低く、抽出結果・重複が少ない
場合に有効なのですね。
ユニークに設定してあると自動でインデックスされているんですよね?

736 名前:NAME IS NULL mailto:sage [2007/08/23(木) 10:55:18 ID:???]
>>735
ユニーク制約だけでは、本来はインデックスが作成されることは保証されない。
だが、内部的にユニークインデックスを作成してるDBMSはあると思う。
心配なら、使ってるDBMSのマニュアル読んでみれば書いてあるはず。

737 名前:734 [2007/08/23(木) 11:36:25 ID:1Mq4cvM8]
>>736ありがとうございました。調べてみます!

738 名前:NAME IS NULL mailto:sage [2007/08/23(木) 12:17:30 ID:???]
発言テーブル.id = コメントテーブル.comment_idという関連性があります。
(掲示板のスレとレスみたいな関係だと思って頂ければ…。)

発言テーブル AA
id, user_id, body, datetime
1 a 'aaa' 2007-08-10 10:00:00
2 a 'bbb' 2007-08-16 10:00:00
3 a 'ccc' 2007-08-18 10:00:00
4 b 'ddd' 2007-08-21 10:00:00
5 c 'eee' 2007-08-23 10:00:00


コメントテーブル BB
id, comment_id, user_id, body, datetime
1 2 b 'aaa' 2007-08-19 10:00:00
2 2 c 'bbb' 2007-08-22 10:00:00
3 4 a 'ccc' 2007-08-23 10:00:00

して、質問なのですが。

AAテーブルのdatetime最新順にソートするのですが
BBにコメントが存在していた場合は、そのdatetimeも含めてソートしたいのです。

AA.id, AA,user_id, AA.body, AA.datetime, BB.datetime
5 c 'eee' 2007-08-23 10:00:00
4 b 'ddd' 2007-08-21 10:00:00 2007-08-23 10:00:00
2 a 'bbb' 2007-08-16 10:00:00 2007-08-22 10:00:00
3 a 'ccc' 2007-08-18 10:00:00
1 a 'aaa' 2007-08-10 10:00:00

上記の様な形をイメージして居ります。
AA.id = BB.comment_idで外部結合し
GROUP BY AA.idで纏めているのですが…

どの様な形でorder byすれば適当でしょうか。
環境はMYSQLです。


739 名前:NAME IS NULL mailto:sage [2007/08/23(木) 12:33:20 ID:???]
ORDER BY AA.datetime, BB.datetime
でいいのかな?

740 名前:NAME IS NULL mailto:sage [2007/08/23(木) 12:59:43 ID:???]
>>739
返信有難う御座います。

既にそれは試してみたのですが、
AA.datetimeの方でのソートが優先され、BB.datetimeの方は見られていませんでした;
また、表示順が
1 a 'aaa' 2007-08-10 10:00:00
2 a 'bbb' 2007-08-16 10:00:00 2007-08-22 10:00:00
3 a 'ccc' 2007-08-18 10:00:00
4 b 'ddd' 2007-08-21 10:00:00 2007-08-23 10:00:00
5 c 'eee' 2007-08-23 10:00:00
の様に逆になってしまいます。
その為、DESCを付けたりもしてみたのですが…どうも思い通りに行かなくてorz



741 名前:NAME IS NULL mailto:sage [2007/08/23(木) 13:30:37 ID:???]
BB.datetimeがAA.datetimeより古い場合は存在しない。
BB.datetimeがあればそちらを優先、でなければAA.datetimeでってことだろ。
MySQLで動くかどうか知らんが、

ORDER BY CASE WHEN BB.datetime IS NOT NULL THEN BB.datetime ELSE AA.datetime END DESC

でいけるんじゃね?


742 名前:NAME IS NULL mailto:sage [2007/08/23(木) 13:32:49 ID:???]
ちょっと誤解を生みそうだ。突っ込まれる前に訂正。
×BB.datetimeがAA.datetimeより古い場合は存在しない。
○「BB.datetimeがAA.datetimeより古い」という状況は存在しない。

743 名前:NAME IS NULL mailto:sage [2007/08/23(木) 13:47:54 ID:???]
>>742
返信有難う御座いました!
そして、その記述で望む動作を得ることが出来ました。
成程、条件で見る値を切り替えるのですね…
本当に有難う御座いました。

744 名前:NAME IS NULL mailto:sage [2007/08/23(木) 14:26:34 ID:???]
>>738 の例が意味不明だと思ったが、そういう意味だったのか・・・

745 名前:NAME IS NULL mailto:sage [2007/08/26(日) 12:40:30 ID:???]
日のアクセス2万ほどなのですが、現在ファイルでアクセスカウントしています。
現在TOPページのみでカウントしています。
全てのページにおいてカウントさせたくてpostgreSQLで管理しようと思うのですけど
やめておいた方がいいように言われました。(人伝いに)
どういった理由が考えられますか?
DBを使ってのアクセスカウントってあまり向いてないのでしょうか?
ページ数は1000ページほどです。

746 名前:NAME IS NULL mailto:sage [2007/08/26(日) 12:47:54 ID:???]
WebPageの話か?
Web鯖がapacheだとしたら、apacheのログを解析するだけで済むと思うのに、
なぜにRDBで管理なんてヘンテコな事考えるんだ?

しかもたかが1000明細(ページ)の為に。

そんなのExcelやAccessで十分過ぎるだろ。

747 名前:745 mailto:sage [2007/08/26(日) 12:55:20 ID:???]
ありがとうございます、
そうです、Webです。
すいません抜けてました。
ページごとにアクセス表示させたいのです。

748 名前:NAME IS NULL mailto:sage [2007/08/26(日) 13:52:37 ID:???]
>>747
> アクセス表示
って何を指してるんやら?
とりあえず、ページ毎にアクセスログをDBに記録して、

1. ページ毎にアクセスカウンタを埋め込む?(普通の閲覧者がカウンタを見れる)。
2. アクセス解析用(管理人しか見ない)

のどっちか? まぁ、2の場合だったら悩むほどのもんでもないだろうけど、
1ならトリガで...って書きかけたけど、1は単なる管理人の自慰行為だよね。

まぁ、DBにアクセスログを入れておけば、SQLだけでいろんな解析ができるだろうから、
俺的にはありだが。

749 名前:748 mailto:sage [2007/08/26(日) 13:56:31 ID:???]
にょ、途中で送ってしまった。

俺的にはありだが、httpdのアクセスログから1日分をバッチ処理して
DBに落としてからで十分だよね。

750 名前:745 mailto:sage [2007/08/26(日) 15:54:15 ID:???]
ありがとうございます。
1です。ページにアクセス数表示させるためです。
自慰行為でもなくて、そのページのアクセス数をリアルタイムで
知りたい人も尋ねてくるページなのです。
なのでそのページでその都度アクセス数を表示させておく必要がありまして。。

ファイルでカウントさせておくほうが良いでしょうか?
DBでアクセスカウントさせるとなるとリソース食いますか?



751 名前:NAME IS NULL mailto:sage [2007/08/26(日) 16:52:05 ID:???]
どうしてもその機能が必要なら喪前の好きな方法でいいのでは?
perlでもJavaでもいいからサ。

ただ「そのページのアクセス数をリアルタイムで
知りたい人も尋ねてくるページなのです。」
なんてのは意味ない行為って教えてやればいいと思うが。

リアルタイムのアクセスレポートの機能の為に
高性能の鯖を買ってくれるお客ならやればいいと思うんだが、
リソースとか気にするならヤめとけ、としか言いようが無い。

752 名前:748 mailto:sage [2007/08/26(日) 17:48:54 ID:???]
カウンタだけならログをとる必要もないし、
SELECT FOR UPDATE でロックして、
後にインクリメントさせるだけでいいのかな?

いいんじゃね、やってみれば。
カウンタのためだけにDB使うってなら、躊躇してしまうところだが、
永続化やpgpoolなどを使えば、それほど気になるものでもないかも。
俺的には「そんなこと止めれ」とは言わない。

それはそうと、ちょっとスレ違いなネタなんだよな。

753 名前:NAME IS NULL [2007/08/27(月) 20:39:46 ID:xlZ83oxI]
PL/SQLの質問です

ファンクションで
変数に2000文字以上の文字列を入れる処理があるのですが
VARCHAR2型だと大きさが足りなかったので
CLOBに変えたのですが
エラーが発生します

変数の宣言のところで

hoge clob;

にしました

CLOBは制限が多いとリファレンスに書いてましたが
適例が無く、読み解けませんでした

何か他の設定?が必要なのでしょうか?

754 名前:NAME IS NULL mailto:sage [2007/08/28(火) 00:31:23 ID:???]
CLOBはあんまり使わない方がいいよ

使わない方向で改修無理なの?

755 名前:NAME IS NULL [2007/08/28(火) 14:53:30 ID:naFGM+aI]
質問です。

主キーやインデックス等の質問なんですが
---------------------
table AAA
col1
col2
col3
index1:col1, col2
---------------------

---------------------
table AAA
col1
col2
col3
index1:col1
index2:col2
---------------------
とでは、

SELECTなどで、col1とcol2を条件にいれた場合、
同じようなスピードになるのでしょうか?(何十万件単位)


もしかしたらとんちんかんな質問かもしれませんが
宜しくお願いします。



756 名前:NAME IS NULL mailto:sage [2007/08/28(火) 15:01:52 ID:???]
1)検索条件がcol1, col2 両方の場合、上はindex1が使用され、下はindex1かindex2のどちらかが使用される。
2)検索条件がcol1だけの場合、上はindex1が使用され、下はindex1が使用される。
3)検索条件がcol2だけの場合、下はindex2が使用されるが、上は使用されない。
1のケースでは上の方が検索スピードが速くなる可能性が高い。
(col1だけで十分件数を絞りlこめている場合はその限りではない。)



757 名前:NAME IS NULL mailto:sage [2007/08/28(火) 15:28:49 ID:???]
>>755
基本的には >>756 の言うとおりだが、DBMSによっては、col2だけの条件でも
DBMSによっては(col1, col2)のインデックスが使われる場合もある。
col1のカーディナリティが低い場合は、効果が期待できることがあるため
(col1が1種類の値しか取らない場合を考えるとわかりやすい)。
とはいえ、(col2)のインデックスより勝るということはないが。

758 名前:NAME IS NULL mailto:sage [2007/08/28(火) 17:13:22 ID:???]
>>757
OracleのCompress索引でしたっけ?
あれは第一キーのカーディナルがほんとに低いときしか効果が無いからなぁ。

759 名前:757 mailto:sage [2007/08/28(火) 17:19:25 ID:???]
>>758
そうそう、Oracleだったっけ。どれで実装されていたか確信がなかった。
補足してくれてありがとう。

760 名前:755 [2007/08/28(火) 18:01:21 ID:naFGM+aI]
756-759
皆様丁寧な説明ありがとうございます。
すごい勉強になりました!!



761 名前:NAME IS NULL [2007/08/28(火) 23:41:36 ID:mh0ASi6S]
SEQUENCEオブジェクトをサポートしていないDBで
次のことをしたいのですが・・・。

■テーブルAはカラムa1,a2,a3・・・で構成される
 主キーは(a1,a2)
 行の追加はあるが更新と削除はない

■テーブルBはカラムb1,b2,b3・・・で構成される
 主キー設定は(b2,b3)
 行の追加はあるが更新と削除はない

上記にて、
・b1は数値である。
・b1はユニークではないが、同一の値の行は、一回のトランザクションで作成される。
・(b2,b3)には(a1,a2)の値が入る。

目的は、Aの行のいくつかをまとめてグループ化したいのと、
そのグループにユニークな番号をつけたいのです。
またAの行は複数のグループに存在してはいけないのですが、
これはBの主キー制約で回避できます。

このような場合、
トランザクション内で、テーブルBをロックして、
MAX(b1)+1を新しいグループの番号にするのがベストでしょうか。
テーブルBの行追加の頻度は高くありません。(既存行の更新はなし。)

テーブルロック以外にいい方法がありましたら、ご教授ください。
よろしくお願いします。




762 名前:NAME IS NULL mailto:sage [2007/08/29(水) 02:22:38 ID:???]
>>761
そもそもトランザクションはロックのおかげで一貫性を保っているようなもんだから、
ロックせずにできないかと言われてもな。
質問内容からは、トランザクションで何を実現したいのかも見えてこないし。

- エラー時にrollbackしたいのが目的?
- Bへの更新者が複数いるからその競合の回避が目的?
- commitするまで更新中のBのデータが参照されないようにするのが目的?

763 名前:NAME IS NULL mailto:sage [2007/08/29(水) 09:33:37 ID:???]
>>761
テーブルA,Bは同一キーで1:1の関連だからテーブルを分ける意味があまりない。
a1, a2, b1, a,3 ... でいいのでは?(もとろん分けてもいいが)

IDENTITY制約列(オートナンバー)がサポートされているなら
b1(PK)IDENTITYのテーブルを作りそこで生成される番号を使用する。
サポートされてないなら採番用のテーブルまたはレコードを準備する。
これについてはいくつか方法がある。

764 名前:NAME IS NULL [2007/08/29(水) 15:33:10 ID:2iUsCkc+]
パソコンショップ完全リンク
search.yahoo.co.jp/search?p=%E5%A4%A7%E6%89%8B+%E3%81%9D%E3%81%AE%E4%BB%96+%E6%9D%B1%E8%8A%9D%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88+%E3%82%A2%E3%83%BC%E3%82%AF%E3%80%80nec&ei=UTF-8&fr=top_v2&x=wrt

765 名前:NAME IS NULL [2007/08/29(水) 22:50:57 ID:skWgmgeO]
>761
not exists (select * from tbl b where max(a.b1)+1=b.b1)
っていう条件をくっつけときゃロックしなくても大丈夫。
ただし、insertもできない場合がある。
そんときゃ、出来るまでループという手もあるけど。

766 名前:NAME IS NULL [2007/08/30(木) 00:55:07 ID:JDv5Lyba]
みなさんレスありがとうございます。

>- エラー時にrollbackしたいのが目的?
>- Bへの更新者が複数いるからその競合の回避が目的?
はいそうです。グループ化の作業をWebページから複数の人が同時に行う可能性(低いけど)を
完全に削除しなければならないのです。

>- commitするまで更新中のBのデータが参照されないようにするのが目的?
ロックの目的はそのとおりです。
IsolationLevelをSerializableにするだけでは、ほぼ同時にグループ化をした場合、
同一グループ番号が割り振られる可能性を排除できないので。

>テーブルA,Bは同一キーで1:1の関連だからテーブルを分ける意味があまりない。
説明不足ですみません。Aは既存のソフトウェアの管理下のテーブルで、
今回の目的のためにBを新規に作成します。またBにはAにない情報も記録して
半永久的にデータを保持します。

>IDENTITY制約列(オートナンバー)がサポートされているなら
>b1(PK)IDENTITYのテーブルを作りそこで生成される番号を使用する。
IDENTITYはサポートされています。
そのIDENTITYのテーブルを占有ロックすれば(トランザクションの間、結果的に占有ロックかかりますね)、
ユニークな番号を取得できますが、
それなら1カラム1行のテーブルで、占有ロックして数字を増やしていくのでも同じですよね。
テーブルを分けたほうがパフォーマンス的にもいいと思いますので、それでやってみようと思います。


>not exists (select * from tbl b where max(a.b1)+1=b.b1)
>っていう条件をくっつけときゃロックしなくても大丈夫。
ごめんなさい。よくわかりません。
テーブルaにはカラムb1はないのですが・・・。

767 名前:NAME IS NULL mailto:sage [2007/08/30(木) 06:40:39 ID:???]
>>766
質問の要領が悪いな。思い込みが激しい上に複数のことをごちゃ混ぜに考えてるように思える。
要はシーケンスのように、特定のレコードに紐つかないID値が欲しいわけだ。
その方法はひとつではないのでいくつか分類してあげてみる。

以下、グループ化してbレコードにレコードを追加する処理を主処理。
新規IDを発行する発番処理と呼ぶことにする。

発番処理を主処理のトランザクションに含む。
主処理が済むまで次の発番および次の主処理はブロックしておくか
IDが競合するようなら失敗または(自動または手動で)再処理させる必要がある。
ブロックさせるのがお前さんが考えてる方法。
>>765のやってるのは再実行の例で
ブロックの必要はないが他の主処理と競合したら再実行になる。

発番処理を主処理のトランザクションに含まない。
シーケンスを使う。
または、主処理のトランザクションの前に発番処理済ませておく。
または、主処理とは独立した接続で発番処理を行う。
同時実行性は高いが主処理がロールバックした場合に空き番号が発生する可能性がある。

IDENTITY制約をもつ発番テーブルを使う。
発番処理を主処理のトランザクションに含むことになるが
それぞれ別のレコードになるため競合はなくブロックする必要はない。
発行した番号はレコードとして残る。ただしID成後すぐにレコードを削除しても良い。
主処理がロールバックした場合はそのIDのレコードは残らない。
同時実行性は高いが主処理がロールバックした場合に空き番号が発生する可能性がある。


768 名前:NAME IS NULL mailto:sage [2007/08/30(木) 07:16:11 ID:???]
>>765の意味は俺も分からん。
not exists (select * from テーブルB b where b.b1 = 入れようとしている番号)
なら分かるけど。

769 名前:NAME IS NULL mailto:sage [2007/08/30(木) 15:28:54 ID:???]
テーブル1と2があって
1はA、B、C、D、Eとカラムがあって
2はF,Gとカラムがあるんだけど
1は単独で利用する場合があって
2と1を結合して利用する場合もある。
それで
2と1結合して利用する場合に2パターンあって
完全に2と1のデータ利用する場合と
2と1のEカラムだけ利用する場合があるのね。
そういう場合データ重複するけどテーブル2にもEカラムのデータおいたほうがいいのかな?

770 名前:NAME IS NULL mailto:sage [2007/08/30(木) 19:48:44 ID:???]
>>769
参照時のパフォーマンス重視ならいいんじゃないかな。
更新と整合性管理のコストがかかるけど。
「インデックス付きビュー」、「マテリアライズド・ビュー」も参照されたし。



771 名前:NAME IS NULL mailto:sage [2007/08/31(金) 07:03:18 ID:???]
>768
765だけど、そういうこと

772 名前:NAME IS NULL [2007/08/31(金) 11:24:39 ID:YdfX5avM]
ある抽出条件に該当する、テーブルAのflgを1にUPDATEし、
テーブルAと1:多の関係にあるテーブルB、
テーブルBと1:多の関係にあるテーブルCの、
テーブルAのキーであるIDに紐付いたレコードに対しても
flgを1にUPDATEしたいのですがどのようにすればよいでしょうか?
そもそもうまく説明ができないのですが。。

773 名前:NAME IS NULL mailto:sage [2007/08/31(金) 12:22:58 ID:???]
>>772
flgというのはA、B、Cそれぞれにあるの?

774 名前:NAME IS NULL [2007/08/31(金) 12:28:36 ID:YdfX5avM]
>>773
あります。

775 名前:769 [2007/08/31(金) 13:21:37 ID:49luVNYp]
>>770
参考になりました、ありがとうございました。

776 名前:NAME IS NULL mailto:sage [2007/08/31(金) 13:41:28 ID:???]
>>772
Aをupdateした後に、
update B set flg = 1 where id in (select A.key_b from A where A.flg = 1);
update C set flg = 1 where id in (select B.key_c from B where B.flg = 1);
こんな感じでできない?
レコード数多くて重いようだったら、もうちょい工夫する必要はあるが。

777 名前:NAME IS NULL [2007/08/31(金) 13:48:18 ID:YdfX5avM]
>>776
inですか。なるほど。
できそうな気がします。
レコード数はそれほどでもないので大丈夫です。

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

778 名前:NAME IS NULL [2007/08/31(金) 14:00:12 ID:c64PJJrl]
質問です。

VBAでDBを組んでいるのですが。
列名が毎回変わるようにPGを組みたいのです。
どのようにテーブルをつくればいいですか?

2つのワークテーブルを使用したいとおもっています。
1つはフォームオープンしたときに、サブフォームにもたせる空の表です。
(見た目、なかみのないからのテーブル)
2つめは、検索をかけた時や一覧表示を押したときにサブフォームに
一覧や、検索結果を表示させるテーブルです。

2つめの表が問題になってます。
CD検索をかけた際、「日付のみ」がかわるようにしたいのです。

表1にある日付のデータを
表2の列名にしたいのです。

表1:
物件CD|枝番|符号|数量|日付|   ←列名
−−−−−−−−−−−−−−
0001|01|01|01|2007/8/31   ←データ
0002|02|01|02|2007/9/3
0003|01|01|01|2007/8/13
0004|01|01|01|2007/9/15




『検索 0001』
表2:
物件CD|枝番|符号|数量|***|***|2007/9/1|・・・(10行)|
0001|01|01|01|   |   |    | ←データ
0001|02|01|02|   |   |    | ←データ
0001|03|01|00|   |   |    | ←データ
0001|03|02|10|   |   |    | ←データ




*に表1の日付を10行もたせたいのです。

職場の方に聞いたら
CREATE TABLE
で出来そうだけどと言われました。

PGになってまだ2ヶ月で初心者です。
どなた様かお力を分けてください。

779 名前:NAME IS NULL mailto:sage [2007/08/31(金) 18:16:39 ID:???]
>>778
VBAなら「ADOX テーブル作成」とかでググった方が早い。
SQLでどうこうするよりADOXでの操作は面倒だけどな。

でも、テーブル作成して実データを毎回突っ込むよりは、
多少複雑でもADOXでVIEWを作るだけに留めた方が良くないか?


780 名前:NAME IS NULL mailto:sage [2007/08/31(金) 22:57:58 ID:???]
>>778
VBAといってるけど、MS-ACCESS?その辺の情報を出せば何か方法が出るかもしれないよ。



781 名前:NAME IS NULL mailto:sage [2007/09/02(日) 01:49:53 ID:???]
勝敗の表示
自分 相手  勝敗
a     b    win
a     b    win
a     b    lose
a     c    win
a     c    lose
a     d    lose  
h     x    win
h     x    win
h     y    lose
h     z    lose  
みたいなテーブルがあって

where 自分 = aのとき
相手 合計 勝ち 負け 勝率
b     3    2    1   0.66
c     2    1    1   0.50
d     1    0    1   0.00

となるようなDB依存しないSQLってどうかけばいいのでしょうか?
ありがちなので、なめてかかってたらさっぱりわかりませんでした。
count, group byとサブクエリあたり使うと思うけど・・・

782 名前:NAME IS NULL mailto:sage [2007/09/02(日) 02:20:04 ID:???]
>>781
JOINで結合してもいいかなと思ったが、WHERE 自分='a' が複数出てきそうなので、
以下なら、GROUP BY の前にひとつ入れるだけで済むからこっちの方がいいかなと。
SELECT 自分, 相手, count(*) ,
(SELECT SUM(CASE result WHEN 'win' THEN 1 ELSE 0 END ) FROM Table WHERE T1.自分=自分 AND T1.相手=相手) AS 勝ち,
(SELECT SUM(CASE result WHEN 'lose' THEN 1 ELSE 0 END ) FROM Table WHERE T1.自分=自分 AND T1.相手=相手) AS 負け
FROM Table AS T1 GROUP BY 自分,相手;
もっと楽にできそうな気もするが...

783 名前:782 mailto:sage [2007/09/02(日) 02:25:10 ID:???]
あ、resultは勝敗のことね。count(*)も AS 合計を付け忘れちゃった。
勝率は出してないけど、勝ち/合計で出せる。
SQLでするなら
SELECT * ,勝ち/合計 FROM (>>782のクエリ) AS T2
とさらに包んだ方がいいかな。


784 名前:782 mailto:sage [2007/09/02(日) 02:28:40 ID:???]
気になったので...連想スマソ。
"引き分け"を考えてなかったが、
あるんだったら勝率は
勝ち/(勝ち+負け) ですね。

785 名前:NAME IS NULL mailto:sage [2007/09/02(日) 03:45:03 ID:???]
>>782
↓な感じに若干修正したら期待通りになりました。
SELECT 自分, 相手, COUNT(*) AS 合計,
       SUM(CASE 勝敗 WHEN 'win' THEN 1 ELSE 0 END) AS 勝ち,
       SUM(CASE 勝敗 WHEN 'lose' THEN 1 ELSE 0 END) AS 負け
  FROM 勝敗表
 GROUP BY 自分, 相手

Javaで作られたDerbyっていうDBMSなのでもしかしたら他のDBと
挙動が違うかもしれません。
ちなみに Derby だとCASE WHEN 勝敗 = 'win' THEN 1 ELSE 0 END と記述します。
非常に参考になりました。CASEって初めて使いました。
ありがとうございます。

786 名前:782 mailto:sage [2007/09/02(日) 04:21:12 ID:???]
そうか、勝敗はCASE内に出てきてもSUMで集約されるから、
わざわざサブクエリにする必要なかったか。こりゃ失礼。

787 名前:NAME IS NULL [2007/09/03(月) 06:25:45 ID:EUzll27l]
初の質問です。
今php+postgresql+fedoracore4でシステムを作っているんですが、
どうも原因がpostgresqlにあるとわかってきました。
自分はDBを作るときまず文字コードをeucに変えて入力するんですが
invalid byte sequence for encoding "EUC_JP": 0xe988
というエラーがでます。
PHPのソースはwww.mywave.co.jp/~ike50/chapter5.zip
にあります。
ぜひ教えてください。


788 名前:NAME IS NULL mailto:sage [2007/09/03(月) 06:48:13 ID:???]
>>787
板違い。
PHP + PostgreSQLスレに池。

PHP + PostgreSQL
pc11.2ch.net/test/read.cgi/php/983128806/


789 名前:NAME IS NULL [2007/09/03(月) 07:09:51 ID:EUzll27l]
今回初めて質問します。
fedoracore4でpostgresql+phpのプログラムを動かそう
としているんですが、データベースがうまく入ってくれません。
エラーです。
また本見てやっているんですが、僕の場合euc-jpではなく
UTF-8で表示されていて、それをeucにテーブルを変換して
やろうと思っているんですが入力の際にデータベースの言語がeuc-jpが最初から書いてあって
俺のはUTF8なんだが、
それを無理やり変換してEUCで入力しようとすると、
invalid byte sequence for encoding "EUC_JP"
のエラーがでます。
どうしたいいでしょうか?
よろしくお願いします。

790 名前:NAME IS NULL mailto:sage [2007/09/03(月) 07:27:00 ID:???]
>>789
スレ違い。
PostgreSQLのスレに池。

【Windows】 PostgreSQL8 Part.1 【対応】
pc11.2ch.net/test/read.cgi/db/1102247223/l50




791 名前:778 [2007/09/03(月) 09:39:53 ID:DLb/zQ6a]
>>779さん
>>780さん

ありがとうございます。
さっそく調べてみます。
vbaは
Accessをつかってます。

792 名前:NAME IS NULL mailto:sage [2007/09/03(月) 14:34:00 ID:???]
わざわざ別にテーブル用意して業種コード 例) 製造 seizou
それでメインテーブルに登録された業種コードseizouから
参照して製造って文字をひらいだすのは、なにかメリットがあるのでしょうか?
はじめからメインテーブルに製造って文字いれておけばいいんじゃない?
と思ったのですが、メリットがあるのなら教えてください。


793 名前:NAME IS NULL mailto:sage [2007/09/03(月) 14:52:54 ID:???]
>>792
製造、製造業、製作....

頼むから正規化しろよ 第二正規形
pc11.2ch.net/test/read.cgi/db/1116097001/

794 名前:NAME IS NULL mailto:sage [2007/09/03(月) 14:58:35 ID:???]
>>792
出力されるデータがログデータなら、リンクさせなくても良いんじゃない。

ただ、後からデータの修正が必要だったり、他のテーブルとの連携が
必要だったりする場合は、コードじゃないと色々と支障が出るだろう。


795 名前:NAME IS NULL mailto:sage [2007/09/04(火) 17:44:30 ID:???]
SQL文の違いで質問です。

TO_NUMBER SQL文で検索時に関数を使ってオラクルデータを引っ張っています。

以下がその例です。
COL1はVarchar2(12)になっています。

SELECT * FROM A
WHERE TO_NUMBER(COL1) = 1

これと同じようなことをACCESSでしようと思うと関数は何を使えばいいのでしょうか?
暗黙型変換での比較をできるだけ行いたくない為お伺いしたいのですが。
ご教授お願いいたします。

796 名前:NAME IS NULL mailto:sage [2007/09/04(火) 17:54:21 ID:???]
>>795
整数期待するならCLng(COL1)で良いんじゃないか?
何が入ってるか分からないならValの方が良いかもしれん。


797 名前:NAME IS NULL mailto:sage [2007/09/04(火) 18:49:37 ID:???]
>>796

整数期待は問題ないのですが桁数の問題のほうがありおそらく9が12ケタきたらオーバーフローするんじゃないかと
なので聞いてみた次第です
Valで取りあえずやろうと思うんですが、本当は適切に12ケタの整数を処理できる型変換がおこなえたらいいなぁとか思っています。

798 名前:NAME IS NULL mailto:sage [2007/09/05(水) 22:11:51 ID:???]
派生テーブルって毎回書かなければならないのでしょうか?
つまり、
SELECT * FROM (SELECT ほげほげ) AS T1, (SELECT count(*) FROM (SELECT ほげほげ) AS T2) AS T3
のように2回同じほげほげを書かなくてはならないのでしょうか?


799 名前:NAME IS NULL mailto:sage [2007/09/05(水) 22:16:28 ID:???]
>>797
そこまで桁が行くのなら通貨型にしたほうが良いんでないか?
Ccur関数があるし。

800 名前:NAME IS NULL mailto:sage [2007/09/05(水) 22:36:10 ID:???]
>>798
共通表式とかインラインビューとかでぐぐれ



801 名前:800 mailto:sage [2007/09/05(水) 22:41:02 ID:???]
違った。インラインビューはぐぐらなくていい。

×共通表式とかインラインビューとかでぐぐれ
○共通表式とかWITH句とかでぐぐれ

802 名前:NAME IS NULL mailto:sage [2007/09/06(木) 09:07:09 ID:???]
>800-801
Thx. 残念ながら対応してなかったので地道に書くことにするよ。


803 名前:NAME IS NULL mailto:sage [2007/09/07(金) 21:24:58 ID:???]
SQL2005だけど
with便利〜と思って使ってたんだけど
妙に遅いクエリがあって
試しにインラインビューで作ってみっかとやってみたら
パフォーマンスが10倍程度改善された事があった


804 名前:NAME IS NULL mailto:sage [2007/09/09(日) 13:01:39 ID:???]
うちは重たいマスタ参照する副照会2回出てくるのをwith句に変更したらちゃんとメモリ上の一時テーブル見てくれて嬉しかったけど


805 名前:NAME IS NULL mailto:sage [2007/09/09(日) 21:24:06 ID:???]
共通表式を使うと必ず一時表を作るんじゃない?
それが良い方向に働く場合もあるし悪い方向に働く場合もある、とか。知らんけど。

806 名前:NAME IS NULL [2007/09/09(日) 22:22:19 ID:8M0+Vljb]
初心者ながら恐れ入ります。
実際、使う機会てそうないと思うのですが、如何か。
アクセスとかの利用者のみか?

807 名前:NAME IS NULL [2007/09/11(火) 11:29:21 ID:IJsUEx2O]
注文テーブル
名前 注文番号
山本 1
高橋 2
佐藤 1
鈴木 1
山口 2

商品テーブル
商品記号 商品名
A    りんご
B    みかん

という2つのテーブルがあります。

山本 りんご
高橋 みかん
佐藤 りんご
鈴木 りんご
山口 みかん

という一覧を取得したいのですが、何かよい方法はないでしょうか。
(SQL1つで取得したい)

注文番号、商品番号などはSQL内で固定で記述してしまってもよいです。

SELECT A.名前,B.商品名 FROM 注文テーブル A,商品テーブル B
WHERE B.商品記号 =(A.注文テーブルが1のときA、2のときB)
のようなSQLを書きたいです。

808 名前:NAME IS NULL [2007/09/11(火) 11:33:37 ID:IJsUEx2O]
ちなみに、それぞれのテーブル間で、キーを持つことはできない状況です。
(各テーブルは別会社管理で、「キー持たせよう」という案は片方の会社で
「やだ」と言われた為。)

ビューは作ってもよいと言われています。

809 名前:NAME IS NULL mailto:sage [2007/09/11(火) 11:46:39 ID:???]
1とA、2とBを関連付けるのは何?

810 名前:NAME IS NULL mailto:sage [2007/09/11(火) 11:48:59 ID:???]
SELECT A.名前,B.商品名
 FROM 注文テーブル A,商品テーブル B
WHERE A.注文番号 =(CASE WHEN B.商品記号 = A THEN 1
                        ELSE B.商品番号 = B THEN 2
                   END)



811 名前:NAME IS NULL mailto:sage [2007/09/11(火) 11:57:00 ID:???]
2つでいいのか

812 名前:NAME IS NULL [2007/09/11(火) 11:57:29 ID:IJsUEx2O]
>>809,>>810
ありがとうございます。

>>809
関連付けはSQL文でベタ書き(DBでは直接関連付けできない)
のつもりです。

>>810
ありがとうございます。
CASEとかWHENとかはOracleでも使えますか?
とりあえず調べてみます。

813 名前:NAME IS NULL mailto:sage [2007/09/11(火) 12:08:36 ID:???]
>>812
そうじゃなくて、AとB以外無いのか、あるならその法則、を聞いたんだけどな
CASEは標準だよ

814 名前:NAME IS NULL mailto:sage [2007/09/11(火) 12:41:13 ID:???]
古いオラクルでcase使えない場合はdecode

815 名前:NAME IS NULL mailto:sage [2007/09/11(火) 13:00:56 ID:???]
Oracle 使ったことないんだけど、

A.注文番号 + 64 = ASC(B.商品番号)

でいいんかな。CASE 使わないだけ、こっちの方が速そう。

816 名前:NAME IS NULL [2007/09/11(火) 15:01:07 ID:+7Z4LZr/]
X列      Y列
____________

か      !
村      の
の      バ
西      村
ー      か
バ      ー

X列に対し、Y列は次にくる文字を表しています。
PLSQLでない普通のSQLを用い、これを順番どおりに
並べ替えて出力する方法を教えてください。

817 名前:NAME IS NULL mailto:sage [2007/09/11(火) 15:58:10 ID:???]
>>816
SQL99のWITH RECURSIVEを使う。

818 名前:NAME IS NULL mailto:sage [2007/09/13(木) 12:04:58 ID:???]
MySQLを始めたばかりなのですが
TABLEを削除する際に
DELETEしないでDROPすると変なものが残ったりするのでしょうか?

819 名前:NAME IS NULL mailto:sage [2007/09/13(木) 12:27:45 ID:???]
>>818
変なものって何だよwww

820 名前:NAME IS NULL mailto:sage [2007/09/13(木) 12:28:56 ID:???]
>>816
OracleならJavaストアドで処理しろwww




821 名前:NAME IS NULL mailto:sage [2007/09/14(金) 02:09:18 ID:???]
exists句が未だに理解できん・・・
使えるには使えるんだが理屈がな・・・

なんでこれでちゃんと動くんだ?って思う。

822 名前:NAME IS NULL mailto:sage [2007/09/14(金) 06:14:47 ID:???]
>>821
exists や in は句じゃなくて述語。

823 名前:NAME IS NULL mailto:sage [2007/09/14(金) 06:29:30 ID:???]
>>821
for文のネストだと思えばいいんじゃね?

select * from Table A
where exists (select * from Table B where AとBの比較)

だったら

for (rowA in Table) {
  for (rowB in Table) {
    if (rowAとrowBの比較) {
      print rowA
      break
    }
  }
}

とか。
実際にループして動いてるとは限らないけど
意味的にはそういうことかと。

824 名前:NAME IS NULL mailto:sage [2007/09/14(金) 18:22:19 ID:???]
なんで、inで指定した順番に取り出すって方法が無いんだろう?

825 名前:NAME IS NULL mailto:sage [2007/09/14(金) 18:37:17 ID:???]
日付を検索条件にしたselect文について質問です。(SQL Server 2000)

特定の日時のデータを検索するときに、
ヘルプにあるとおり下記のようなSQL文を使っています。
select * from abc where date like { ts '2007-09-10 06:10:00' }

日時はdate列に入っていて1分間毎に1件のデータがあります。
2007年9月中(日付は指定しない)の06:10の全てのデータを抜き出すには
どのようなSQLを書けばいいのでしょうか?

文字列を抽出するときのようにワイルドカードも使えないようで
どうやっていいのかわからない状況です。
よろしくお願いいたします

826 名前:NAME IS NULL mailto:sage [2007/09/14(金) 19:19:56 ID:???]
>>825
YEAR(date) = 2007
and MONTH(date) = 9
and SUBSTRING(CONVERT(varchar, date, 120), 12, 8) = '06:10:00'

試してないので、微妙にずれてるかも。

827 名前:NAME IS NULL mailto:sage [2007/09/15(土) 06:18:32 ID:???]
>>824
抽出結果をソートすれば事足りるからじゃね?


828 名前:NAME IS NULL mailto:sage [2007/09/15(土) 10:22:23 ID:???]
>>826
ありがとうございます。
やはり1行のselect文ではできないんですね
convertなどを調べてみます。

829 名前:NAME IS NULL mailto:sage [2007/09/15(土) 17:34:06 ID:???]
1行だろこれw

830 名前:NAME IS NULL mailto:sage [2007/09/16(日) 02:28:47 ID:???]
ある条件で絞り込んでorder by idで下のようになっている場合
id, flag
========
 1,  0
 2,  0
10,  1
14,  1
18,  1
20,  0
flag(0か1のみ)が連続している数(連続記録)をカウントしたい
0が2連続のグループ、1が3連続のグループ、0が1(連続)のグループに
して、0が最大(2連続)と1が最大(3連続)を求めてたいのですが、どうやって
グルーピングして、結果を出力すればよいでしょうか?(自己参照か相関サブクエリで)
DBから引っ張ってきてプログラムで求めれば簡単なのですが・・・



831 名前:NAME IS NULL mailto:sage [2007/09/16(日) 04:41:05 ID:???]
>>830
SELECT flag ,
max((SELECT count(*) FROM Table WHERE id BETWEEN T1.id AND (SELECT COALESCE(min(id),9999) FROM Table WHERE id>T1.id AND flag<>T1.flag) AND flag=T1.flag)) AS cnt FROM Table AS T1
GROUP BY flag;

COALESCE内の9999 は仮のid最大値
定数を用いたくないのなら定数(9999)の変わりに
(SELECT max(id)+1 FROM Table)
とすればいい。-- が、相関サブクエリ内のサブクエリにさらにサブクエリが...


832 名前:831 mailto:sage [2007/09/16(日) 05:01:32 ID:???]
どっちでもいいことなんだが、気になったもので訂正
> (SELECT max(id)+1 FROM Table)
の+1は無くてもよかった...orz

833 名前:NAME IS NULL mailto:sage [2007/09/16(日) 16:59:59 ID:???]
>>831
スゲー。期待したものが取れました。書いてもらうとなるほどと
思うのですが。SQLってむずかしい。

834 名前:NAME IS NULL mailto:sage [2007/09/17(月) 11:00:47 ID:???]
以下のような2つのテーブルがあるとします。

1.商品テーブル:
商品コードと商品名の列からなるテーブル。
前提として商品コードの数は少ないものとし(10個程度)、今後増えるとしても1年に1個増える程度と仮定します。

2.部材テーブル:
部材コードと部材名称の列からなるテーブル。データ数は数万件。

ここで部材毎にこの商品では使用可能、使用不可能という情報を定義するとなると、部材コード、商品コードを列に持つ別テーブルを作成し、そこにデータを作成するのが普通かと思います。

しかし、現在携わっているシステムでは、そのようにしないで、部材テーブルに商品コードを列名として追加し、その値をフラグとして使用可能、使用不可能を定義するという設計がされてました。


このようなテーブル設計になっている理由ですが、どうやら以下のようなことらしいです。

・部材テーブルを開くだけで、部材がどの商品で使用可能かが一目で確認出きる。

・最初に大量に部材をテーブルに登録する時に、EXCELで管理している一覧表からコピーペーストで簡単にデータを追加出きる。

部材一覧はお客様がEXCELで管理してます。フォーマットは部材が行方向に並び、列方向に商品コードがあって、セルのチェックのありなしで、部材がどの商品で使えるかどうかを管理してます。

・新しい部材コードを追加する時に、その部材がどの商品で利用可能かを同時にチェックしていくことでデータが作成出きる。

上記のような設計とか場合によってはありなのでしょうか?
メンテナンス上の理由だけであれば、テーブルは3つ使い、クロス集計のviewを作成して、それで管理するというのもありそうな気がしてますが。

835 名前:NAME IS NULL mailto:sage [2007/09/17(月) 15:19:32 ID:???]
>>834
正規化という観点からなら、商品・部材・商品部材関連の3表に分けるのがセオリー。
ただしパフォーマンスや運用上の理由で(第一)正規形崩しをすることはある。
以下3つの条件がそろえば使うこともある。
部材から商品の問い合わせだけで商品からの問い合わせがない。
基本的に登録時に辞書的に使うもので基本的に結合はしない。
商品側のアイテムにほとんど変化がない。

客に入力してもらうためのフォームはデータを横に持ったほうがわかりやすいとしても
内部のテーブルをどう持つかは分けて考えるべき。
あとエクセルのデータと内部のテーブルはどちらが正でどちらが副かはしっかり決めておくこと。


836 名前:NAME IS NULL [2007/09/21(金) 23:16:04 ID:kSnyp4HK]
user score
-------------
aho   10
boke 20
aho     5

user
------
aho
boke
kasu
から
user score
-------------
boke 20
aho   15
kasu   0
というのを得たいのですが、どのようにすればいいのでしょうか。

837 名前:NAME IS NULL mailto:sage [2007/09/22(土) 00:04:32 ID:???]
>>836
上をTable1、下をTable2として、
SELECT t2.user, SUM(t1.score)
FROM Table1 t1
   RIGHT OUTER JOIN
   Table2 t2
   ON t1.user = t2.user
GROUP BY t2.user

838 名前:837 mailto:sage [2007/09/22(土) 00:05:45 ID:???]
ORDER BYつけ忘れた・・・

839 名前:NAME IS NULL mailto:sage [2007/09/22(土) 00:30:08 ID:???]
>>837
それだとkasuのscoreが0にならずにnullになる。


840 名前:837 mailto:sage [2007/09/22(土) 00:36:09 ID:???]
>>839
まあそのへんは適当にCOALESCEなりCASEなりで。



841 名前:836 mailto:sage [2007/09/22(土) 00:47:43 ID:???]
>>837 (840)
caseを使えばよかったんですね。
ありがとうございます。


842 名前:NAME IS NULL [2007/09/22(土) 16:43:44 ID:gJY9Nx7q]
day ID data
0922 1 あ
0922 2 い
0923 1 う
0923 2 え
0924 1 お
0924 2 か

上記のIDのルールは、必ず各日付で1から開始されるということです。
22日のID2から24日のID1までという指定で、「いうえお」という結果を得たいのです。
これって1度のクエリで取得することは可能なんでしょうか?

843 名前:NAME IS NULL mailto:sage [2007/09/22(土) 16:56:40 ID:???]
>>842
day-IDで索引があるなら野暮ったいようで一番妥当なやり方。最適化も期待できる。
where day > '0922' and day < '0924 or day = '0922' and ID >='2' or day = '0924' and ID <= '1'
下記の場合索引がつかわれない可能性が大きい。
where day + ID >= '09222' and day + ID <= '092401'
(+ で文字列の連結が出来るとする)

844 名前:NAME IS NULL mailto:sage [2007/09/22(土) 16:58:51 ID:???]
もしかして、where日付範囲 and not (22日でID2未満) and not (24日でIDが1より大)
という感じで、日付で選択してから両端を切り落とせばOK?

845 名前:842 mailto:sage [2007/09/22(土) 17:10:43 ID:???]
>>843
大変美しい解を、どうも有り難うございます。
一瞬、844を思いついたのですが、843様の方がスマートです。
どうも有り難うございました。


846 名前:NAME IS NULL [2007/09/24(月) 21:15:10 ID:2+Cwu/kw]
ずいぶん初歩的な質問で悪いんですが合併律、分解律、擬推移律の成り立ちを証明したいんですが…
アームストロングの公理系調べても成り立つとしか書いてないもので…
だれか証明のプロセスを説明していただけないでしょうか?

847 名前:NAME IS NULL [2007/09/24(月) 22:09:07 ID:BEV9oSXR]
それってSQL関係あんの?

848 名前:NAME IS NULL mailto:sage [2007/09/24(月) 22:31:48 ID:???]
こっち(↓)向きの話題かな。

頼むから正規化しろよ 第二正規形
pc11.2ch.net/test/read.cgi/db/1116097001/

849 名前:NAME IS NULL [2007/09/24(月) 23:51:54 ID:2+Cwu/kw]
あーそっちのほうがいいかもしれないです

そっちで聞いてもマルチ死ねって言われないですかね…?

850 名前:NAME IS NULL mailto:sage [2007/09/24(月) 23:54:16 ID:???]
「向こうで聞きます」って言ってからにすれば普通はマルチだとは言われない



851 名前:NAME IS NULL mailto:sage [2007/09/25(火) 00:13:19 ID:???]
では向こうで聞いてみます…

852 名前:NAME IS NULL [2007/09/26(水) 13:06:56 ID:xJgKrS79]
ID TYPE COUNT
001 A 1
002 A 2
002 B 5
003 A 3
003 B 6
003 C 9

という表から

ID A B C
001 1 0 0
002 2 5 0
003 3 6 9

という結果を得たいのですが良い方法は無いでしょうか?
TYPE の数は取りあえず固定なのですが増えても大丈夫なようにしたいのです。


853 名前:NAME IS NULL mailto:sage [2007/09/26(水) 14:57:12 ID:???]
テーブルA, Bがあって、AのキーはID、BのキーはIDと枝番です。

Bのテーブルの数量をID毎に集計し、それをAのテーブルにある単位数で割った
結果を、最後にAにupdateしてやりたいんですが、

UPDATE A
SET
A.基準数 = (SELECT SUM(B.数量) FROM B WHERE B.ID = A.ID) / A.単位数

というSQLは書けない訳で、、、、(by Oracle10g)


この意図に沿ったSQLの記述をご教示頂きたく。




854 名前:NAME IS NULL [2007/09/26(水) 15:08:06 ID:T24KY3Jz]
>>852
SELECT ID,
    CASE WHEN TYPE='A' THEN COUNT ELSE 0 END AS A
    CASE WHEN TYPE='B' THEN COUNT ELSE 0 END AS B
    CASE WHEN TYPE='C' THEN COUNT ELSE 0 END AS C
FROM テーブル名


855 名前:NAME IS NULL mailto:sage [2007/09/26(水) 17:30:16 ID:???]
>>853
Oracle使いじゃないからワカランのだけど、そのSQLが動いてもよさそうなもんだが...。
他には、
SET A.基準数 = (SELECT SUM(B.数量)/A.単位数 FROM B WHERE B.ID=A.ID)
とかでもダメなんかな。

856 名前:NAME IS NULL mailto:sage [2007/09/26(水) 17:31:11 ID:???]
>854
レス、サンクスです。
でもダメでした。環境は PostgreSQL 8.1.9

create table idtest (id char(3),type char(1),count int);
insert into idtest values ('001', 'A', 1);
insert into idtest values ('002', 'A', 2);
insert into idtest values ('002', 'B', 5);
insert into idtest values ('003', 'A', 3);
insert into idtest values ('003', 'B', 6);
insert into idtest values ('003', 'C', 9);

SELECT ID,
CASE WHEN TYPE='A' THEN COUNT ELSE 0 END AS A,
CASE WHEN TYPE='B' THEN COUNT ELSE 0 END AS B,
CASE WHEN TYPE='C' THEN COUNT ELSE 0 END AS C
FROM IDTEST;

id | a | b | c
-----+---+---+---
001 | 1 | 0 | 0
002 | 2 | 0 | 0
002 | 0 | 5 | 0
003 | 3 | 0 | 0
003 | 0 | 6 | 0
003 | 0 | 0 | 9
(6 rows)
別々の行ででてしまいましたです…

857 名前:NAME IS NULL mailto:sage [2007/09/26(水) 17:38:32 ID:???]
>>856
当たり前だろ。Group by しれ

858 名前:NAME IS NULL [2007/09/26(水) 18:06:26 ID:xJgKrS79]
>857

IDでgroup by しようとして

SELECT ID,
CASE WHEN TYPE='A' THEN COUNT ELSE 0 END AS A,
CASE WHEN TYPE='B' THEN COUNT ELSE 0 END AS B,
CASE WHEN TYPE='C' THEN COUNT ELSE 0 END AS C
FROM IDTEST group by ID;

こうすると
ERROR: column "idtest.type" must appear in the GROUP BY clause or be used in an aggregate function
でおこられるのですよ。
type をgroup by に含めると相変わらず6行出て来てしまいますし…


859 名前:NAME IS NULL mailto:sage [2007/09/26(水) 18:21:00 ID:???]
>>858
sumで括れ。
sum(CASE WHEN TYPE='A' THEN COUNT ELSE 0 END) AS A,
以下同じ

860 名前:NAME IS NULL mailto:sage [2007/09/26(水) 18:21:24 ID:???]
>>853
update ... set ... = <subquery> は動くはずだから >>855 でいけるはず。

>>858
select ID, count(case when TYPE = 'A' then 1 else 0 end),(以下略)



861 名前:860 mailto:sage [2007/09/26(水) 18:24:08 ID:???]
ケコーンした上に間違えた・・・
>>859でいいです・・・

862 名前:NAME IS NULL mailto:sage [2007/09/26(水) 18:25:50 ID:???]
>859
天才。
別に足すわけじゃなくても sum 使うんだ…
aggregate function 云々のエラーが出たからsumも考えたんだけど
sum(count)とかやったら相変わらずtypeをgroup by に含めろって言われるし。

これでうまくいきました。サンクス>859
SELECT ID,
sum(CASE WHEN TYPE='A' THEN COUNT ELSE 0 END) AS A,
sum(CASE WHEN TYPE='B' THEN COUNT ELSE 0 END) AS B,
sum(CASE WHEN TYPE='C' THEN COUNT ELSE 0 END) AS C
FROM IDTEST group by ID;
id | a | b | c
-----+---+---+---
003 | 3 | 6 | 9
001 | 1 | 0 | 0
002 | 2 | 5 | 0
(3 rows)


863 名前:NAME IS NULL [2007/09/26(水) 23:39:37 ID:DBQhsmg7]
SQLとは話がずれてしまうのですが、質問させてください。

私が今入っている現場で、「デッドロックが起きるから」という理由で
ロックを使わずに、更新日時を持たせたカラムを使って排他制御をして
います。これって普通なんでしょうか?

ロックだけで排他制御をするのっておかしいんでしょうか?

864 名前:NAME IS NULL mailto:sage [2007/09/27(木) 00:18:21 ID:???]
>>863
楽観的排他というよく使われる手法。
悲観的排他という言葉と一緒にググってみなされ。

865 名前:NAME IS NULL mailto:sage [2007/09/27(木) 00:44:20 ID:???]
>>864
オプティミスティックロックでデッドロックは防げんと思うがな。

まぁ>>863の説明だけからじゃ、どっちなのか判断はつかんが。
本当にPMがアホだったという可能性もなくはないし。

866 名前:NAME IS NULL mailto:sage [2007/09/27(木) 01:10:55 ID:???]
>>865
デットロックにはならないのと違うの?あっさり失敗するだけで。

867 名前:NAME IS NULL mailto:sage [2007/09/27(木) 14:05:47 ID:???]
ttp://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp11/entwebapp11_02.html
↑でいう「業務排他制御」の事か?

868 名前:NAME IS NULL mailto:sage [2007/09/27(木) 22:18:48 ID:???]
>>866
更新対象のリソースが一つだけの場合はそもそもデッドロックは発生しない。
更新対象のリソースが複数ある場合、基本的にオプティミスティックロックは使えない。

ただしこの手法がまったく使えないわけではなくて、例えば代表の一つのテーブルを
決めて、それを参照して全テーブルの更新の可否を判断するという形で用いられる
ことはある。
ところがそのような形にした場合、オプティミスティックロックだろうが通常のロック
だろうが、デッドロックを防ぐ上では同等。
要は、複数のリソースの獲得の競合がデッドロックなわけなんで、それを代表の
1リソース(mutex)を獲得したトランザクションが総獲りできるという形にすることが
この場合のデッドロック防止手法の本質なわけ。


869 名前:NAME IS NULL mailto:sage [2007/09/27(木) 22:39:45 ID:???]
質問者が「デッドロック」という単語を
ただの「ロック待ち」と混同して使っている予感。

てか実際に混同されてるケースって多いと思う。

870 名前:863 mailto:sage [2007/09/27(木) 23:42:25 ID:???]
>>864-869
回答ありがとうございました。

教えていただいた通り、楽観的排他のことでした。
大変勉強になりました。




871 名前:NAME IS NULL mailto:sage [2007/09/28(金) 13:04:37 ID:???]
code
------
'abcd'
''
NULL

上のような文字列値が入っているテーブルで
「NULLでない」かつ「1文字以上の値が入っている」行を抽出しようと

WHERE (code IS NOT NULL) AND (code <> '')

上記のSQLを実行したのですが、SQLServerでは期待通り'abcd'の行が帰ってきたのに
Oracle9iでは1行も該当しませんでした。

Oracleで同様の結果を得るためには条件式をどのようにすればいいのでしょうか?

872 名前:NAME IS NULL mailto:sage [2007/09/28(金) 18:04:51 ID:???]
>>871
WHERE code IS NOT NULL
oracleだと '' と NULL の区別はないからこれでいい。

873 名前:871 mailto:sage [2007/09/28(金) 19:37:32 ID:???]
>>872
SQLServerをメインで使っているので知らなかったのですが
まさか''とNULLが区別されないとは思いもよりませんでした。

おかげで思ったとおりの動作ができそうです。ありがとうとざいました

874 名前:NAME IS NULL mailto:sage [2007/09/28(金) 19:48:47 ID:???]
like '_%' なら DBMS 問わないんじゃね?

875 名前:NAME IS NULL mailto:sage [2007/09/30(日) 13:56:59 ID:???]
内容
----------
123450
123459
345210
233442
323280

例えば↑のような数字の羅列が入ったテーブルがあったとして
↓のように下一桁が「0」のデータ内容だけ取りたいんですけど


内容
----------
123450
345210
323280

何かいいSQLはないでしょうか?
環境はoracle10gを使用しています。

876 名前:NAME IS NULL mailto:sage [2007/09/30(日) 14:16:11 ID:???]
>875
mod(列名,10)=10
でいいんでわ?


877 名前:NAME IS NULL mailto:sage [2007/09/30(日) 14:55:09 ID:???]
=0 でしょ。

878 名前:NAME IS NULL mailto:sage [2007/09/30(日) 19:08:56 ID:???]
>>875-876
mod(列名,10)=0でいいのかな?
余りから導き出せばいいのですね。
ありがとうございます

879 名前:NAME IS NULL mailto:sage [2007/09/30(日) 22:53:43 ID:???]
spool パス名 ファイル名

で、メモ帳に書いた命令を全部行うことができるとわかったのですが
なんどやっても成功せず・・・
パス名ってのを勘違いしてるのか、もしくは拡張子が.txtのままじゃあだめなのか・・・

どうすればよいでしょうか?

880 名前:NAME IS NULL mailto:sage [2007/09/30(日) 23:32:20 ID:???]
>>879
それはSQLとは関係ないぞ、sqlplusのコマンドの質問はoracleスレへ。

建前はそれとして、spoolは結果の出力先をファイルにする命令じゃ無かった?



881 名前:NAME IS NULL mailto:sage [2007/10/01(月) 16:39:37 ID:???]
"select id, num from tbl" で取得した結果が

id num
---------
1  3
1  4
1  5
2  1
2  2
3  2
3  3
3  4

となった場合に、numだけは1からの連番にしたいんですがSQLの書き方だけで
可能でしょうか。つまり、TBLに8行しかなくても、以下の様に11行返したい
んです。

id num
---------
1  1
1  2
1  3
1  4
1  5
2  1
2  2
3  1
3  2
3  3
3  4


882 名前:NAME IS NULL mailto:sage [2007/10/01(月) 17:28:21 ID:???]
>>881
SQLでやらなきゃいかんような処理じゃないと思う。
select id, max(num) from t881 group by id
ここまでSQLであとはストアド使うかアプリでやったほうがまとも。
どうしてもSQLだけでやりたいなら別途
seq
---
1
2
3
:
99
といったレコードのテーブルを準備しておいてクロスジョイン。
select a.id, b.seq as num from
(select id, max(num) as maxnum from t881 group by id) a
cross join t881s b
where b.seq <= maxnum


883 名前:NAME IS NULL mailto:sage [2007/10/02(火) 19:19:44 ID:???]

select t1.id,count(*) num
from tbl t1
cross join tbl t2
where t1.id=t2.id
and t2.num<=t1.id
group by t1.id



884 名前:NAME IS NULL mailto:sage [2007/10/04(木) 17:16:12 ID:???]
>>883
????意味不明


885 名前:NAME IS NULL [2007/10/06(土) 09:37:10 ID:eMMtvj7o]
すみません教えてください

Aテーブル
SYSCODE   NAME
1         山田太郎
2         田中花子
3         山本次郎

Bテーブル
SYSCODE   A_SYSCODE  NAIYO
1         2         2007/10/01 入室
2         2         2007/10/01 貸し出し
3         1         2007/10/01 入室
4         3         2007/10/01 入室
5         3         2007/10/01 退室

AテーブルのSYSCODEとBテーブルのA_SYSCODEをSQLでLEFTJOINして
SYSCODE   NAME    B_SYSCODE   NAIYO
1         山田太郎  3          2007/10/01
2         田中花子  1
2         田中花子
3         山本次郎


886 名前:885 [2007/10/06(土) 09:59:40 ID:eMMtvj7o]
書き込みミスった・・・OTL
すみません教えてください

Aテーブル(個人情報テーブル)(1000件)
SYSCODE   NAME
1         山田太郎
2         田中花子
3         山本次郎

Bテーブル(カードログテーブル)(100万件)
SYSCODE   A_SYSCODE  NAIYO
1         2         2007/10/01 入室
2         2         2007/10/01 貸し出し
3         1         2007/10/01 入室
4         3         2007/10/01 入室
5         3         2007/10/01 退室

AテーブルのSYSCODEとBテーブルのA_SYSCODEをSQLでLEFTJOINして
SYSCODE   NAME    B_SYSCODE   NAIYO
1         山田太郎  3          2007/10/01 入室
2         田中花子  1          2007/10/01 入室
2         田中花子  2          2007/10/01 貸し出し
3         山本次郎  4          2007/10/01 入室
3         山本次郎  5          2007/10/01 退室
と出しています。
Bテーブルの内容は個人の最新のカードログ情報だけを表示させて欲しいと
依頼がありメンテしていますが
BテーブルでSYSCODEの最大値(別名でBMAXCD)をA_SYSCODEでグループ化してaを作成。
(A_SYSCODEとBMAXCDのフィールド)
aのBMAXCDとBテーブルのSYSCODEをLEFTJOINしてNAIYOを結合させてbを作成。
(A_SYSCODEとBMAXCDとNAIYOのフィールド)
AテーブルのSYSCODEとbのA_SYSCODEをLEFTJOINして最新のログ番号と内容を結合させて
結果を表示するSQLを作り実行すると回答が返ってくるまでに20分近くかかります(下手したらタイムアウトする)
20分近くかかって表示される結果を速くすることはできないのでしょうか?

887 名前:NAME IS NULL mailto:sage [2007/10/06(土) 10:21:24 ID:???]
>>886
Bテーブルに(SYSCODE, A_SYSCODE)と(SYSCODE, NAIYO)の
インデックスを張る。
DBMSによっては(SYSCODE, A_SYSCODE, NAIYO)のインデックスだけでも
いいかもしれない。

888 名前:NAME IS NULL mailto:sage [2007/10/06(土) 10:28:14 ID:???]
>>886
どの処理に時間がかかっているか調べたら? たぶん
> BテーブルでSYSCODEの最大値(別名でBMAXCD)をA_SYSCODEでグループ化してaを作成。
に時間がかかっているかと。

BテーブルのA_SYSCODEにインデックスを張って、先に対象のA_SYSCODEを抜き出してmax(B.SYSCODE)をゲット。
そこから、B LEFT JON Aでいいんじゃね。

SELECT * FROM
(SELECT * FROM Btable WHERE SYSCODE = (SELECT max(SYSCODE) FROM Btable WHERE A_SYSCODE = ?)) AS b
JOIN Atable ON b.A_SYSCODE = Atable.SYSCODE;

DBによっては、

SELECT * FROM Btable JOIN Atable
ON Btable.SYSCODE = (SELECT max(SYSCODE) FROM Btable WHERE A_SYSCODE = ?)
AND Btable.A_SYSCODE = Atable.SYSCODE;

でもいいかな。

889 名前:NAME IS NULL mailto:sage [2007/10/06(土) 10:31:14 ID:???]
っと、だらだら書いたらかぶった。
おまけに、A_SYSCODE=? じゃだめか、Atable.NAMEから引っ張り出さんと。

890 名前:NAME IS NULL mailto:sage [2007/10/06(土) 10:33:47 ID:???]
>>886
A, BテーブルのSYSCODEに索引があるのは当然として、
Bテーブルに(A_SYSCODE, SYSCODE)の索引が必要なんじゃないかな。
これがないと
SELECT A_SYSCODE, MAX(SYSCODE) AS BMAXCD FROM Bテーブル GROUP BY A_SYSCODE
で実際の並び替えが発生する。



891 名前:885 [2007/10/06(土) 14:16:11 ID:eMMtvj7o]
ありがとうございます
ちなみに使用しているDBはSQL Server7.0です・・・
調べてみたらBテーブルでSYSCODEの最大値(別名でBMAXCD)をA_SYSCODEで
グループ化してaを作成でものすごく時間かかっていました。
よくしらべてみたA_SYSCODEのフィールドがNULLのものあった・・・
(カードや個人データない人の処理でA_SYSCODEに何も入れてない・・・OTL)
INDEXはSYSCODEのみでその他のINDEXは他の画面や処理で使っているので
今回の処理では使えないINDEXばかりです・・・・
やっぱBテーブルのSYSCODEとA_SYSCODEの組み合わせのINDEXも張らないと
いけないようですね・・・・
そうなるとBテーブルに(ログテーブル)にINDEXが20個になってしまい
張りすぎで他の処理に影響でないか不安ですが・・・
SELECT
A_SYSCODE, MAX(SYSCODE) AS BMAXCD
FROM Bテーブル
GROUP BY A_SYSCODE
でビューを作って
AのSYSCODEとビューのA_SYSCODEをJOIN
ビューのBMAXCDとB.SYSCODEでJOINしようと
おもったんですけど・・・どうなんでしょうか?

892 名前:NAME IS NULL mailto:sage [2007/10/06(土) 17:35:14 ID:???]
>>891
BテーブルにA_SYSCODEのインデックスがすでにあり、
かつ、A_SYSCODEがNULLの割合が非常に高ければ(8割とかそのくらい)、
AテーブルとBテーブルを先にINNER JOINすると多少速くなるかもしれない。

そうでないなら(SYSCODE, A_SYSCODE)のインデックスを張っちゃうしかないと思う。
19個が20個になったところで今更どうってことないでしょ。

ちなみにビューでは解決にならないよ。

893 名前:NAME IS NULL mailto:sage [2007/10/06(土) 18:05:59 ID:???]
B.A_SYSCODEごとのB.SYSCODEが最大のレコードを求めるという
問題ならさんざん既出だが。

ただ、今日の回答者連はろくなのがいないな。

894 名前:NAME IS NULL mailto:sage [2007/10/06(土) 18:15:49 ID:???]
>>893
いや、やり方は分かった上でパフォーマンスのことを聞いているんだから
別に既出じゃないと思うが。

てか自分が「まともな回答」をしてやれよ。

895 名前:NAME IS NULL mailto:sage [2007/10/06(土) 20:55:44 ID:???]
過去ログ嫁


896 名前:NAME IS NULL mailto:sage [2007/10/07(日) 19:36:49 ID:???]
>891は素直に一時テーブルというものを調べてみるがヨロシ。
ちょっと複雑なSQLを書く場合には、SQL鯖の場合は1SQLでやらず、
一時テーブルが最強。

897 名前:NAME IS NULL mailto:sage [2007/10/07(日) 20:22:11 ID:???]
>>896
インデックスのない100万件のテーブルから1000件程度を取り出すのに
一時テーブルを使ったらどう速くなるのかkwsk。

898 名前:NAME IS NULL mailto:sage [2007/10/09(火) 21:55:52 ID:???]
>897
896だけど。
詳しくといわれても、詳しくは書けん。原理はおいらも知らん。
だって、それがSQL鯖クォリティであり、MSの企業秘密だから。

Oracleとかで一時テーブル使ってたら一生判らないことだから、
一度、使ってみて実感すればよいことなりよ。

899 名前:NAME IS NULL mailto:sage [2007/10/09(火) 22:20:38 ID:???]
>>898
理屈のわからない動作というのは少なからずあるものだが、
そのときは再現性のあるコードなり条件なりをあげるべき。
そうでなければただの電波。

900 名前:NAME IS NULL mailto:sage [2007/10/09(火) 22:47:33 ID:???]
一時テーブル+ストアドプロシージャで少しましになるケース。
A_SYSCODE、NAME, B_SYSCODE, NAIYO からなる一時テーブルを準備。
Aテーブルをもとに1000件のレコードを作る。
 B_SYSCODEはゼロ, NAIYOはNULLで初期化。
Bテーブルをカーソルで1件ずつ読み、
 一時テーブルのA_SYSCODEがマッチする場合は
  B_SYSCODEを比べて大きければ
    そのレコードのB_SYSCODE, NAIYOを置き換える。
これでBテーブルへのアクセスは全件読み取りだけでソートは発生しなくなる。

A_SYSCODEとB_SYSCODE(最終分のみ)のレコードをはじめから用意しておくのが、
この手の問題への一番の処方箋なのだけどね。



901 名前:NAME IS NULL [2007/10/10(水) 17:16:18 ID:sVDA5qMU]
SQLSERVER2000

ビュー内でストアドプロシージャを呼び出す方法はありますか?



902 名前:NAME IS NULL mailto:sage [2007/10/10(水) 18:17:03 ID:???]
>>901
Microsoft SQL Server 総合スレ 5
pc11.2ch.net/test/read.cgi/db/1175091880/l50


903 名前:NAME IS NULL mailto:sage [2007/10/10(水) 18:29:10 ID:???]
ありがとうございます。そちらを探してみます。

904 名前:NAME IS NULL [2007/10/10(水) 18:29:22 ID:IgcJtG6a]
Accessの集約関数にFirst()というのがあって、
並んだ列の一番最初の要素を返すというものなんですが、
Postgresで同じようなことをやる関数もしくは方法のアイデアはないでしょうか?

a| b
----
あ|0
い|0
う|1
え|2

の場合に、select distinct first(a), b from table group by b
とすると、あ, 0 と い, 1 と う, 2という風になります。

905 名前:NAME IS NULL mailto:sage [2007/10/10(水) 19:27:06 ID:???]
>>904
あ=>0 う=>1 え=>2 の間違いじゃないのか?
それならDISTINCT ON が使えるが...
SELECT DISTINCT ON (b) b, a FROM Table ORDER BY b;

詳しくはマニュアルを、DISTINCT ONはPostgreSQL特有なので、続きがあれば
【Windows】 PostgreSQL8 Part.1 【対応】
pc11.2ch.net/test/read.cgi/db/1102247223/

906 名前:904 mailto:sage [2007/10/10(水) 19:46:56 ID:???]
>>905
ありがとうございます。
ばっちりいけました。

907 名前:NAME IS NULL mailto:sage [2007/10/11(木) 10:50:12 ID:???]
WEBシステムで画像のバイナリーデータを放り込んで
画像の管理を簡素化したいのですが
実際にそのようなシステムで管理されている大手サイトなどあるのでしょうか?
DB管理にともなってDBへの負担があまりにも大きいようなら採用しないつもりです。



908 名前:NAME IS NULL mailto:sage [2007/10/11(木) 23:37:25 ID:???]
>899
sigh....クレクレ君かい。

tblっていう10万件overぐらいのテーブル用意汁。

select * from tbl
union all
select * from tbl
union all
select * from tbl



insert into #tbl
select * from tbl

insert into #tbl
select * from tbl

insert into #tbl
select * from tbl

select * from #tbl

と、どっちが早いか試してみたらヨロシ。もちろんSQL鯖で。


909 名前:NAME IS NULL mailto:sage [2007/10/12(金) 00:27:36 ID:???]
>>908
クエリアナライザだと出すぎるから、これはADOとかで空読みしたらいいの?

910 名前:NAME IS NULL mailto:sage [2007/10/12(金) 05:51:23 ID:???]
>>908
899じゃないけど、なんか、メモリ上に読み込んでスワップが発生するから、
結局一時テーブルへ書き出した方が速いって感じか?
意外とDBの違いじゃなくて、OSに依存してて、他のDBでもWindows版なら
一時テーブルを使った方が速かったりして...。

にしても、元質の回答にあったインデックスを張って、必要なレコードだけ読み込んでから
集約させる方が、一時テーブルを使ったとしても100万件を読み込むより速い気がする。
まぁ、SQL鯖使いじゃないからどっちだっていいや。



911 名前:NAME IS NULL mailto:sage [2007/10/12(金) 07:01:05 ID:???]
>>907
昔Oracle InterMediaで作った。
管理は普通のデータと同じだが、
データの取り出しやプロパティ検索がめんどくさかった。


912 名前:NAME IS NULL mailto:sage [2007/10/12(金) 12:00:37 ID:???]
>>908
試してみたが一時テーブルを使った方が早いということは無かった。
ちょうどコピー分くらい余分に時間がかかっている。

使ったスクリプトはロダにあげた。
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/5053.txt

913 名前:NAME IS NULL [2007/10/13(土) 17:20:10 ID:jINrTab0]
NO NAME FLAG
1 tanaka 0
1 tanaka 1
2 satou 0
3 hayasi 0
3 hayasi 1

上記のようなNO,FLAGでユニークなテーブルがあるのですが、
NO毎に

FLAG=1のレコードが存在すればそのレコード
FLAG=1のレコードが存在しなければFLAG=0のレコード

を取得したいのですが、SQLでやるとすればどういうSQLになるのでしょうか?
DBはoracleなのですが、こういう処理はプログラム側で対応すべきなのでしょうか?

914 名前:NAME IS NULL mailto:sage [2007/10/13(土) 18:12:04 ID:???]
>913
とりあえずテーブル名をxとして、
select * from x where flag = 1 union select * from x where flag = 0 and not exists( select * from x as t where flag = 1 and t.no = x.no );
でどう?

915 名前:NAME IS NULL mailto:sage [2007/10/13(土) 18:15:30 ID:???]
>>913
その例テーブルだけだと、
SELECT NO,max(NAME),max(FLAG) FROM Table GROUP BY NO;
でもよさそうだな。

916 名前:NAME IS NULL mailto:sage [2007/10/13(土) 19:25:30 ID:???]
oracleならrank partitionでもいける。

917 名前:NAME IS NULL [2007/10/13(土) 23:18:47 ID:ATcEauDQ]
質問があります
>>885と似たようなケースなんですが


ログデータ(1000万件)
ログNo ログ区分 顧客コード 内容1 内容2 内容3

このテーブルを顧客コード毎にあるログ区分でログNoの最大(最新)をとる。 (A)
(A)の結果とログデータを(A)の最新ログNoとログデータのログNoでLeftJoin
して内容1・内容2・内容3とってきて顧客コード 最新ログNo 内容1 内容2 内容3
とする(B)

この(B)を

顧客マスタ
顧客コード 顧客名 商品シリアルNo 商品コード

シリアルマスタ
シリアルNo 商品コード 製造日 業者コード

商品マスタ
商品コード 商品名

業者マスタ
業者コード 業者名 部門コード 担当コード

部門マスタ
部門コード 部門名

担当マスタ
担当コード 担当名

6つのテーブルでLeftJOINして

業者コード 業者名 部門コード 部門名 担当コード 担当名 商品コード 商品名 シリアルNo 顧客コード 顧客名で
(D)を作り

(D)の顧客コードと(B)の顧客コードをLeftJoinし
(D)の内容+最新ログNo 内容1 内容2 内容3を表示したいのですが
ものすごく時間がかかります。(20分〜30分)
(D)の状態だと1分くらいでデータは取れるのですが・・・
よい方法はないでしょうか?

918 名前:NAME IS NULL mailto:sage [2007/10/14(日) 00:16:52 ID:???]
>>917
なんかよく分からんテーブル設計だな。

例えば「顧客コード」はひとつの顧客に対してひとつ振られるわけじゃなくて
ある顧客に出荷した商品ひとつに対してひとつ振られるわけ?

そうだとしたら、「顧客マスタ」(と言いながら実は出荷実績みたいなもの)に
あらかじめ商品名やら業者名やらを入れといちゃえばいいと思うけど。

この設計のままでどうにかしたいなら、
まずは(A)を作る時間、(B)を作る時間、(D)を作る時間を
それぞれ測ってみるところからだろ。

919 名前:NAME IS NULL mailto:sage [2007/10/14(日) 07:34:50 ID:???]
回答が欲しいならキーの情報と投げたSQLは必要。
自分で何とかしたいならプランを調べる。

920 名前:NAME IS NULL [2007/10/15(月) 09:44:37 ID:Y520eQFI]
一日ごとの東証一部の全株価の終値のデータがあります。
証券コード(INTEGER)
日付(DATE)
終値(FLOAT)
これが2年分あるのですが、これをDBに入れて、証券コードごとに
2年分を取り出せるようにしたいとおもってます。たとえば
トヨタ自動車だったら、証券コード(7203)を指定すると、2年分の
終値のデータが得られる、という感じです。
このとき、DBのテーブルはどのように設計したらいいですか?
どうかよろしくお願いします。




921 名前:NAME IS NULL mailto:sage [2007/10/15(月) 10:37:38 ID:???]
>>914-916さん
ありがとうございます!

>>914
うーん・・非常にわかりやすいです
>>915
参考になります。MAXだとちょっと問題あるケースでした、説明不足ですみません
>>916
ちょっと難しそうなので勉強してきます

一応以下のSQLのviewを作ってなんとか出来たのですが、
>>914の方がすっきりしそうです。
SELECT
CASE WHEN y.NO IS NULL THEN x.NO ELSE y.NO END,
CASE WHEN y.NO IS NULL THEN x.NAME ELSE y.NAME END,
CASE WHEN y.NO IS NULL THEN x.FLAG ELSE y.FLAG END,
FROM
(
SELECT * FROM x WHERE FLAG = 0
LEFT OUTER JOIN
SELECT * FROM y WHERE FLAG = 1
)

922 名前:NAME IS NULL mailto:sage [2007/10/15(月) 16:22:32 ID:???]
>>920
その3つでいいんじゃね?

923 名前:NAME IS NULL [2007/10/15(月) 19:41:31 ID:Y520eQFI]
>>922
ありがとうございます。
でも、上記のようにすると、2000/01/20のトヨタのデータをinsertして
その後に2000/01/21のデータをinsertすると、重複扱いになってしまいます。
primary keyは証券コードにしました。

924 名前:NAME IS NULL mailto:sage [2007/10/15(月) 20:10:05 ID:???]
>>923
PKは(証券コード, 日付)だろ。

ただし日付がDATE型だと同じ日の違う時間の値も入れられちゃうから
それがマズければもう少し工夫が必要。

925 名前:NAME IS NULL [2007/10/15(月) 20:21:37 ID:Y520eQFI]
>>924
ありがとうございます!
結局以下のテーブルにしました。
いまデータをinsert中です。

create table owarine (
id integer,
date date,
close float not null,
primary key (id,date));


926 名前:NAME IS NULL mailto:sage [2007/10/15(月) 20:38:12 ID:???]
>>920
個人的に作ってるものだけど、俺は

kabukaテーブル
銘柄コード 出来高年月日 始値 高値 安値 終値 出来高

primary key (銘柄コード、出来高年月日)にしてる。
(市場は考えない)

meigaraテーブル
銘柄コード 銘柄名 その他の情報〜

としてる


927 名前:NAME IS NULL [2007/10/15(月) 20:52:33 ID:Y520eQFI]
>>926
ありがとうございます。
そっちの方がいいですねえ。でもそれをつかうとするとinsert またやり直しか。。。。
でもやりなおしてみます。


928 名前:NAME IS NULL mailto:sage [2007/10/16(火) 15:24:43 ID:???]
nameとaddressのフィールドがあって、

address='○○県○○市〜'

と入力されているものとします。
このとき、県内、県外の順にソートしたい場合は
どのようなSQLを書けばよいのでしょうか?

929 名前:NAME IS NULL mailto:sage [2007/10/16(火) 15:39:04 ID:???]
上の例をみてSQLいじっていたらできました。

select name,
case when address like '○○県%' then 1
else 2 end as odr from tblHoge
order by odr
とすればいいんですね。

930 名前:NAME IS NULL [2007/10/18(木) 01:23:37 ID:G1mBcPwT]
oracle です。
テーブルAの各レコードのcolの値に対して
テーブルBからその値以下の最大値を得たいです。

【テーブル A】
col
10
20
30

【テーブル B】
col
5
15
18
25
30
40

【得たい結果】
5(Aは10。Bからこの値以下の最大値)
18(Aは20。Bからこの値以下の最大値)
30(Aは30。Bからこの値以下の最大値)


よろしくお願いします。




931 名前:NAME IS NULL mailto:sage [2007/10/18(木) 01:29:05 ID:???]
>>930
Oracle で通るかどうかわからんけど

select (select max(col) from B where col < A.col)
from A

932 名前:NAME IS NULL mailto:sage [2007/10/18(木) 01:30:47 ID:???]
>>930
いや、答えはすぐ書けるけど自分がどう考えたかぐらいは書こうぜ

933 名前:NAME IS NULL [2007/10/18(木) 11:20:44 ID:HHvByvdj]
初歩的なことですが、、、。
DB2で抽出した数字を指定桁でのゼロ埋め(前ゼロ)で抽出する方法が
わかりません。。。

例えば、指定フィールドに「2」が入っていたときは
002 で抽出するというような方法です。

すいませんがよろしくお願いします。

934 名前:NAME IS NULL mailto:sage [2007/10/18(木) 14:00:05 ID:???]
select '00' || 指定フィールド from なんか

935 名前:NAME IS NULL mailto:sage [2007/10/18(木) 14:30:26 ID:???]
あと、桁数を指定して右から切り取ればOK。
Right() とか。

936 名前:NAME IS NULL mailto:sage [2007/10/18(木) 22:08:14 ID:???]
>931
ありがとうございます


937 名前:NAME IS NULL [2007/10/19(金) 00:14:26 ID:dUbvn7+G]
すみません。教えてください。

SUBSTR と LIKE ではどちらが処理速度が速いですか?

SELECT * FROM TBL WHERE SUBSTR(B,1,2) = '12'

SELECT * FROM TBL WHERE B LIKE '12%'

938 名前:NAME IS NULL mailto:sage [2007/10/19(金) 00:17:02 ID:???]
ジブン デ タメセル ダロ ガ!!!!

939 名前:NAME IS NULL [2007/10/19(金) 12:41:53 ID:VIvt3Tqz]
はじめまして。

いま定職がなくて、今度面接を受けるのですが、

SQLの知識が必要な仕事なのですけれど、

ぜんぜんSQLのこと理解していなくて。。。

一時間の面接でボロが出ない程度の知識をあと一日か二日で覚えようと思ってるのですが、

最低限どれくらいのことを知っていればいいのでしょうか。。。

どうかよろしくお願い致します><

940 名前:NAME IS NULL [2007/10/19(金) 13:05:31 ID:sjmFNeIx]
質問させて下さい。

ACCESSでCOUNT関数内でDISTINCTが使えないので、
他に良い方法は無いか調べています。

| ID | SHOP | YYYYMM | DAY | PRICE |
 01    0001  200710   1     1000
 01    0002  200710   1      500
 02    0001  200710   2      800
 02    0002  200710   3      700

目的としては、上ようなテーブルで、
同一日に別なSHOPで買い物をしていないID(の人)で、
最大の単価(PRICEの合計)を求めたいのです。
(上の例だと3行目の800円が結果として欲しい)

SELECT MAX(total.hoge) as 最大の合計 FROM
 [SELECT SUM(PRICE) as total FROM tablename WHERE COUNT(DISTINCT SHOP) < 2
 GROUP BY ID, SHOP, YYYYMM, DAY;]. as hoge;

みたいな事でどうかな?と思ったのですが、ACCESSの制限で無理でした。
他にやりかたなどあれば教えて頂きたいのですが、如何でしょうか?




941 名前:NAME IS NULL mailto:sage [2007/10/19(金) 14:46:57 ID:???]
>>939
pc11.2ch.net/test/read.cgi/db/1057289721/

ここのスレを1から全部読んで理解くらいになれば大丈夫だと思うお!


942 名前:NAME IS NULL mailto:sage [2007/10/19(金) 15:45:30 ID:???]
>>940
そこはWHERE句じゃなくて、GROUP BY 句の後ろに
HAVING COUNT(DISTINCT SHOP) < 2
とすべきだと思うのだが、本当にCOUNT関数内にDISTINCTが使えないの?


943 名前:942 mailto:sage [2007/10/19(金) 15:53:43 ID:???]
ちょい補足。
HAVING count(DISTINCT SHOP)が使えるのなら、
GROUP BY句からSHOPは外せ。

944 名前:NAME IS NULL mailto:sage [2007/10/19(金) 18:11:12 ID:???]
>>942
あーご回答ありがとうございます。
調べて回ったんですが、ACCESSではCOUNT内でのDISTINCTは
使えないんです。(ACCESS 2003)
その後調べていると、WHEREにCOUNTはダメっぽいですね、、、
HAVINGが良く分かってないので、使いどころが分かりませんでした(><)
修正します。ありがとうございます。

945 名前:940 mailto:sage [2007/10/19(金) 19:29:00 ID:???]
自己解決出来たので報告しておきます。
(もっとスマートなやりかたあるかも知れませんが、、、)

SELECT Max(total) AS 最大値
FROM [SELECT SUM(price) AS total FROM tablename as a
 WHERE NOT EXISTS (SELECT * FROM tablename as b
  WHERE a.id = b.id
  AND a.yyyymm = b.yyyymm
  AND a.day = b.day
  AND a.office <> b.office;)
 GROUP BY id, yyyymm, day, office;]. AS c;

で、一応940で求めている最大値=800が表示されました。
942さん、ありがとうございました。

946 名前:sage [2007/10/19(金) 23:38:32 ID:a5j8WAG3]
>>941さん
ああ!どうもありがとうございます!!
これで受かる気がしてきました!!
わかりやすいですねー^^

947 名前:NAME IS NULL mailto:sage [2007/10/20(土) 16:32:47 ID:???]
valueSQL使いたいんだが、繋ぎ方がわからん。
データソースって、何を入れればいいんだ?

948 名前:NAME IS NULL mailto:sage [2007/10/22(月) 05:26:32 ID:???]
valueSQLって何かしらなかったんで調べてしまった。。
RDBMSは何使ってんの?
つーかスレ違いなんだが、汎用の質問スレ無かったっけ?

949 名前:NAME IS NULL mailto:sage [2007/10/23(火) 09:20:58 ID:???]
>>946
まじかよw

950 名前:NAME IS NULL [2007/10/23(火) 13:35:37 ID:4X2HVnn9]
SQLServer初心者です。
VB2005からSQLServer2005への接続について質問させて下さい。
同サーバーのプロジェクト名Test_dbにテスト接続はできるのですが、
データソース構成ウィザードで、テーブル、ビュー等の左側に「+」「−」
が無く、展開できません。 データソース、データセットとして実態を
取込めません。

ちなみにVB2005からAccessのテーブルをデータソース、データセットとして取込む事は
できました。

SQLServerから取込むにはどの様にするば良いでしょうか。
アドバイスお願いします。



951 名前:NAME IS NULL mailto:sage [2007/10/23(火) 17:03:06 ID:???]
トランザクションの分離レベルのRepeatable Readって、
トランザクションAがRepeatable Readでトランザクション開始
->
トランザクションBが表AのレコードBをUpdate更新して、コミット
->
トランザクションAが同じ表AのレコードBをUpdateで更新

しようとしたらどうなる?


952 名前:NAME IS NULL mailto:sage [2007/10/23(火) 17:32:55 ID:???]
>>950
ここはSQLServerのスレじゃないよ

Microsoft SQL Server 総合スレ 5
pc11.2ch.net/test/read.cgi/db/1175091880/

953 名前:NAME IS NULL mailto:sage [2007/10/23(火) 17:38:53 ID:???]
>>951
共有ロック式の場合のRepeatable Readは、トランザクションが読み取ったレコード全部に
コミットまでの期間共有ロックをかけてゆくと考えればいい。
>トランザクションBが表AのレコードBをUpdate更新して、コミット
この前にトランザクションAがレコードAを読み取っていればトランザクションBの更新はロックされ待機状態になる。
この前にトランザクションAがレコードAを読み取っていなければ競合は起きない。

マルチバージョニングの場合はシリアライザブルと同じ動作になる実装が多いと思う。Oracleとか。

954 名前:NAME IS NULL [2007/10/23(火) 17:39:23 ID:4X2HVnn9]
>952
失礼しました。 そちらに質問しました。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](;´∀`)<352KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef