トップページ⇒db
1001コメント361KB

SQL質疑応答スレ 14問目

レス数が1000を超えています。これ以上書き込みはできません。
0001NAME IS NULL2013/06/17(月) 22:42:14.82ID:???
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

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

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

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

前スレ:
SQL質疑応答スレ 13問目
http://toro.2ch.net/test/read.cgi/db/1343899481/
0002NAME IS NULL2013/06/17(月) 22:43:14.88ID:???
SQL言語リファレンス一覧
Oracle Database
http://docs.oracle.com/cd/E16338_01/server.112/b56299/toc.htm
Microsoft SQL Server
http://msdn.microsoft.com/ja-jp/library/bb510741
IBM DB2 Database
http://pic.dhe.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/c0004100.html
PostgreSQL
http://www.postgresql.jp/document/current/html/sql.html
MySQL
http://dev.mysql.com/doc/refman/5.1/ja/sql-syntax.html


参考リンク
http://sql.main.jp/cont/sql/map.html
http://www.atmarkit.co.jp/fnetwork/rensai/sql01/sql1.html
http://www.geocities.jp/oraclesqlpuzzle/
http://www.techscore.com/tech/sql/
0003NAME IS NULL2013/06/17(月) 22:44:16.85ID:???
過去スレ
13問目:http://toro.2ch.net/test/read.cgi/db/1343899481/
12問目:http://toro.2ch.net/test/read.cgi/db/1316769778/
11問目:http://hibari.2ch.net/test/read.cgi/db/1299305530/
10問目:http://hibari.2ch.net/test/read.cgi/db/1274791771/
9問目:http://pc11.2ch.net/test/read.cgi/db/1252492296/
8問目:http://pc11.2ch.net/test/read.cgi/db/1236253554/
7問目:http://pc11.2ch.net/test/read.cgi/db/1223525474/
6問目:http://pc11.2ch.net/test/read.cgi/db/1210940477/
5問目:http://pc11.2ch.net/test/read.cgi/db/1193486961/
4問目:http://pc11.2ch.net/test/read.cgi/db/1176553195/
3問目:http://pc11.2ch.net/test/read.cgi/db/1160458216/
2問目:http://pc8.2ch.net/test/read.cgi/db/1141622643/
帰ってきた:http://pc8.2ch.net/test/read.cgi/db/1124178925/
Part 2:http://pc8.2ch.net/test/read.cgi/db/1103113155/
初代:http://pc8.2ch.net/test/read.cgi/db/1056973582/
0004NAME IS NULL2013/06/17(月) 22:45:18.01ID:???
よくある質問1

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

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

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

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

(答)
select A.ID,
    A.DATE,
    A.DATA
from TableName A
   inner join
   (select ID, max(DATE) as MAX_DATE
    from TableName
    group by ID
   ) B
   on A.ID = B.ID
   and A.DATE = B.MAX_DATE
;
0005NAME IS NULL2013/06/17(月) 22:46:19.58ID:???
よくある質問2

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

というテーブルから

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

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

(答)
SELECT key,
    SUM(CASE data WHEN 'a' THEN 1 END) AS a,
    SUM(CASE data WHEN 'b' THEN 1 END) AS b
FROM table
GROUP BY key
ORDER BY key
;
0006NAME IS NULL2013/06/17(月) 22:47:20.85ID:???
よくある質問3

(問)
ID HOGE
01 A
01 B
01 C
02 A
03 B

HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか

(答1)
SELECT id
FROM TableName
WHERE hoge in ('A','B','C')
GROUP BY id
HAVING count(DISTINCT hoge) = 3
;

(答2)
select *
from TableName T1
where not exists (select *
         from (values 'A', 'B', 'C') T2 (HOGE)
         where not exists (select *
                  from TableName T3
                  where T1.ID = T3.ID
                  and T2.HOGE = T3.HOGE
                  )
         )
;
※valuesの部分(Table Value Constructor)はDBMSによって文法がかなり違うので注意
0007NAME IS NULL2013/06/17(月) 22:48:21.93ID:???
よくある質問4

(問)
列の数が可変な問合せはどう書きますか?

(答)
標準SQLでは書けません。
pivotという機能を搭載したDBMSなら一見書けそうですが実はやっぱり書けません。
Oracle 11g以降でpivot xmlというキーワードを使用すれば一応可変っぽくはなります。
が、素直にプロシージャを書くかアプリケーションで処理したほうが良いでしょう。

SQL Serverのpivot(2005以降)
http://msdn.microsoft.com/ja-jp/library/ms177410.aspx
http://www.sqlprof.com/blogs/sqldev/archive/2008/04/12/pivots-with-dynamic-columns-in-sql-server-2005-2008.aspx

Oracleのpivot(11g以降)
http://download.oracle.com/docs/cd/E16338_01/server.112/b56299/statements_10002.htm#CHDCEJJE
http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html
0008NAME IS NULL2013/06/17(月) 22:49:22.88ID:???
よくある質問5

(問)
年月(YYYYMM)を指定し、その年月に対応する年月日を取得したい

 例:201006を指定したら、以下の結果を得たい

   20100601
   20100602
    ・
    ・
    ・
   20100630

(答)
SQLでは存在しないデータを生成することはできません。
この問いの場合は素直にカレンダーテーブルを用意しましょう。

どうしてもやりたければ以下のような方法もなくはないですが、
再帰問合せの本来の使い方ではありません。
やめておくことを強くお奨めします。
(PostgreSQLのgenerate_series()関数なら辛うじてセーフかもしれませんが
 賛否の分かれるところでしょう。)

with TEMP (NUM) as (
    select 1 from dual
    union all
    select NUM + 1 from TEMP where NUM < 31
)
select to_char(to_date('201006', 'YYYYMM') + NUM - 1, 'YYYYMMDD')
from TEMP
where to_date('201006', 'YYYYMM') + NUM - 1 < add_months(to_date('201006', 'YYYYMM'), 1)
;

※上記はOracleの場合です。(11gR2以降)
※再帰問合せをサポートするDBMSならこれを適当に改変すれば動きますが
 どのみちお奨めしません。
0009NAME IS NULL2013/06/17(月) 22:50:23.84ID:???
以上、テンプレ終わり
0010NAME IS NULL2013/06/17(月) 23:03:40.16ID:???
同じデータベース内のあるテーブルが更新されたら、そのテーブルのデータに処理を行って別のテーブルに行を追加したいのですが
このような事をやる場合は他の言語(スクリプト言語など)を利用するしかないですか?
0011NAME IS NULL2013/06/17(月) 23:05:48.73ID:???
↑PostgreSQL をwebserver上で使う予定です
元のデータ追加にはpython上のプログラムから追加を行ったり問い合わせを行おうと思っています
0012NAME IS NULL2013/06/18(火) 00:16:44.80ID:???
>>10
triggerを知らないってことなの?
0013NAME IS NULL2013/06/18(火) 01:46:01.74ID:???
おとしやがって
0014NAME IS NULL2013/06/18(火) 10:43:41.02ID:???
ストアド作ってトリガで実行
0015NAME IS NULL2013/06/18(火) 11:54:39.89ID:???
ありがとうございます
どの項目を勉強すればいいかわかりました
0016NAME IS NULL2013/06/18(火) 22:12:58.28ID:nx7caqYT
【質問テンプレ】
・DBMS名とバージョン
SQlite3をphpのPDOを使って(ローカルでやるのはいろいろインストール面倒なので@pagesの無料サーバでやってます)
・テーブルデータ


・欲しい結果

テーブルitemに「8 hhh」というレコードを挿入する(手順1)と同時に
テーブルstockに「8 xxx 0」,「8 yyy 0」というレコードを挿入したい(手順2)。

手順1の段階でautoincrementのitemId 8を知る方法はありますか?
もしくは手順1と手順2との間で”重複している可能性のある”「data hhh」から「8 hhh」のレコード1つだけをselectする方法はありますか?


・説明
0017NAME IS NULL2013/06/18(火) 22:14:22.04ID:nx7caqYT
ttp://www.dotup.org/uploda/www.dotup.org4283484.jpg

すみません。画像上げるの忘れてました
0018NAME IS NULL2013/06/19(水) 02:48:05.64ID:???
ぐぐって上のほうに出てきたのがこれだけどどう
http://sqlite.1065341.n5.nabble.com/how-to-get-last-autoincrement-value-td1516.html
0019NAME IS NULL2013/06/19(水) 16:17:27.60ID:???
http://php.net/manual/ja/pdo.lastinsertid.php
適当にググってみた。違うかね。
0020NAME IS NULL2013/06/19(水) 19:22:51.50ID:9J5TodXQ
ありがとうございます。試してみます
0021NAME IS NULL2013/06/20(木) 11:47:44.37ID:???
>>20
試してから言え。
0022NAME IS NULL2013/06/21(金) 04:38:49.90ID:6QPf6GEU
同一構造のテーブルが二つあり、
二つを見比べて片方にしかない値を抽出したい場合、どう書けばいいでしょうか?
0023NAME IS NULL2013/06/21(金) 05:40:55.99ID:???
>>22
selectのマニュアル読め
0024NAME IS NULL2013/06/21(金) 06:19:37.15ID:???
EXCEPT(OracleだとMINUS)とかNOT EXISTSとかNOT INとか
やりようはあるけどそれだけの質問じゃあ>>23になっちゃうな
0025NAME IS NULL2013/06/22(土) 11:41:49.25ID:???
まぁ普通にminusだろうな
0026NAME IS NULL2013/06/22(土) 15:14:41.03ID:???
tbl1 join tbl2(直積)とwhere句の組み合わせと、

tbl1 inner join tbl2 on (列x=列y)と、処理の速さを比較すると違ってきますか。


複数列にnullを含んだテーブル同士があって、
そのnullを含む列をつかって結合させたいんですが、
どうも処理が重たくて困っています。

nullは値がないので、インデックスがつくられないそうです。
nullが多ければ多いほど、処理って遅くなりますよね。
0027NAME IS NULL2013/06/22(土) 15:19:18.33ID:???
>>26
sql server 2008 r2のexpressなんで、メモリが1GBまでしか有効にならないみたいです。
有料版つかったら、ぱぱぱっと処理されるでしょうか。
30分が経過しました。

行を1行だけに絞って同じ処理をすると、一瞬で終わりました。
これが22万行あるので、時間がかかっているようです。
メモリに展開させられたらもっと処理が速くなるのかなって思いました。
0028NAME IS NULL2013/06/22(土) 16:15:26.41ID:???
>>26
上のjoinはinner joinのinnerが無いだけじゃないのか?

一般論だが
DBMSにはオプティマイザがあるので、SQLだけでどっちが早いかはわからない
null=nullは真ではない。null=値も真ではない
null可能の項目でも、null以外を選択するのにインデックスは有効
0029NAME IS NULL2013/06/22(土) 17:02:43.33ID:???
>>28
ありがとうございます
今、インデックスをあわてて勉強しています
ユニーク制約でつくられるインデックスしかなかったんです
0030NAME IS NULL2013/06/22(土) 22:14:46.81ID:???
すみません。

相関クエリを、通常のテーブルを相関させて書くことはできますが、
相関クエリを、導出テーブルをつかって書くことはできるでしょうか。

外側のテーブルとして導出テーブルを使います。
それを内側の相関クエリ内で使いたいんです。

しかし、as table1 T1 などとして導出テーブルに相関名をつけられません。


select
x
,y
,z
,(select SUM(S) from table2 T2 where T2.k = T1.k) as r

from
)
select x,y,z,k
from abc
) as table1 T1 ←導出テーブルでこのT1という相関名をつけられません
0031NAME IS NULL2013/06/22(土) 22:17:00.22ID:???
>>30
SQL SERVER 2008 R2 EXPRESSです。
よろしくお願いします。

導出テーブルに相関名ってSQLデフォルトでも普通はつけられないのかな。
0032NAME IS NULL2013/06/22(土) 22:24:33.84ID:???
それ相関名じゃなくない?
table1ってのが相関名だろ。相関名二つもつけれるか?
0033NAME IS NULL2013/06/22(土) 22:30:41.38ID:???
>>32
table1だけではエラーになってしまいました。

select
x
,y
,z
,(select SUM(S) from table2 T2 where T2.k = table1.k) as r  ←ここで「table1」と指定することになりますが、エラーになって外テーブルと相関しません。

from
)
select x,y,z,k
from abc
) as table1 ←外側テーブルとなる導出テーブルを名づけます。

かといって、as table1 T1と二重に名前付けできません。
導出テーブルを相関クエリではつかえないってことでしょうか。
0034NAME IS NULL2013/06/22(土) 22:42:40.21ID:???
>>33
試したけど、SQLは問題なく通る
fromの後のカッコのtypo直してもダメなのか?
エラー出てるならエラー内容書いてみ
0035NAME IS NULL2013/06/23(日) 02:13:04.72ID:???
oracleとかで、外部参照制約かけるとのとかけないのとでは、selectの実効速度に違いは出ますか?
0036NAME IS NULL2013/06/23(日) 03:05:20.55ID:???
>>34
レスありがとうございます。

すみません、もう一度試してみたいと思います。
外側導出テーブル(as table1)と、スカラ相関クエリ内テーブルと、
相関させてみます。

できるとお聞きして、一度、簡単な例で試してみようと思います。
またレスします。

ありがとうございます。
0037NAME IS NULL2013/06/23(日) 18:49:45.05ID:???
>>34

ありがとうございました。
「できた」とお聞きして、自分でも簡単な例を実行してみました。
すると、エラーにならずに実行することできました。


次の相関クエリを組み試しました。

select 敬称CD as CD,(select 敬称 from 敬称表 TB2 where TB2.敬称CD = TB1.敬称CD) as 名称
from
(
select 敬称CD
from 敬称表
) as TB1


敬称表
--------
1 様
2 御中
3 殿
--------

意図した結果を得られました。

TB1は導出テーブルのエイリアスです。
また、これは、相関クエリでつかえる相関させるテーブル名としても使えることがわかりました。

>>33では勘違いしていたようです。
何か、別のエラーを生じさせてしまっていたようです。
原因を究明します。

ありがとうございました。
0038NAME IS NULL2013/06/25(火) 00:23:48.21ID:zEc4TkxA
SQLserver 2008 R2 です

where句の等号不等号の表記で、

where ・・・
and x <= y だと、okで、

where ・・・
and x =< y だと、エラーになります。

これって、標準なんでしょうか。
どっちでも良いように思うんですが、納得のいく説明があれば教えてください。
0039NAME IS NULL2013/06/25(火) 02:05:31.92ID:???
>>38
納得のいく説明とは、何が納得いかないの?

SQL Server(Transact-SQL)に =< と言う演算子は有りません
したがってエラーになるのは当たり前
標準SQLにあればサポートされるはずなので、標準SQLにもないでしょう
0040NAME IS NULL2013/06/25(火) 02:51:14.35ID:???
>>39
すみません、
等号不等号を組み合わせた演算子レベルでみることを忘れていました。
0041NAME IS NULL2013/06/25(火) 23:37:11.67ID:???
副問い合わせによる導出テーブルの各列のインデックスは、
もともとの実テーブルの列インデックスを継承して、
自動的に有効になっているのでしょうか。

それとも、導出クエリでインデックスを作成するステートメントでも必要になるのでしょうか。
ORDER BY句に列を書けばインデックスが有効化されるなどありますでしょうか。
0042NAME IS NULL2013/06/26(水) 02:25:45.85ID:???
>>41
自分が使っているデータベースの実行計画を見る方法を調べて、それで表示される
内容の意味を調べて、そしてもう一度自分のレスを読み直せ。
0043NAME IS NULL2013/06/27(木) 02:34:19.56ID:14GM02fv
>>20です。できました。お礼が遅くなってすみません。
0044NAME IS NULL2013/06/30(日) 14:48:16.61ID:???
mySQL5系の質問です。
2テーブルからデータを取得したいのですが、効率的なSQL文が組めず困っております。


tableA
 id name
 1 サザエ
 2 カツオ
 3 ワカメ
 4 タラヲ

というテーブルがあり、tableA.idをデータとしてセットする
tableBがあったとします。

tableB
 tableA_id key1 key2 key3 
   4     1    2   3 

key1〜key3にセットされる値は、tableA.idの値になります。tableA_idに関しても同様です。
この2つのテーブルからtableBのkey1〜key3にセットされているidに紐づく
実際のnameを取得したいです。

tableBがちょっと妙な気がするのですが、「tableA.idを構成しているのが、key1〜key3という意味」らしいです
データ取得時にtableA_idにセットする値が渡ってくるものとします

SELECT name FROM tableA
WHERE id IN (SELECT key1, key2, key3 FROM tableB WHERE tableA_id = 4);

最初はこのようなSQL文を組んでみたのですが、サブクエリ的にダメなようなので

SELECT name FROM tableA
WHERE id IN (SELECT key1 FROM tableB WHERE tableA_id = 4);

というようなSQL文をkey1〜key3まで繰り返すことしか思いつきません。。
もう少し効率的なSQL文が組めればと思うのですが、どなたかご指導頂けないでしょうか?
0045NAME IS NULL2013/06/30(日) 15:00:45.46ID:???
5系で纏めんじゃねえよ
EXPLAINしてみた?
ちなみにそのサブクエリだと5.5未満と5.6以降でだいぶ速度変わると思うけど
0046NAME IS NULL2013/06/30(日) 15:31:48.78ID:???
>>44
試してないけど

SELECT name FROM tableA
WHERE id IN (
SELECT key1 FROM tableB WHERE tableA_id = 4
UNION
SELECT key2 FROM tableB WHERE tableA_id = 4
UNION
SELECT key3 FROM tableB WHERE tableA_id = 4
)

はできないかな。
0047NAME IS NULL2013/06/30(日) 15:47:42.97ID:???
tableBの設計が明らかにおかしいけど
設計の話はスレ違いだしな
0048NAME IS NULL2013/06/30(日) 15:50:35.11ID:???
いや、明らかにおかしいというのは言いすぎだな
key1=保証人1、key2=保証人2とかだったらありえるか
0049NAME IS NULL2013/06/30(日) 23:59:22.56ID:???
>>44
最終的に欲しいデータが解らん
タラヲ,サザエ,カツオ,ワカメ で良いのか?

普通に考えたらtableAを4回joinするだけだが
select t.name,t1.name,t2.name,t3.name
from tableB
join tableA t on t.id=tableB.tableA_id
join tableA t1 on t1.id=tableB.key1
join tableA t2 on t2.id=tableB.key2
join tableA t3 on t3.id=tableB.key3
こんな感じ。mySQLで動くかどうかは知らん
0050NAME IS NULL2013/07/01(月) NY:AN:NY.ANID:???
>>44です。
返信遅れて申し訳ないです
>>46さん方式と>>49さん方式を試してみようと思います。

>>48-49
サザエさんの例がよくなかったのと、自分の説明が雑でした
テーブルAを食べ物、テーブルBを献立とさせてください

テーブルAには食べ物も献立もどちらも入っているのです(ここがよく意味わからないのですが。。。)
例えばサーモン握りであれば、サーモン握りもごはんもサーモンもタマネギも
テーブルAに登録されていて、テーブルBの方には
  
  tableA.id      key1      key2      key3
サーモン握りのid ごはんのid サーモンのid タマネギのid

このような形でデータが入っています。
それで、テーブルBの方からidを使ってテーブルAの食べ物名を取得。。らしいです。

ソシャゲ業界に転職したばかりで、ソシャゲはこういうものなのかと思っていたのですが
やっぱり変ですよね。。

お答え頂いた方、ありがとうございました
0051NAME IS NULL2013/07/01(月) NY:AN:NY.ANID:???
単に親子関係を持っていて、親は高々3つの個しか持たないっていう要件があるだけでしょう。
何を難しく考えてるのやら
0052NAME IS NULL2013/07/02(火) NY:AN:NY.ANID:???
まあ作りが悪いことはたしかw
0053NAME IS NULL2013/07/02(火) NY:AN:NY.ANID:???
正規化しろよ
0054NAME IS NULL2013/07/02(火) NY:AN:NY.ANID:???
ソシャゲだし、正規化しないほうが速度要件を満たしやすいんじゃない?
あと多分データのメンテがやりやすい(というかツールを作るのが楽)など。
0055NAME IS NULL2013/07/03(水) NY:AN:NY.ANID:???
普段SQLには全くご縁が無いのですが、急遽下記の作業をしなけらばならず困っています。

DBMS名とバージョン:SQLServer 2008 R2
説明
データベースAに格納されていたテーブルを新しいwinサーバBにコピーするように言われています。
そのため、外付けのHDDで、圧縮されたMDFファイルを渡されました。
外付けHDDから、サーバのデスクトップ上にデータをコピーし、そこで作業が止まっています。
(圧縮されたまま)


新しいサーバBにはSQL Server 2008R2がインストール済みですが、全く使っていません。
データは外付けのストレージに入れる予定です。
(つまり、サーバBのSQL Serverのmdfの置き場はストレージ上にする)
csvファイルの場合、テーブルを作ってデータを流し込むという作業はしたことがあるのですが、
mdfファイルで渡されたことが無かったので、作業が中断しております。
変な質問だったらごめんなさい。
ご教示頂けますと幸いです。
0056NAME IS NULL2013/07/03(水) NY:AN:NY.ANID:???
>>55
MDFファイルならアタッチでいける。
その外付けストレージにファイルを置いてからな。
0057NAME IS NULL2013/07/03(水) NY:AN:NY.ANID:???
どう考えてもスレ違い。専用スレにどうぞ。
0058NAME IS NULL2013/07/03(水) NY:AN:NY.ANID:???
>>56
ありがとうございます(T_T)
0059NAME IS NULL2013/07/05(金) NY:AN:NY.ANID:???
追加しようとしているレコードを主キーから追加・修正を自動判別して実行させたいんですけど良い方法は無いでしょうか?
今はselect count (*) from tableName where primarykey=fookeyで
1ならupdate、0ならinsertってしているんですがこの方法しか無いのでしょうか?
python2.6.6からsqlite3を使用しています。
0060NAME IS NULL2013/07/05(金) NY:AN:NY.ANID:???
SQLiteならinsert or replaceの構文があるだろう
0061592013/07/06(土) NY:AN:NY.ANID:???
>>60
ありがとうございます!
こんな便利な構文があったんですね、まさに求めていた理想的な方法でした。
0062NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
MYSQL5.5

key   a   b
--------------------
1    3   2
2    1   1
3    5   2
4    2   3

こんな感じでkeyが1〜500万くらいまでの500万行のテーブルなんですが

UPDATE テーブル SET a = a + 1 WHERE key = 5749
UPDATE テーブル SET b = b + 1 WHERE key = 18312
UPDATE テーブル SET a = a + 1 WHERE key = 991127
〜
みたいなUPDATE文を300回くらい同時に実行すると10秒程度掛かってしまい
遅すぎて死にそうです

なにか早くする方法ないでしょうか
0063NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>62
「同時」というのが、厳密にどういうことなのかわからないけど、keyにインデックスが無いなら
インデックスを張れば速くなるよ。
0064NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
sqlite 3.7.17

* table club_master

club&nbsp;&nbsp;name
--------------
0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名古屋
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;東京
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大阪

* table match_data

match&nbsp;&nbsp;club
--------------
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1

* table scores

match&nbsp;&nbsp;club&nbsp;&nbsp;scorer
---------------------------------
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;山田
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;鈴木
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;田中
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;田中

と3個のテーブルがあって、match_data と scores を結合してそれぞれのテーブルのカラム club から
club_master を参照したいのですがどうしたらいいでしょうか?

select match,
&nbsp;&nbsp;&nbsp;&nbsp;match_data.club as opponent,
&nbsp;&nbsp;&nbsp;&nbsp;scores.club as scorer_club,
&nbsp;&nbsp;&nbsp;&nbsp;scorer
from scores join match_data using(match)

とした場合で、これに加えて club_master を join して、カラム opponent と scorer_club の値でそれぞれ
club_master を参照して以下のようにしたいのです。

match&nbsp;&nbsp;opponent&nbsp;&nbsp;scorer_club&nbsp;&nbsp;scorer
---------------------------------
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;山田
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;鈴木
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;横浜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名古屋&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;田中
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;東京&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名古屋&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;田中

サブクエリ使えよって話でしょうか?
0065642013/07/08(月) NY:AN:NY.ANID:???
うぎゃー、文字参照使えないのか(´・ω・`)
改めて書き込み直します。
0066NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
もうだいぶ前に2ちゃん全体で仕様変更になったはずだがw
0067642013/07/08(月) NY:AN:NY.ANID:???
改めてお聞きします。

sqlite 3.7.17

* table club_master

club  name
--------------
0   名古屋
1   東京
2   横浜
3   大阪

* table match_data

match club
--------------
1    2
2    3
3    1

* table scores

match club scorer
-------------------------
1    2   山田
1    2   鈴木
1    0   田中
3    0   田中

と3個のテーブルがあって、match_data と scores を結合してそれぞれのテーブルのカラム club から
club_master を参照したいのですがどうしたらいいでしょうか?

select match,
match_data.club as opponent,
scores.club as scorer_club,
scorer
from scores join match_data using(match)

とした場合で、これに加えて club_master を join して、カラム opponent と scorer_club の値でそれぞれ
club_master を参照して以下のようにしたいのです。

match opponent scorer_club scorer
------------------------------------
1   横浜   横浜     山田
1   横浜   横浜     鈴木
1   横浜   名古屋    田中
3   東京   名古屋    田中

サブクエリ使えよって話でしょうか?
0068NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>63
単純に>>62のような文を300回実行するという意味です

INDEXはkeyにのみ張ってます
他には張ってません
0069NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>63
こいつ馬鹿500万行って書いてあるのが読めないのか
0070NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>68
トランザクションにするとどうなる?
0071NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>67
select match,
a.name,
b.name,
scorer
from scores join match_data using(match)
join club_master a on match_data.club = a.club
join club_master b on scores.club = b.club

適当だけど、こんなんでいいんじゃない?
0072NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>68
その300回ってのは、同一のコネクションから順次実行するのか?
(最大300の)複数のコネクションが接続して更新するのか?
環境やスペック書いてないから何とも言えんが、更新そのものが遅いのか
それ以外が遅いのか切り分けろ

>>69
>>63の何がどう馬鹿なのか解説してくれ
俺には言ってる事に間違いがあるとは思えん、
0073NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>72
インデックスがついてなければ10秒で済むはずがないってことじゃない?
0074NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>71
おーおー、できましたできました!
どうもありがとうございました!!
0075632013/07/08(月) NY:AN:NY.ANID:???
>>69
1万行だろうと500万行だろうと、インデックスアクセスでは大差ないよ。

ちなみに、手元でPostgreSQLなんだけど、pgbenchで1000万行のテーブルを作って
300回更新する時間を計ったら、大体300ms位だったよ。
つまり、1000万行程度なら、ローカルでレコードを更新するのに1ms/rec程度なんだよ。

300回の更新で10秒かかるということは、33ms/recくらいかかってるということで、
更新対象のレコードを見つけるのにインデックスが使われているのなら、
・レコードがとても長い
・ネットワーク経由でDBアクセスをしていて、ネットワークが遅い
とかなのかな。
あるいは、実行しているPCのメモリがとても少ないとか、CPUがとても貧弱とか、ディスクがとても遅いとか?
0076NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>75
ついでにインデックスつけないで計測してくれ
0077NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>68
MySQLスレに行った方がいいんじゃない?
0078NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
つかってるDBMSとかわからんけど
毎回テーブルロックー開放してるとか?それでも遅い気はするが
0079NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
データサイズにも寄るけど、インデックスなかったら10秒程度で終わるわけない。
1回の更新で数百ms位かかると思う。500msだとして、*300で150秒。
なので、インデックスは使われていて、10秒というのが「最も高速に処理が終わる時間」に
比べて遅いのなら、何か別の理由だな。
ただし、「最も高速に処理が終わる時間」というのが10秒であるという可能性も捨てきれない。
0080NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>78
あ−、(connect→begintran->update->commit->close)*300ってやってて遅いのかも。
0081NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
テーブルサイズにもよるが
たとえば数字3項目で6バイトとして、500万件で30Mバイト
今時のサーバスペックならオンメモリで処理できる
インデックスなしでも数百msもかかるか?
0082NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
HDDからメモリ移すだけで1秒は掛かりそうだけど
0083NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>82
それははじめの1回だけで済む。あとの299回はオンメモリでいけるだろ
まあDBのバッファに入るか単にファイルキャッシュなのかとかによっても変わるが
0084622013/07/08(月) NY:AN:NY.ANID:???
エンジンはInnoDBです

>>62の10秒超というのは
↓のようなストアドプロシージャを実行した時に掛かった時間です
CREATE PROCEDURE test( IN x1 INT, IN x2 INT, IN x3 INT 〜〜 )
BEGIN
UPDATE テーブル SET a = a + 1 WHERE key = x1
UPDATE テーブル SET b = b + 1 WHERE key = x2
UPDATE テーブル SET a = a + 1 WHERE key = x3
〜〜
×300行

今自宅でローカルに同様の構成で10万行のテーブルを作って
100行でプロシージャを実行してみたらやはり3〜3.5秒程掛かります
試しに
UPDATE テーブル SET a = a + 1 WHERE key = 1
を1行だけ実行じてみたら
(クエリの実行時間 0.0474 秒)と出ました
phpmyadminから実行してるのですがこの表示が間違っているでしょうか
MYSQLのUPDATEが遅いというのは色々読んでわかったのですが
1行だけで50msというのは何か問題があると考えた方がいいのでしょうか
0085NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
>>83
文字列比較は0という計算ならな
0086NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
やっぱmysqlスレ行け
0087NAME IS NULL2013/07/08(月) NY:AN:NY.ANID:???
引数300個のプロシジャか
すげえとしか言いようがないな
0088NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
以下のようなテーブルがあります。

val  priority
---------------
123  2
456  1
456  2
789  1

ここで、val が重複した場合は priority の大きいほうを選ぶにはどうしたらいいでしょうか。
この場合なら
123  2
456  2
789  1
という結果がほしいです。

環境:postgresql 9.1
0089NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
select val, max(priority) from テーブル group by val
0090NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
>>88
select val, max(priority)
from table1
group by val
でいけました。ですよねー。
ほんとうは他にもカラムがあるから、こんな簡単じゃないけど。
0091NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
>>89
ありがとうございます
0092NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:v+VyPD99
質問をさせて頂きます。
よろしくお願いします。

・DBMS名とバージョン
Oracle 8.05

・テーブルデータ
No ,CTG,TIME
1 , A, 1h
2 , B, 2h
3 , C, 3h
4 , A, 1h
1 , C, 2h
1 , B, 3h

※CTGはC以降もあるが、全10個程度
レコード数は100程度

・欲しい結果
NoごとにCTG_A,B,CのTimeを集計(sum)した結果を
取得したいです

出力結果OKイメージ:
No,CTG_A,CTG_B,CTG_C
1 2, 3, 2
2 , 2,
3 , , 3

下記のような出力はNGです
NO CTG Time
1 , A, 2
1 , B, 3
1 , C, 2
2 , B, 2
3 , C, 3

前任者がなんの引き継ぎもないまま
いなくなってしまい前知識なしにSQLを
使用する立場となってしまいました
どうかご助力ください

情報が不足していれば追記します
0093NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
>>92
> 下記のような出力はNGです
の結果を出すクエリがかけるなら後は >>5
0094NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:v+VyPD99
>>93
素早い返答有難う御座います
Oracle 8ではcaseは全て使えないと
誤って覚えておりました
単純CaseはOracle8でも使えるのですね
本当に助かりました 
ありがとうございます
0095NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:???
Oracle 8.0(ほんとかよ)だとcase式はないからdecode式を使うんだろうな
http://www.oracle.com/technetwork/jp/content/general-092398-ja.html
0096NAME IS NULL2013/07/10(水) NY:AN:NY.ANID:v+VyPD99
>>95
情報提供有難う御座います
DBはOracle 8.0で間違いないです
前任者の方が10年以上一人で
保守・開発をされていたとのことで
更新などは全くされていないようです
0097NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
select id from ( (select id from table1) except (select id from table2) ) as t
というSQLがあります。このとき、「select id from table1」の部分を、リテラル値を埋め込んだ形にする方法があれば教えてください。
イメージとしては
select id from ( (81, 72, 47, 99) except (select id from table2) ) as t;
とか
select id from ( (select id from (81, 72, 47, 99)) except (select id from table2) ) as t;
みたいな感じです。
(PostgreSQL 9.x)
よろしくお願いします。
0098NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
リテラルをselectするのをunionでつなげれば出来るだろうけど
そのリテラルはどっからもってきたんだ?何がしたいのかまったくわからんな
0099NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
つ VALUES
http://www.postgresql.jp/document/9.2/html/sql-values.html
0100NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
VALUESってINSERTでよく使うけどSELECTでも使えたのかw
0101NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
というかSELECTと同等、か。
そういやINSERTでVALUESのとこにSELECT置くもんなあ
0102NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
VALUESで複数列書けるのは標準的なSQLなのか?
0103NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
複数列も複数行も少なくともSQL92ではすでに標準としてある
どのDBMSにいつ実装されたかまでは知らない
0104NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
insertで書くときは何も思わずに複数行、複数列指定に使われていたりする、そんなvaluesさん。
便利だよね。
0105NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
それでもOracleくんには頑なに受け入れてもらえない、それがvaluesちゃん
0106NAME IS NULL2013/07/17(水) NY:AN:NY.ANID:???
valuesで複数行書けるの標準SQLだとは思ってなかった
SQLServerは2008から出来るっぽい
0107NAME IS NULL2013/07/18(木) NY:AN:NY.ANID:???
>>99
まさにこれです!すてきすぎ!
99とPostgresqlにいいことがありますように。

>>101
その考え方いいですね。
0108NAME IS NULL2013/07/18(木) NY:AN:NY.ANID:???
>>107
その考え方いいですねって、素敵過ぎると思ったマニュアルを読まなかったのか?
0109NAME IS NULL2013/07/18(木) NY:AN:NY.ANID:???
そのマニュアル、翻訳間違ってるな。

> ORDER BY、LIMIT(、これと等価なFETCH FIRST)そしてOFFSET句でVALUESコマンドを使用することができます。

〜OFFSET句「を」VALUESコマンド「で」使用することができます。
だろう。
0110NAME IS NULL2013/07/19(金) NY:AN:NY.ANID:???
いや、あってるだろ
0111NAME IS NULL2013/07/19(金) NY:AN:NY.ANID:???
そのマニュアルとやらがどれか知らんが、ここで言ってもしょうがないだろうに
0112NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
【質問テンプレ】
MySQL5.5

key   a   b   c
--------------------
1    3   3   2
1    4   1   1
1    5   2   2
1    2   3   2
2    1   0   5
2    5   0   2
2    2   3   2
2    1   0   0
3    1   2   2
3    2   3   0


上記のような2000万行程度のテーブルに↓のようなSELECT文を投げたいのですが

SELECT abs(a + b - c) AS abs_hoge, key FROM table WHERE key = 2 ORDER BY abs_hoge ASC LIMIT 1;

大体20〜40秒程度の時間が掛かります
インデックスはkeyにのみ張ってます
一つのkeyの値につき2000レコード程あるので
まず2000行フェッチされた後、a+b-cの絶対値でfile_sortされてるみたいなのですが

どうにかして処理を速くできないでしょうか
実際はa,b,cだけでなくd,f 〜 y,zくらいまでカラムがあり
場合によって abs(a - f - k)のように文を変えるので複合インデックスも試そうとしましたが難しいです

よろしくお願いします
0113NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
order by で limit 1ってmin とか使えないの?
0114NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
は?
0115NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
>>112
2000行フェッチするまでが遅いの?それともその後?
感覚的には後者ってことはなさそうな気がするんだけど
0116NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
>>112
パフォーマンスはまず実行計画見てみないと話にならん

レコードサイズとかにもよるけど、2000行の演算とソートが20秒もかかるとは思えん
となると遅いのはSELECTそのものの可能性が高い
keyにインデックスあるなら、これ以上は一般論では無理
MySQLのスレいって聞け
0117NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:vvTOE8eP
その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。
その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。
その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。
その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。その目気色悪すぎこっち見んな死ね。
01181122013/07/21(日) NY:AN:NY.ANID:???
フェッチ後が遅いようです
100万行程度テーブルなら2000行程度のfilesortも一瞬なのですが
2000万行でやるとなぜか一気に時間が増えてしまいます

mysqlスレで聞いてみます
ありがとうございました
0119NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:+gxDS+8E
【質問テンプレ】
・DBMS名とバージョン: MySQL ver5.0.95

PHPと組み合わせて使っているのですが、PDOステートメントを使って

foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
 $rows[$row['data1'] = array($row['data2']);
}
という感じに値を$rowsという配列に入れていってます。
このdata1はカラム名です。data2がNULLになってしまってるのですが
data2というのはサブクエリでとってきた値なのです。
このサブクエリにキー名のようなものをつけることは出来ないのですか?

foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo var_dump($row);
}

で中身を見ると、
array(3) {
["data1"]=>
string(5) "wtb_3"
["(select data2 from 〜〜〜〜)"]=>
NULL
}

こんな感じで入ってます。
サブクエリの結果を表示するには$row['(select data2 from 〜〜〜〜)']とする以外方法はないのでしょうか。
サブクエリ文自体を変数に入れればスッキリはしますが、他に方法があれば知りたいです。
宜しく御願いします。
01201192013/07/21(日) NY:AN:NY.ANID:+gxDS+8E
あ、ごめんなさい
["(select data2 from 〜〜〜〜)"]=>
NULL
ではなく、この場合はちゃんと欲しいデータが入ってます。

foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
 $rows[$row['data1'] = array($row['data2']);
}
echo var_dump($rows);
としたときに
["data2"]=>NULLとなるのでした。
0121NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
スレ違い。
0122NAME IS NULL2013/07/21(日) NY:AN:NY.ANID:???
・DBMS名とバージョン:MySQL5.5

SELECT IF(DATEDIFF(NOW(), created)=0, value, 0) FROM TBL1;
このIF文でcreatedという時間データと現在時刻を比較し、1日以上経っているか、それともcreatedと同じ日かという判別をしているのですが
もし1日以上経っていたら、同じ命令文の中でvalueを0にアップデートする方法が知りたいです。可能なら方法をご教授下さい。
0123NAME IS NULL2013/07/22(月) NY:AN:NY.ANID:???
何だよ命令文って。更新したいならUpdateしろよ。
0124NAME IS NULL2013/07/22(月) NY:AN:NY.ANID:???
>>120
よくわからんけど構文エラーがあるように見える。
それで動くのかな。

>>122
update TBL1 set value = 0 where datediff(now(), created) = 0;
とか?
0125NAME IS NULL2013/07/22(月) NY:AN:NY.ANID:???
sql server 2008とADO.NETを使っています
クライアントのアプリからストアドプロシージャに配列を渡すにはどうすれば良いのでしょうか?
0126NAME IS NULL2013/07/22(月) NY:AN:NY.ANID:???
スレ違いです。
0127NAME IS NULL2013/07/23(火) NY:AN:NY.ANID:???
なかっち 動画
http://www.youtube.com/watch?v=z2qK2lhk9O0s



みんなで選ぶニコ生重大事件 2012
http://vote1.fc2.com/browse/16615334/2/
2012年 ニコ生MVP
http://blog.with2.net/vote/?m=va&;id=103374&bm=
2012年ニコ生事件簿ベスト10
http://niconama.doorblog.jp/archives/21097592.html


生放送の配信者がFME切り忘れプライベートを晒す羽目に 放送後に取った行動とは?
http://getnews.jp/archives/227112
FME切り忘れた生主が放送終了後、驚愕の行動
http://niconama.doorblog.jp/archives/9369466.html
台湾誌
http://www.ettoday.net/news/20120625/64810.htm
0128NAME IS NULL2013/07/23(火) NY:AN:NY.ANID:???
お世話になります。

複合インデックスの項目を歯抜けにしても効果的にインデックスを効かせるSQLの書き方教えていただけませんでしょうか。

1テーブルのWhere句に入る項目数は最大30位あるんですけど、全部検索条件に指定してもらえるわけもなく困ってます。
『数値型検索列>=0』のようなもので埋めればいいのですか?

DBはSymfowareV10です。

ご教授の程、よろしくお願いします。
0129NAME IS NULL2013/07/24(水) NY:AN:NY.ANID:???
>>128
特定のDBMSのオプティマイザ動作をここで聞かれてもなぁ
専用スレ行け。あるのかないのかしらんが
0130NAME IS NULL2013/07/24(水) NY:AN:NY.ANID:???
こっちで答えて貰ったから、ここはもういいです

DB設計を語るスレ 6
http://toro.2ch.net/test/read.cgi/db/1341061787/300
0131NAME IS NULL2013/07/24(水) NY:AN:NY.ANID:???
感じわる
0132NAME IS NULL2013/07/24(水) NY:AN:NY.ANID:???
みりゃわかるがまともな回答はついてない。
マルチポストを非難する煽りレスかと。
0133NAME IS NULL2013/07/31(水) NY:AN:NY.ANID:???
SQL server2012 expressですが
指定したテーブル内の項目名を全て取得するにはどうすれば良いでしょうか?
Googleで検索すると'syscolumns'を検索するば良いみたいですが
それっぽい文字列が見つかりません。
0134NAME IS NULL2013/07/31(水) NY:AN:NY.ANID:???
このスレ的には、INFORMATION_SCHEMA.COLUMNS かな。
0135NAME IS NULL2013/07/31(水) NY:AN:NY.ANID:???
>>133ですが
USEでデータベース指定してませんでした。
>>134
ありがとうございました。
0136NAME IS NULL2013/08/01(木) NY:AN:NY.ANID:???
sqlsrver2008R2なんだが、updateクエリを使って列のデータ型を変更する方法を教えて欲しい。
先輩が言うにはやれるらしいが、調べてもalter tableを使う方法しか出てこない。
0137NAME IS NULL2013/08/01(木) NY:AN:NY.ANID:???
無理。
0138NAME IS NULL2013/08/02(金) NY:AN:NY.ANID:???
その先輩をゴーモンして口を割らせろ
0139NAME IS NULL2013/08/02(金) NY:AN:NY.ANID:???
システムテーブル書き換えるんじゃね
0140NAME IS NULL2013/08/02(金) NY:AN:NY.ANID:???
それならできそうw
0141NAME IS NULL2013/08/02(金) NY:AN:NY.ANID:???
凌遅刑
0142NAME IS NULL2013/08/04(日) NY:AN:NY.ANID:???
update table1 set col1 = 'value1' where id = 111;
update table1 set col1 = 'value2' where id = 222;
update table1 set col1 = 'value3' where id = 333;

これを1文でスマートに実行するにはどうしたらいいですか。
以下のようなのを考えたけど、どう考えてもスマートではありません。

update table1
set col1 = case
     when id = 111 then 'value1'
     when id = 222 then 'value2'
     when id = 333 then 'value3'
    end
where id in (111, 222, 333);
0143NAME IS NULL2013/08/05(月) NY:AN:NY.ANID:???
update fromを使ったところでスマートかというとな。
求めてるのって、1文かどうかが重要なんじゃないの。
0144NAME IS NULL2013/08/08(木) NY:AN:NY.ANID:???
update table1 set col1='value'||substr(to_char(id),1,1);
0145NAME IS NULL2013/08/08(木) NY:AN:NY.ANID:???
全件ヒットしちゃうじゃん
0146NAME IS NULL2013/08/08(木) NY:AN:NY.ANID:???
問題はそこじゃないだろ
0147NAME IS NULL2013/08/08(木) NY:AN:NY.ANID:???
自分でいうのもなんだけど。
0148NAME IS NULL2013/08/09(金) NY:AN:NY.ANID:???
1文かどうかなんて重要じゃないと思うが
そもそも1文で処理する必要性がわからん
0149NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
排他制御がしやすい
0150NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
複文だとしにくいって言ってる?
0151NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
うん。
ちょっとだけだけど。
0152NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
今回は違うけど、id を書き換えるような場合は1行でやらないと
結果が変わってくる
0153NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
複数行ならtransaction使うだろ。
結果が変わって困るというなら設計がおかしい。
0154NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
transactionフリーにすると後々様々なメリットを享受できる
0155NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
トランザクションを理解できなかった奴がよくこういうことを言ったりする
0156NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
トランザクションを理解出来ないやつほど無駄にトランザクションを使う
0157NAME IS NULL2013/08/10(土) NY:AN:NY.ANID:???
一文のSQLはトランザクションじゃないと誤解するのも初心者にはありがち
0158NAME IS NULL2013/08/15(木) NY:AN:NY.ANID:???
俺も昔はそうだった
0159NAME IS NULL2013/08/18(日) NY:AN:NY.ANID:???
SQL Server 2008

日付と時刻とを date型とtime型と、別々に分離されているものを
datetime型に変換するにはどうしたらいいのでしょうか。

declare @date as date;
declare @time as time;
declare @datetime as datetime;

set @datetime = @date + @time;   ← かなぁと思ったら、NGでした
0160NAME IS NULL2013/08/18(日) NY:AN:NY.ANID:???
文字列として組み立てて変換すればいいんじゃね?
0161NAME IS NULL2013/08/18(日) NY:AN:NY.ANID:???
>>159
型が違うんだからまずdatetimeにしてから足せよ
set @datetime = cast(@date as datetime) + cast(@time as datetime);

型が違うものの演算とか代入とか、型の優先順位や暗黙の変換によって結果が決まる奴は
よっぼど自信があっても使わん方が良いぞ
01621592013/08/18(日) NY:AN:NY.ANID:???
cast する方法でバッチリ出来ました
どうもありがとうございました
0163NAME IS NULL2013/08/21(水) NY:AN:NY.ANID:???
ポケモンマスターとはポケットモンスターのマスタテーブルであると仮定して
サトシはどのようなクエリ言語でこれを参照しているのでしょうか
0164NAME IS NULL2013/08/21(水) NY:AN:NY.ANID:???
構文は○○ゲットだぜだけで大丈夫よ。初心者にもオススメ。
0165NAME IS NULL2013/08/21(水) NY:AN:NY.ANID:???
ピカ厨
0166NAME IS NULL2013/08/26(月) NY:AN:NY.ANID:ar04zqCb
・DBMS名とバージョン: MySQL 5.0.92

・テーブルデータ     ・欲しい結果
ID |DOMAIN        DOMAIN
- | -----------    -----------
1 |foo.hoge.ne.jp     hoge.ne.jp
2 |bar.fuga.ne.jp →  fuga.ne.jp
3 |qux.piyo.co.jp     piyo.co.jp

テーブル構造
ID integer primary key auto_increment
DOMAIN varchar(255) not null
・説明
DOMAINを like '%.__,jp'で抽出し、
DOMAINのうち右から3番目の「.」以降の文字を、「.」が2個以下の場合全文を列挙したい

よろしくお願いします!
0167NAME IS NULL2013/08/26(月) NY:AN:NY.ANID:???
MySQLならこういう関数があるらしい
http://dev.mysql.com/doc/refman/5.1/ja/string-functions.html#function_substring-index
0168NAME IS NULL2013/08/27(火) NY:AN:NY.ANID:???
ドメイン名の取り扱いは悩ましいなぁ
FQDNじゃなくてサブドメイン単位のデータを格納するべきなんじゃないかと思ってみたり
しかし取り扱いを考えるとFQDNの文字列で持ちたい
ビューでなんとかすべきか、正規化くずすべきか
0169NAME IS NULL2013/08/27(火) NY:AN:NY.ANID:???
ドメイン名自体を管理するならともかく、単に覚えておくだけなら、全部だな。
0170NAME IS NULL2013/08/28(水) NY:AN:NY.ANID:???
FQDNとドメインを両方持ったところで、FQDN→ドメインという関係が存在するだけで
正規化どうこうの問題にはならんだろう。
というか逆に、部分文字列の抽出とか文字列の構造に依存した処理を前提とした
DB設計ってのは避けるべきだな。
0171NAME IS NULL2013/08/31(土) NY:AN:NY.ANID:???
PHP5+MySQL 5.1.69を使っているんだけど…

id user tag
1 56 hoge
2 24 piyo
3 56 foo
4 12 bar
5 1 hoge
6 2 foo
...続く


って感じのテーブル…要するにuserひとつにタグが最大で8個ぐらい付いているっていうのがある
userとtagの組み合わせはユニークになってる(ひとつのuserが同じtagはつけられない)

これで例えばhogeのtagがついているuserは他にどんなtagがついているか知りたい
それがグループ、オーダーで登録数順になった形式が欲しいんだけど

こんなん

tag sum
foo 26
bar 12
pyo 5
...

簡単かなって思ったけど全然思いつかない
誰かご教授いただけると有難い
0172NAME IS NULL2013/08/31(土) NY:AN:NY.ANID:???
tag 毎の登録数が知りたいの?

であれば、select tag, count(*) from table group by tag order by count(*) desc; でいいと思う。

> これで例えばhogeのtagがついているuserは他にどんなtagがついているか知りたい

にどう繋がるかはよくわからんけど。
0173NAME IS NULL2013/08/31(土) NY:AN:NY.ANID:???
いやごめんちょっと違う

id user tag
1 56 hoge
2 24 piyo
3 56 foo
4 12 bar
5 1 hoge
6 2 foo
...

って状態で格納されてるけど

要するに
user tag
56 hoge, piyo, foo
1 piyo, bar, hage
23 bar, foo, piyo
4 hage, bar
...

ってphpで出力して使ってる
これで
「hogeを登録している人は○○も登録していますよ」って感じにしたいから
hogeを登録している人が他に登録しているtagを多い順に集計したい
上の4つだと例えばfooを登録している人は…ってなると


tag sum
piyo 2
bar 1
hoge 1

ってなるようにしたいんだ
0174NAME IS NULL2013/09/01(日) 07:33:56.65ID:???
ああそういうことか、ではこうかな?
※ 手元に環境ないので未検証

select t2.tag as tag, count(*) as sum from table t1 inner join table t2 on t1.id = t2.id where t1.tag = 'foo' and t2.tag <> 'foo' group by t2.tag order by count(*) desc;
0175NAME IS NULL2013/09/01(日) 11:49:31.17ID:???
それじゃ無理な気がする。
0176NAME IS NULL2013/09/01(日) 11:55:38.08ID:???
1. fooを登録してるユーザー一覧
2. 1. のユーザー達が登録してるtag一覧
3. 2. のtag一覧からfooを除いたものをGroup By、でいいのかな。
0177NAME IS NULL2013/09/01(日) 12:38:15.81ID:???
>>171
仕事?
趣味?
まさか仕事じゃないよね?
この程度が解決できないレベルでお金もらえるはずがないよね?
0178NAME IS NULL2013/09/01(日) 13:31:41.83ID:???
select tag, count(tag) as sum
from table
where
tag <> 'hoge' and
user in (select user from table where tag = 'hoge')
group by tag
order by count(tag) desc;

こんなか?
0179NAME IS NULL2013/09/01(日) 13:35:47.20ID:???
>>173
そこに書いてあるやつ、上と下でデータ違うじゃねえか
ちゃんと合わせとけよ

select tag,count(*) from テーブル
where user in (select user from テーブル where tag='foo') and tag<>'foo'
group by tag order by count(*) desc
たぶんこんな感じ
0180NAME IS NULL2013/09/01(日) 13:49:49.63ID:???
>>173

SELECT t2.tag,COUNT(1) FROM tables AS t1 INNER JOIN tables AS t2 USING(user)
WHERE t1.tag != t2.tag AND t1.tag='foo' GROUP BY t2.tag ORDER BY t2.tag DESC;

こんな感じ?
01811802013/09/01(日) 13:57:25.96ID:???
>>179
すまん、かぶった
01821712013/09/01(日) 20:58:36.70ID:M1fx7C6f
うおーありがたい!
どれも上手くいったよ。
どれ使えばいいか迷うなw

>177
もちろん趣味
0183NAME IS NULL2013/09/04(水) 16:11:46.28ID:???
質問なのですが、レコードが最後に読み出された時間は自分でフィルード作って記録する必要がありますか?
0184NAME IS NULL2013/09/04(水) 16:44:48.97ID:???
一般的には自分で管理しないと無理
selectにトリガ張れるDBMSは聞いたことないけど、監査機能で実現できるかもしれん
0185NAME IS NULL2013/09/04(水) 17:04:33.57ID:???
>>184
ありがとうございました!
0186NAME IS NULL2013/09/05(木) 19:02:17.17ID:???
mysqlでのソートについてですが
ソート対象のカラム内にa,b,c,dとはじまる文字列あった場合に
最初をbとしてその後にa,c,dなどのようにすることはできるのでしょうか
0187NAME IS NULL2013/09/05(木) 21:53:39.74ID:???
>>186
case文でソート用の列をつくればいいんじゃない?
0188NAME IS NULL2013/09/05(木) 22:31:34.39ID:???
select * from table order by field(left(col,1),'b','a','c','d');
0189NAME IS NULL2013/09/08(日) 10:23:49.56ID:???
order by には複数条件書けるから
col = b desc, col
ってやればbのときTRUEで最優先、残りはcol順になる
0190NAME IS NULL2013/09/08(日) 10:25:05.03ID:???
おっと、bで始まる、か
まあ>>188の例も見ればわかるよね
0191NAME IS NULL2013/09/08(日) 11:18:00.36ID:???
>>189
アホはレスしなきゃいいのに...
0192NAME IS NULL2013/09/10(火) 13:32:46.41ID:???
mysqlでの質問になります
あるカラムの同一データごとからランダムに一つずつデータを抽出することは可能でしょうか。
0193NAME IS NULL2013/09/10(火) 15:31:34.22ID:u4dYxzY0
ランダムにってどういうこと?
0194NAME IS NULL2013/09/10(火) 15:38:21.21ID:y1marFjb
>>193
説明不足ですいません。
以下のようなカラムからカラムAの1から一つ、カラムAの2から一つというように取得したいんです・・・
カラムA カラムB
1    a
1    b
1    c
2    a
2    b
2    c
3    a
3    b
3    c
0195NAME IS NULL2013/09/10(火) 16:30:03.58ID:???
適当

select * from table group by カラムA;
0196NAME IS NULL2013/09/10(火) 17:01:22.49ID:???
>>195
いくらなんでもそれは適当すぎる

>>194
select
カラムA,
(select カラムB from テーブル where カラムA=t1.カラムA order by rand() limit 1);
from
(select カラムA from テーブル group by カラムA) t1
とかじゃね、mysql手元にないから知らんけど
0197NAME IS NULL2013/09/10(火) 17:02:29.23ID:???
あ、いらんとこにセミコロン入ってる
0198NAME IS NULL2013/09/10(火) 20:43:12.75ID:???
標準SQLだとだめ。MySQLだといいみたい

>GROUP BY 部から省略したカラムがグループ内で一定していない場合は、この機能を 使用しないで ください。
>サーバはいかなる値もグループから自由に戻すことができ、すべての値が同じでない限り、結果は不確定です。

http://dev.mysql.com/doc/refman/5.1/ja/group-by-hidden-fields.html
0199NAME IS NULL2013/09/11(水) 05:35:45.51ID:???
m(._.)mド初心者です。 MySQL5.5

テーブル名:売上計 
魚 数
はまち 10
かつお 10
いわし 20

テーブル名:売上月次テーブル
魚 数
はまち 1
かつお 0
いわし 5

の2つのテーブルがあるときに、

売上計  に月次のレコードの数をすべて足して、

テーブル名:売上計
魚 数
はまち 11
かつお 10
いわし 25

としたいです。
どうすればよいでしょうか。

UPDATE 売上計 SET 売上計.数 = 売上計.数 + 売上月次.数 WHERE 売上計.魚 = 売上月次.魚 ;

としましたが#1054 エラー UNKNOWN COLUMN 売上計.魚 と出ます。
0200NAME IS NULL2013/09/11(水) 12:01:51.44ID:???
UPDATE 売上計,売上月次テーブル SET 売上計.数 = 売上計.数 + 売上月次テーブル.数 WHERE 売上計.魚 = 売上月次テーブル.魚 ;
0201NAME IS NULL2013/09/11(水) 15:38:36.92ID:???
ありがとうございます。
UPDATEで 売上計 , 売上月次
とするんですね。できました。

レコードの値を参照するだけで更新しないテーブルでも、
クエリで触れるテーブルについては、UPDATEで書くんですか。
0202NAME IS NULL2013/09/11(水) 22:06:51.44ID:???
SELECTで足せばいいだろう、常に使うならVIEW作ればいい
0203NAME IS NULL2013/09/14(土) 16:59:52.45ID:???
union all してsumればいいんじゃない?
0204NAME IS NULL2013/09/16(月) 00:33:09.89ID:???
SQL SERVER 2008 R2 - Microsoft SQL Server Management Studio 10.50.2550.0
の質問なのですが、SQL文発行時等のエラーメッセージが日本語にならないのですがどこに設定があるのでしょう
メニューバーその他設定などは全て日本語で、DBの照合順序などもJapanese_CI_ASになっているのですが・・・
別環境では問題なく全て日本語で出るのですが、新しく作った環境では上記のような状態になってしまいます
とても初歩的で申し訳ありませんがご教授お願い致します
0205NAME IS NULL2013/09/19(木) 21:48:14.24ID:bkFzQmtP
各キーのトップ5を抽出するSQLを教えてください。
0206NAME IS NULL2013/09/20(金) 10:06:54.20ID:cIRAGCg1
SELECT TOP 5
0207NAME IS NULL2013/09/23(月) 15:28:21.90ID:Fbkd2zVx
id name num とあって

id: 1 2 3 4 5 6 7 ...
name: tarou hanako tarou tarou tarou hanako tarou
num

となっています。

update table set num = 1 where name = tarou

とすると、tarou全てが1になります。
ですが、idが最大のtarouだけを1にしたいんです。

update table set num = 1 where name = tarou and id = 7

とやれば7のtarouだけを更新することができますが、常に最大のものだけを更新したいので
これではできません。
簡単にできそうに見えるんですがやり方が分かりません。
やり方教えてください!ちなみにsqliteを使ってます。
0208NAME IS NULL2013/09/23(月) 15:36:05.62ID:???
update table set num = 1 where id = (select max(id) from table where name = 'tarou')
とか?
0209NAME IS NULL2013/09/23(月) 15:41:22.04ID:Fbkd2zVx
ありがとーーーーーー

できました。
0210NAME IS NULL2013/09/30(月) 18:54:54.29ID:???
MySQL5.5です。

テーブル構成等

CREATE TABLE `tab` (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
status VARCHAR(12),
created DATE
);

INSERT INTO tab (id, status, created) VALUES
(0,'ENABLE','2013-01-01'),
(0,'DISABLE','2013-01-02'),
(0,'ENABLE','2013-01-03'),
(0,'DISABLE','2013-01-03');

欲しい結果

CREATED     ENABLED      DISABLED
2013-01-01    1           0
2013-01-02    0           1
2013-01-03    1           1

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

created毎にGROUP BYしてENABLEDとDISABLEDがそれぞれ何件ずつ登録があったかを
SELECT一発で調べたいのですが、どうもうまくSQL文をイメージすることができません。
お手数ですがお願いできませんでしょうか。

よろしくお願いいたします。
0211NAME IS NULL2013/09/30(月) 19:17:31.90ID:???
>>210
>>5
02122102013/09/30(月) 19:34:12.24ID:???
Nooo
すみません。
ありがとうございます。
0213NAME IS NULL2013/10/01(火) 14:44:38.86ID:???
SQLiteを使っています。
同時に更新する可能性のあるデータベースで、
update文を実行したとき、すでに削除されているケースもあり、
その場合エラーをキャッチしプログラム側で例外処理するようにできています。
update文は複数に対して行うことがあります。
そのため1つずつupdate文を実行するのですが、例外処理に移行した場合、
無視して継続というようなことが出来ないため、
トランザクション処理の中で行い、正常に終わってる分も含めてロールバックすることになります。
そこでまず最初にselectして、update対象があるかを確認する方法が考えられますが、
selectしたカラムが存在していたら、update文を実行するみたいな処理はどのように書けばいいでしょうか?
1回のSQLでは無理でしょうか?
0214NAME IS NULL2013/10/01(火) 15:48:22.30ID:???
update hoge set a='なんたら' where exists (select 1 from hoge h1 where h1.b = 'キー')
SQLiteはupdate側に別名使えないらしいが今環境ないから不明
02152132013/10/01(火) 21:19:17.09ID:???
>>214
どうもありがとうございます。

id name emailというuserテーブルとして、

update user set email='[email protected]' where exists (select 1 from user h1 where h1.id = 3)

という感じでやってみたところ、正常に実行はできたのですが、
全てのカラムのemailが[email protected]になりました。
もう少しいじればできそうな気がするので、頑張ってみます。
02162132013/10/01(火) 21:26:48.58ID:???
update user set email='a@examplecom' where id = (select id from user where id = 3)

正しい文なのかどうかはわかりませんが、こんな感じで行けました。
どうもありがとうございました。
0217NAME IS NULL2013/10/01(火) 21:55:00.71ID:???
update user set email='a@examplecom' where id = 3;
これじゃだめなのか?
id = 3が複数あれば、それ全部更新する。
無ければ、何もしないはず。
02182132013/10/01(火) 22:02:06.34ID:???
>>217
すみませんおっしゃるとおりでした。
firefoxアドオンのSQLite Managerを使っていますが、
update文もdelete文も、存在しないidに対してやっても問題ありませんでした。
エラーが出るものとばかり思い込んでいました。
0219NAME IS NULL2013/10/02(水) 14:50:47.01ID:eTCIsFeO
初歩的な質問ですみません。UPDATEでINは通常使えるのでしょうか?
IDが5,6,7の人のAGEを20にする
UPDATE MAN SET AGE = 20 WHERE ID IN (5,6,7);
日頃使っているDBでは通るのですが、一般的に使えるものがどうか知りたいです。
INの説明文・例文が、SELECTばかりなものですから・・・。
0220NAME IS NULL2013/10/02(水) 15:00:39.32ID:???
SQL92 defines a different syntax for positioned UPDATE statement:

SQL92 では位置付け型 UPDATE 文用の異なる構文を定義しています。
UPDATE table SET column = expression [, ...]
WHERE CURRENT OF cursor

http://www.postgresql.jp/document/pg653doc/ej/user/sql-update.htm

よく判りまへんw ↑を見る限りSQL92をサポートしてるんだったら大丈夫なんじゃ?
0221NAME IS NULL2013/10/02(水) 20:55:12.91ID:???
>>219
通常ってのがどんなものを想定してるのか分からんが
WHEREにIN使えないDBMSの方が少ないんじゃないかね
02222192013/10/03(木) 09:00:41.99ID:???
>>220
その構文説明はちょっと違うと思うのですが、リンク先でpostgreSQLは
使えることがわかりました。
>>221
なんていいましたっけDDTとDDA?参照と更新にかかわらず、WHEREは
WHEREちゅうことですね。

使えると思ってよさげですね。更新とか削除とか、いいのかなーとか
思いながら使ってたんで、安心しました。ありがとうございました。
0223NAME IS NULL2013/10/03(木) 17:59:44.54ID:???
MYSQL5.5です。教えていただけると助かります。

テーブル名:子供
子供番号、名前
1,たろう
2,はなこ
3,じろう

テーブル名:きらい
子供番号,食べ物
1,にんじん
1,ピーマン
2,にんじん
2,トマト
3,ピーマン

この二つを結合して、にんじんトマトどちらも嫌いな子供を出すことはできるのでしょうか。

select * from 子供 left join きらいなもの on 子供.子供番号 where きらい.食べ物 = にんじん and きらい.食べ物 = トマト
これだとだめですよね。
02242232013/10/03(木) 18:08:33.54ID:???
すみません。>>6 でできました。
重ねてで申し訳ないのですが、
たとえば、食べ物カラムに入る値をスペース区切りにして、
テーブル名:きらい
子供番号,食べ物
1,にんじん ピーマン
2,にんじん トマト
3,ピーマン

select * from 子供 left join きらいなもの on 子供.子供番号 where きらい.食べ物 like %にんじん% and きらい.食べ物 like %トマト%
ってやるとトマトもピーマンもきらいな子供を出せると思うのですが、これはダメなんですよね。

第一正規形じゃないのはわかるのですが、なぜだめなんでしょう。
0225NAME IS NULL2013/10/03(木) 18:22:59.21ID:???
>>223
にんじんが嫌い、かつ、トマトが嫌い って条件なんだから、きらいテーブルににんじんが存在する、かつ、きらいテーブルにトマトが存在する
素直にSQL書けば
select * from 子供 t
where exists (select * from きらい where きらい.子供番号=t.子供番号 and きらい.食べ物='にんじん')
and exists (select * from きらい where きらい.子供番号=t.子供番号 and きらい.食べ物='トマト')
とか
select * from 子供
where 子供番号 in (select 子供番号 from きらい where 食べ物='にんじん')
and 子供番号 in (select 子供番号 from きらい where 食べ物='トマト')
とか

結合でやりたいなら
select 子供.* from 子供
join きらい t1 on t1.子供番号=子供.子供番号 and t1.食べ物='にんじん'
join きらい t2 on t2.子供番号=子供.子供番号 and t2.食べ物='トマト'
とか

MySQLで動くかどうかはしらんが
0226NAME IS NULL2013/10/03(木) 18:25:19.60ID:???
>>224
それ赤ピーマンあったらどうなるの?
とまとがひらがなだったらどうなるの?
02272232013/10/03(木) 18:48:21.43ID:???
>>225
なるほど!そういう書き方もあるんですね。

>>226
確かにlikeだと別のものも出てしまいます!

すごい目から鱗です。ありがとうございます。


さらに質問させてください。

嫌いテーブルと同じ構造で、好きテーブルがあったとして、
--------
名前:はなこ 嫌いなもの:にんじん,トマト 好きなもの:オムライス,肉まん,焼き鳥
-------
のように子供の情報をずらっと表示するときは、1度のSQL文で抽出できるのでしょうか。
3つのテーブルを外部結合するのかなと思ったのですが、

はなこ,にんじん,オムライス
はなこ,にんじん,肉まん
はなこ,にんじん,焼き鳥
・・・
のようになってしまいます。

それとも該当する子供だけ先に抽出して、嫌いなもの、好きなものを子供ごとに抽出するのでしょうか。
0228NAME IS NULL2013/10/03(木) 20:11:16.58ID:???
>>227
group_concat
で検索。
0229NAME IS NULL2013/10/03(木) 21:21:32.45ID:???
>>227
まず良くある質問を見ろ
まあ、その手はホストアプリでやるのが無難
02302232013/10/03(木) 22:54:49.24ID:???
>>228
group_concat すごい便利ですね。ありがとうございます。

>>229
PHPで取得したデータを展開するつもりです。
複数のテーブルからデータをひっぱってきて、前述の
名前:はなこ ・・・ 焼き鳥 のようにクライアント側で表示しようとする場合の
一般なやり方というか、どこまでをSQLで担当するのかがわからないのです。

一度で全部のデータをSQLで取得してPHPで表示するのか、
それとも、子供、好き、嫌いそれぞれを別個に取得してPHP側でうまいこと表示するのか。
例に挙げたものよりも列もテーブル数もすごく多くなった場合、どうしたらよいのか
わからないのです。
0231NAME IS NULL2013/10/04(金) 00:24:00.30ID:???
>>230
>テーブル数もすごく多くなった場合

ここで現在のテーブル設計がどうなってるか見なおしてもらえw

DB設計を語るスレ 6
http://toro.2ch.net/test/read.cgi/db/1341061787/l50
02322232013/10/04(金) 20:21:36.78ID:???
>>231
誘導までしていただいてすみません。

そちらのスレも読んでみましたが、いろいろと奥深い世界ですね!
もう少し自分で調べてみてから設計スレで質問してみます。

レスくれた方々、ありがとうございました!
0233NAME IS NULL2013/10/08(火) 19:31:07.14ID:q6jVV2Df
ショッピングカートに商品を追加するとき
カートのテーブルが itemID, userID, item_num って構成だったとして
同一商品を時間を置いて2度以上カートに追加する状況が発生した場合の処理がわかりません

同じitemIDの個数(item_num)を+1するupdateするとしたら
最初にitemIDをキーにselectを実行して存在すれば+1のupdateという流れ以外無理でしょうか
(一つのクエリで実現できないものかな、と)

それとも、同じitemIDの「行」をupdateするという考え自体捨てて
どんどん新規にinsertして行った方が良いんでしょうか。

一般的にはどうだ、というものがあれば聞かせてくれると嬉しいです
よろしくお願いします
0234NAME IS NULL2013/10/08(火) 20:45:56.32ID:???
>>233
業務(仕事)でやるなら金払えって
0235NAME IS NULL2013/10/08(火) 20:50:56.53ID:???
SQL以前の話なんだが、何がしたいか分からん
要件がわからん
要件も決まってないのにテーブル設計してるのもわからん

SQLの話なら、
updateしたければすればいいし、insertしたければすればいい
どちらかしたいというなら、mergeとかupsertとか調べろ
0236NAME IS NULL2013/10/08(火) 21:21:25.21ID:???
>>233
そもそもカートにDB使わない。
cookieに入れて処理。
0237NAME IS NULL2013/10/09(水) 00:34:51.85ID:???
処理速度の部分でたぶんものすごい基礎的なところなんですけど
テーブルA,Bで
A UserID 100件
B UserID , Userの所持品(一人100個) 、各所持品の値段

とあった場合に
両方を結合してからUserIDでGroupするのと
Bをサブクエリで先にGroupしたものを結合するのだとどのような効果になるのでしょうか
0238NAME IS NULL2013/10/09(水) 02:37:32.45ID:???
>>237
実装に依存する話なのでこのスレはふさわしくない
使っているDBMSのスレで聞こう
0239NAME IS NULL2013/10/09(水) 03:04:48.40ID:UYLm0PgE
ベンチマークとって速いほうにすりゃいいじゃん
って思ったけどもっと仕様的な事が知りたいのかな?
0240NAME IS NULL2013/10/09(水) 04:11:51.88ID:???
大前提として、SQLは書いたとおりに実行されるとは限らない
SQLだけをみて、どう実行されるかは分かりません
これ以上は使ってるDBMSのスレで聞いて下さい
0241NAME IS NULL2013/10/10(木) 00:20:44.05ID:???
SQL server 2008R2です。
補完方法について教えてください。

下記のようなテーブルデータがある場合VAL1=NULLの行に対して、
同じCODEのうち最も日付が近い(後ろ方向に)VAL1がNULLでない値で補完をしたいのです。

テーブルデータ
DATE(int) CODE(varchar) VAL1(int)
201301 AAAB 12
201302 AAAB NULL
201303 AAAB NULL
201304 AAAB 51
201301 AAAC 23
201302 AAAC NULL
201303 AAAC 52

取りたいデータ
DATE(int) CODE(varchar) VAL1(int)
201301 AAAB 12
201302 AAAB 51
201303 AAAB 51
201304 AAAB 51
201301 AAAC 23
201302 AAAC 52
201303 AAAC 52

よろしくお願いいたします。
0242NAME IS NULL2013/10/10(木) 02:36:29.28ID:???
NULLでない値が必ずあるという前提でいいかな?

select
`DATE`,`CODE`,
case when `VAL1` is null then (
select `VAL1` from T T2
where
T2.`DATE` = (
select min(`DATE`) from T T3
where T3.`CODE` = T1.`CODE` and
T3.`DATE` > T1.`DATE` and
T3.`VAL1` is not NULL) and
T2.`CODE` = T1.`CODE` and
T2.`VAL1` is not null)
else T1.`VAL1` end `VAL1`
from T T1;
0243NAME IS NULL2013/10/12(土) 09:11:28.33ID:???
>>238-240
そういうもんなのですね
MySQLなんですけど実際にやってみたら
後者が50倍以上早くなったもので何事かと
0244NAME IS NULL2013/10/12(土) 10:01:50.93ID:???
>>242
お返事遅くなりましたが、無事動作しました。
先頭がNULLのものも存在しますが、
それは放置でもよいので、このSQLで無事で動作できました。
どうもありがとうございました。
0245NAME IS NULL2013/10/12(土) 13:51:38.75ID:???
>>243
テーブルABを結合してからgroupかけたほうが遅くなる。
基本的なSQLの考え方として、テーブルABの結合したとき、単純に考えてテーブルAの行数が
UserID*アイテム数になったものを一時的に作成してからgroupをかけるから。
もちろんテーブルAの列数が少ない、もしくはテーブルBの行数が少ないならそう変わらない。
しかしまあ、テーブルBをgroup化してまとめたものを結合したほうが、考え方としては処理的に
軽そうっていうのが想像つくんじゃないかな。

ただDBMSによってはその辺微妙なところがある。
結合してからgroupっていうのに最適化しているDBMSがあるかもしれない。
あとMySQLはサブクエリの処理が遅いって言われてるから、group化して結合するほうが遅い場合
がある。これはプライマリキーやindexの貼り方とか設定によって変わってくるとか色々要因がある
ので、これ以上はスレ違いなのでググったり違うスレで聞いてくれ。
0246NAME IS NULL2013/10/12(土) 23:42:22.45ID:???
>>245
わかりましたー
ありがとうございます
もうちょっと体系的な勉強からしたほうが良さそうですね
0247NAME IS NULL2013/10/15(火) 07:20:59.81ID:???
SQLServerなんですが、
あるncharの文字列に日付やそれ以外の文字が格納されているのですが
これが日付の時だけ別の処理を施したいのですがどうすればいいですか?
ちなみに、別のフィールドが0の時はその他の文字、1の時は日付か空文字です。

case OTHER_FIELD when 0 then THIS_FIELD else 日付の時の処理 end
の日付の時の処理で困ってます。
0248NAME IS NULL2013/10/15(火) 07:45:30.79ID:???
SQL ServerってLIKE使えねーの?
0249NAME IS NULL2013/10/15(火) 08:28:11.31ID:???
あ違った。case when then THIS_FIELD の部分で文字がint型に変換出来ませんとか出ていた
0250NAME IS NULL2013/10/15(火) 20:32:09.73ID:???
つか日付じゃなかったらどうしたくて、日付ならどうしたいんだ?
単純に区別するだけならcaseでもwhereでもISDATEでも好きなの使え
0251NAME IS NULL2013/10/16(水) 16:56:10.86ID:Qxpo2MUC
質問していること以外で問題が起きてるの?
0252NAME IS NULL2013/10/16(水) 17:10:53.86ID:???
case 〜 when 〜 then THIS_FIELD else 〜のTHIS_FIELDは文字列型をSQLServerが何故かint型に変換しようとしててエラーになってる
0253NAME IS NULL2013/10/16(水) 17:39:54.63ID:j81of1eF
mysqlなんですけどdate型とtime型の値を使って新しく作ったカラムのdatetime型に挿入したいのですができません。
insert into テーブル(datetime) select concat(date,' ',time) from テーブル;
こんな感じでやってみたんですがなんかエラーはでないけどnullのまま。
どうすりゃいいのかわからないので誰か教えてください!
0254NAME IS NULL2013/10/16(水) 18:20:21.98ID:j81of1eF
select文単体でやると「2009-01-01 10:00」みたいに出ます。
それをdatetime型のカラムにに挿入したいだけなんだが…
0255NAME IS NULL2013/10/16(水) 18:25:19.49ID:j81of1eF
あっもしかしてupdateでやればいいのかな…俺アホかもしれん。insertじゃ無理か。
0256NAME IS NULL2013/10/16(水) 18:57:22.56ID:???
concatで文字列が返るからdatetimeにキャストするとか?
0257NAME IS NULL2013/10/16(水) 19:03:38.98ID:j81of1eF
お騒がせしました。なんとかできましたw
0258NAME IS NULL2013/10/16(水) 19:06:47.39ID:???
同じテーブルの同じとこに更新か
0259NAME IS NULL2013/10/16(水) 20:25:35.00ID:???
>>252
CASEのヘルプ見ると
>戻り値の型
>result_expressions およびオプションの else_result_expression の型のセットの中から、最も優先順位の高い型を返します
ってなってるからな
THIS_FIELDがint型なんだろ
0260NAME IS NULL2013/10/16(水) 20:28:46.55ID:???
ああ、ちがう
elseでもどしてるのがint型だな
0261NAME IS NULL2013/10/16(水) 20:32:00.94ID:???
いや、>>247みたらwhen 0か
そこでintで比較してるのかな
0262NAME IS NULL2013/10/17(木) 13:46:06.15ID:???
thenの後は出力したい物を書くところじゃないのか…
0263NAME IS NULL2013/10/17(木) 13:52:47.11ID:???
あ、Current_Timestampを置いたらエラーになったな。これがダメなのか。
0264NAME IS NULL2013/10/17(木) 14:14:50.50ID:???
THIS_FIELDがtext型だからdatetime型はそのまま表示出来なかったり、
int型の結果だったりが変換出来なかっただけだったらしい
次のようにして解決しました。お騒がせしました。

case FIELD_TYPE when 0 then THIS_FIELD else
  case isdate(THIS_FIELD) when 1 then
    str(datediff(yyyy,CONVERT(datetime,THIS_FIELD),current_timestamp))
    else THIS_FIELD
  end
end
0265NAME IS NULL2013/10/17(木) 16:10:40.34ID:zvWiJyP2
逆アクセス解析を作りたいのですが、
1年分のデータを蓄積する場合にテーブル設計はどのようにするのがいいのでしょうか

それとも、ログに書き込む方が理想的なのか・・・・
0266NAME IS NULL2013/10/17(木) 16:14:03.36ID:+UG0MVbJ
何をやりたいのか、よくわからない
0267NAME IS NULL2013/10/17(木) 16:15:13.11ID:zvWiJyP2
逆アクセスランキングを作成したいのです・・・
0268NAME IS NULL2013/10/17(木) 16:23:28.01ID:???
アクセスって何のアクセス?
逆ってなんの逆?
0269NAME IS NULL2013/10/17(木) 16:36:02.73ID:???
DB設計を語るスレ 6
http://toro.2ch.net/test/read.cgi/db/1341061787/l50


ここへ行く以前の話のような気もするけどw
0270NAME IS NULL2013/10/17(木) 16:59:26.76ID:+UG0MVbJ
こういうことをするにはどういうSQLを書いたらいいか?
そういう質問とはちょっと違うよね?
0271NAME IS NULL2013/10/17(木) 18:18:18.90ID:???
ランキングならfluentd + redisだな(適当)
0272NAME IS NULL2013/10/22(火) 19:57:31.97ID:QHt9HIxR
DB: Oracle11g XE
横持ちのレコードを縦持ちに変換する簡単な方法はないでしょうか?

create table yoko (
foo_id varchar2(8) primary key,
val1 number,
val2 number,
val3 number,
val4 number
);
insert into yoko values ('a', 10, 20, 30, 40);
insert into yoko values ('b', 11, 21, 31, 41);

create table tate (
foo_id varchar2(8) primary key,
val_no number primary key,
val number
);
insert into tate values ('a', 1, 10);
insert into tate values ('a', 2, 20);

今はUNIONでつないで全valを変換しているのですが、現在val1068まで来ており今後さらに拡張予定です。
0273NAME IS NULL2013/10/23(水) 09:24:50.97ID:???
ちゃんと正規化してそれなの?
0274NAME IS NULL2013/10/23(水) 12:52:22.57ID:???
ちゃんと設計されたテーブルが、カラムが今後拡張予定とかないだろ
今縦持ちに変換したら、すくなくとも今後カラム増やす必要なんてなくなるだろうし
0275NAME IS NULL2013/10/23(水) 12:54:00.24ID:???
まあ、ホストアプリかストアド組んで変換するしかないんじゃない
0276NAME IS NULL2013/10/24(木) 00:27:53.26ID:???
11gなら unpivot 演算子で少しは楽できるんじゃないかな
それよりval1からval1068まで歯抜けがないとしたら
カラム数の上限を突破していると思うんだけど、そっちが気になってしょうがない
0277NAME IS NULL2013/10/25(金) 20:32:59.92ID:4tXZFiaL
ファイルをgmailのようにラベルで管理するプログラムを作りたいんですが
データベースをどういう構造にすればいいか悩んでいます
以下は思い付いた構造と検索方法なんですが、もっといい方法があればアドバイスお願いします

・ひとつのテーブルに <ファイルパス>|<区切り文字で区切ったラベルリスト、たとえばlabel1,label2,label3> として
LIKEやMATCHでラベルリストを検索後、マッチしたラベルリストを区切り文字で分解し、検索とラベルの精査をする方法
・ラベルごとにテーブルを設けてファイルパス(又は他テーブルでファイルパスをインデックス化したもの)を格納する方法
0278NAME IS NULL2013/10/25(金) 21:29:26.86ID:???
>>277
設計のお話はこちらで
http://toro.2ch.net/test/read.cgi/db/1341061787/
0279NAME IS NULL2013/10/25(金) 21:36:14.51ID:???
>>278
失礼しました
そちらへ移動します
0280NAME IS NULL2013/10/30(水) 23:03:34.66ID:???
お疲れ様です。山下です。
以下のような内容のSQLの実現方法についてご教授下さい。
フィールドはこのようになっています。
"ID","subID","value"
実データが
1,1-1,A
1,1-2,B
2,2-1,C
2,2-2,NULL
2,2-3,D
3,3-1,E
3,3-2,G
3,3-3,I
3,3-3,NULL

このテーブルからsubIDでユニークな結果を出力する必要があり、value部分での条件分けが必要になります。

�@既にsubIDでユニークな場合はそのまま出力をする。
�AsubIDが重複する場合は必ず片方のvalueはNULLなのでvalueを持つものを出力する。
※valueがNULLでも既にsubIDでユニークな場合はそのまま出力します。

上記例だと結果が
1,1-1,A
1,1-2,B
2,2-1,C
2,2-2,NULL
2,2-3,D
3,3-1,E
3,3-2,G
3,3-3,I
このよう結果を期待します。

以上、よろしくお願いします。
0281NAME IS NULL2013/10/31(木) 00:12:14.13ID:???
>>280
>�AsubIDが重複する場合は必ず片方のvalueはNULLなのでvalueを持つものを出力する。

同一subIDで複数の異なる非NULL値があった場合はどうしますか?
0282NAME IS NULL2013/10/31(木) 00:53:19.69ID:???
>>280
group by ID, subIDでmax(value)とか手抜きだろうか?
0283NAME IS NULL2013/10/31(木) 01:06:11.81ID:???
>>282
俺もそれで良いと思うが
subIDがどういう意味なのかよくわからんな
ID=1でsubIDが2-xとかあったりするんだろうか
subIDだけでグループ化すれば良いんじゃね。設計が悪いってのはあるけど
0284NAME IS NULL2013/10/31(木) 08:08:08.19ID:???
>>281
重複する場合、"必ず"片方はNULLなのでそのケースはないので除外します。

>>282
それでちょっと試してみます。

>>283
例としてあげるのは良くなかったかもしれないですね。
設計ミスではなく、ログデータに存在する項目を総取りしなきゃならないので、この形で設計されてます。
ID1,subID2-xはないはずで、そういうものがないはずですが例外として存在することも今後あります。
0285NAME IS NULL2013/10/31(木) 08:15:55.91ID:???
oracle11gですが
<<hoge>>
のように不等号で囲まれているのはなんという名称でしょうか
0286NAME IS NULL2013/10/31(木) 15:59:24.50ID:???
>>284
>>281はたとえば
2,2-2,X
2,2-2,Y
2,2-2,NULL
ってデータがあったときにどうするって言ってるんだと思うが?
0287NAME IS NULL2013/10/31(木) 23:06:46.45ID:???
>>286
すいません。
あっても必ず二つまでしか重複しないようになってます。
それとgroup byとmaxで解決できました。
ありがとうございました!
0288NAME IS NULL2013/11/01(金) 20:49:30.11ID:???
ネット上ではワイルドカード(*)はできるだけ使わないほうがいいとありますが
例えばカラムが10個あって9個必要な場合も*を使わないほうがいいのでしょうか?
0289NAME IS NULL2013/11/01(金) 20:53:48.17ID:???
当たり前だ
0290NAME IS NULL2013/11/01(金) 22:55:04.03ID:???
めんどくさがらず必要テーブル名だけ全部書くことにします
ありがとう
0291NAME IS NULL2013/11/01(金) 23:00:22.48ID:???
カラム名じゃなくてテーブル名を?
0292NAME IS NULL2013/11/01(金) 23:02:33.48ID:???
いえ、カラム名です すいません
0293NAME IS NULL2013/11/02(土) 00:58:18.26ID:???
*は後で項目が追加されたときとかに、バグの原因になるからね。
0294NAME IS NULL2013/11/02(土) 01:49:11.74ID:???
ああ select * のことを言ってたのか
ワイルドカードとか言うから like 'hoge*' みたいなこと言ってるのかと思って意味分からなかった
0295NAME IS NULL2013/11/02(土) 11:20:26.53ID:???
'*' で like の方が意味わからん。
0296NAME IS NULL2013/11/02(土) 12:00:10.89ID:EKiJUbY2
*が好き ということだな
0297NAME IS NULL2013/11/02(土) 18:28:59.81ID:???
外部結合って、where区で T1.NAME=T2.NAME(+)って書くのと、
LEFT OUTER JOINとONを使って書くのだと効率は同じ?
0298NAME IS NULL2013/11/02(土) 19:16:21.11ID:???
>>297
それだけでは判断できんが、まあ、同じ
SQLは書いたとおりに実行されるとは限らないので、最終的には実行計画みろとしか言えん
0299NAME IS NULL2013/11/04(月) 14:34:25.89ID:???
【複数テーブルからの累計取得】

ORACLE 11gです。

以下のような2つのテーブルから4/1〜6/30までのamount累計を
取得したいのですがどのようにSQLを書けばよいでしょうか?

月末の累計値は該当する日付、コードがTABLE_Bに存在する場合は、
TABLE_Bから取得し、存在しない場合はそれまでの累計値から取得します。

TABLE_A
day,code,amount
4/1,1,100
4/2,1,100
:
4/30,1,100
5/1,1,200
5/2,1,200
:
5/31,1,200
6/1,1,300
6/2,1,300
:
6/30,1,300

TABLE_B
day,code,amount
4/30,1,2800


欲しい結果
day,code,amount,cum_amount
4/1,1,100,100
4/2,1,100,200
:
4/29,1,100,2900
4/30,1,100,2800 ← TABLE_Bから取得
5/1,1,200,3000
5/2,1,200,3200
:
5/30,1,200,8800
5/31,1,200,9000 ← TABLE_Bに存在しないので累計値
6/1,1,300,9300
6/2,1,300,9600
:
6/30,1,300,18000 ← TABLE_Bに存在しないので累計値

よろしくお願いします。
0300NAME IS NULL2013/11/04(月) 18:08:41.62ID:???
5/1は3100じゃなく4/30で書き換わったcum_amountから引き継がないと駄目なのか
つかもうデータ引っ張った後に表計算かプログラムかでどうにかしろよと思いたくなるな
0301NAME IS NULL2013/11/04(月) 18:18:16.49ID:???
TABLE_Aを月別にサマリ、そのうちTABLE_Bに存在しない行とTABLE_Bをunion
そいつを指定月で絞ってサマリ
こんな感じでできるんじゃね

俺ならまずそんな設計してるやつを問い詰めに行くが
0302NAME IS NULL2013/11/05(火) 20:12:08.14ID:???
>>299
クソ設計乙

with rec(Val,iday,amount,cum_amount) as(
select 0,TO_DATE('2013/04/01','YYYY/MM/DD'),0,0 from dual
union all
select Val+1,
TO_DATE('2013/04/01','YYYY/MM/DD')+r.val,
nvl(t1.amount,0),
nvl(t2.amount,nvl(nvl(t1.amount,0) + r.cum_amount,0))
from rec r
left join table_a t1 on t1.day = TO_DATE('2013/04/01','YYYY/MM/DD') +(r.val)
left join table_b t2 on t2.day = TO_DATE('2013/04/01','YYYY/MM/DD') +(r.val)
where Val+1 <= 365)
select Val,iday,amount,cum_amount from rec
where iday between TO_DATE('2013/04/01','YYYY/MM/DD') and TO_DATE('2013/06/30','YYYY/MM/DD')
and val > 0
;

あんまり良いSQLではない、日付指定は一つにできると思うんだが、、
エロい人、、改善よろしく。

ただ、このSQLは、5/31にTABLE_Bにどのような累計が入るかで
修正する必要あり。
TABLE_B
day,code,amount
5/31,1,9100とかって4月からの累計が入るなら良いんだが、
5月分の累計が入ってると少し変更する必要あり。
0303NAME IS NULL2013/11/05(火) 21:17:01.99ID:???
それ累計じゃなくてタダの合計ですから
0304NAME IS NULL2013/11/05(火) 21:28:04.91ID:???
>>303
この人の言っている意味が分からないんですが・・・。
欲しい結果の通り出るんですけど・・・。
再帰SQL知らないのかな・・・。
0305NAME IS NULL2013/11/10(日) 22:49:40.53ID:???
すいません教えてください。
sqlite 3.8.1 です

select で as 指定した別名を同じ select 内で取得するカラム名として使用する方法はありませんか。

select
count(*) as matches,
sum(goals) as goals,
goals / matches as goals_per_match
from
match_results

のようなことしたいのですがこれだとエラーになります。
このようなことはできないのでしょうか。
0306NAME IS NULL2013/11/10(日) 22:55:47.62ID:???
sqliteを知らないのですが、、
select
res.goals / res.matches as goals_per_match
from (
select
count(*) as matches,
sum(goals) as goals
from
match_results
) res

これではダメですかねぇ。。
0307NAME IS NULL2013/11/10(日) 23:24:34.58ID:???
>>306
うぉぉできましたできました!
ありがとうございました!!
0308NAME IS NULL2013/11/11(月) 03:43:01.38ID:???
sqlite知らんが、普通に考えれば
select
count(*) as matches,
sum(goals) as goals,
sum(goals) / count(*) as goals_per_match
from
match_results
だろ
>>305のようにかければ便利な気はするが、ほとんどのRDBMSで出来ないと思う
あと、ほんどのRDBMSで平均出す関数があると思うぞ
0309NAME IS NULL2013/11/11(月) 06:38:41.36ID:???
> >>305のようにかければ便利な気はするが、ほとんどのRDBMSで出来ないと思う

これなんでできるようにしないんだろう?
ちょっとした構文定義してフィールドなのかエイリアスなのか区別できるようにして、SQL パースしたときに >>308 のように変換すればいいだけなので実装は難しくないと思うんだけど、ニーズがないのかなぁ...
0310NAME IS NULL2013/11/11(月) 07:54:37.36ID:???
goals / matches の goals がどっちか迷うからじゃないか
0311NAME IS NULL2013/11/11(月) 09:00:05.29ID:???
同じような話題でちょっと前にpostgresのスレが荒れてたなあ
0312NAME IS NULL2013/11/11(月) 09:05:51.29ID:???
よく読んだらぜんぜん違った
0313NAME IS NULL2013/11/11(月) 13:16:08.35ID:???
>>310
それはいくらでもやりようがあると思う。
Oracle の dual 表みたいな感じで、例えば alias 表作って、これは alias を参照するとか。
>>305 なら
select
 count(*) as matches,
 sum(goals) as goals,
 alias.goals / alias.matches as goals_per_match
from
 match_results
みたいな感じ。
0314NAME IS NULL2013/11/11(月) 20:56:24.85ID:???
お前dual 表ってなんだと思ってるんだ
0315NAME IS NULL2013/11/11(月) 21:03:10.89ID:???
人生…かな
0316NAME IS NULL2013/11/12(火) 02:46:24.26ID:???
ヅアル
0317NAME IS NULL2013/11/12(火) 23:48:34.57ID:???
PostgreSQL 8.4.11で
table1
name  id(ユニーク)
a    1
a    2
a    3
b    4
b    5
c    6
から、
name name出現個数 id(最大2個までsort表示させる)
a    3      1 2
b    2      4 5
c    1      6
のような結果が欲しいのですが、どうすればよいでしょうか?
無理なら最小idを一個ずつでもいいです。
0318NAME IS NULL2013/11/13(水) 00:03:21.44ID:???
後者なら普通に、
select name, count(*), min(id) from table1 group by name order by count(*)
でいいんじゃないのかな。

二つ出す場合は、相関サブクエリの結果とくっつけることになるかな。
もしかしたらうまい方法が他にあるかもしんない。
0319NAME IS NULL2013/11/13(水) 01:07:03.73ID:???
>>317です。>>318さま早速のレスありがとうございます。
すみません、簡略化ミスで、idは数字でなく文字列になります。
PostgreSQL 8.4.11で
table1
name  id(ユニーク)
a    あ
a    い
a    う
b    え
b    お
c    か
から、
name name出現個数 id(最大2個までsort表示させる)
a    3      あ い
b    2      え お
c    1      か
のような結果が欲しいのですが、どうすればよいでしょうか?
無理なら最小idを一個ずつでもいいです。
0320NAME IS NULL2013/11/13(水) 01:11:56.94ID:???
minは文字列でも問題無い。
ttp://www.postgresql.jp/document/8.4/html/functions-aggregate.html
0321NAME IS NULL2013/11/13(水) 01:22:56.56ID:???
>>320さま早速のレスありがとうございます。
明日、dbで試してみます。

できればid最大2個までsort表示させる方もよろしくお願いします。
0322NAME IS NULL2013/11/13(水) 03:35:07.23ID:???
functionを使ってみた。一度登録したら、最後のSQLだけで結果は出ます。

drop function top2(varchar);
create function top2(varchar) returns text as
'
declare
param alias for $1;
cu cursor for
select id from table1 where name = param order by id limit 2;
ret text := '''';
rec record;
begin
open cu;
loop
fetch cu into rec;
if not found then
exit;
end if;
raise debug ''id = %'', rec.id;
ret := ret || rec.id || '' '';
end loop;
close cu;
return ret;
end;
'
language 'plpgsql'
;

select name, count(*), top2(name) from table1 group by name order by name;
0323NAME IS NULL2013/11/13(水) 19:54:30.31ID:???
oracle9i環境です。
以下の木構造sqlを9iで再現するにはどうしたらよいでしょうか。

select
ID,
NextID,
sys_connect_by_path(to_char(ID),',') as path,
connect_by_IsCycle as IsCycle
from
RosenMap
start with ID = 10
connect by nocycle prior NextID = ID;

レコードはループしています。
ID NextID
10 20
20 10
0324NAME IS NULL2013/11/13(水) 21:41:49.63ID:???
ループしてるなら木構造じゃないと思うが
nocycleを9iで実現する方法を聞いているならたぶん無理
0325NAME IS NULL2013/11/13(水) 23:15:39.99ID:???
>>320さま
min,maxが数字のみ対象と思い込んでいたので、min(id)も入れて、
select name, count(*), min(id), max(id) from table1 group by name order by count(*)
で対応できました。ありがとうございました。

>>322さま せっかく作って頂いたのですが、利用しているDBは読み込みのみ可だったので、
ユーザ定義関数ではERROR: transaction is read-onlyで
使えませんでしたがユーザ定義関数というのがこういう場面で使えることが分かり参考になりました。

もし、>>319の結果ページのidにて任意の個数を出力させる方法が分かる人がいれば
教えて下さい。>>318さんの言われるように相関サブクエリを使えばできそうな気はするんですが、なかなかできません。
0326NAME IS NULL2013/11/13(水) 23:43:35.79ID:???
>>325
たとえば2個なら
select t.*,(select min(id) from table1 where name=t.name and id>t.min_id) as min2_id
from (select name,count(*) as name出現個数,min(id) as min_id from table1 group by name) t
order by t.name
こんな感じでできる
3個とか4個とか、固定ならこの調子で出来なくはない
0327NAME IS NULL2013/11/14(木) 00:08:28.88ID:???
>>325
posgresql8.4だとarray_aggっていう関数があるらしいから、

select
t1.name,
t1.count(*),
t2.id[1],
t2.id[2]
from (
select
*
from table1
group by t1.name
order by count(*)
) t1
left join (
select
name,
array_agg(id)
from table1
order by id
) t2 on t1.name = t2.name

みたいな感じでいけるんじゃないかなと。
idのnullは配慮していないのと環境が無いからテストしていない。
0328NAME IS NULL2013/11/14(木) 00:23:55.27ID:???
あーたしかに。配列を使うことで簡潔に書ける場面をもっと知っておかないとなぁ
0329NAME IS NULL2013/11/14(木) 00:37:14.33ID:???
posgresqlしらんしそのarray_aggとやらがどんなものか知らんが
group by 書いてるselectに*とか
joinする両方のサブクエリにorder byとか
それホントにちゃんと動くの?なんだか無茶苦茶な気がするけど
0330NAME IS NULL2013/11/14(木) 00:49:13.91ID:???
Postgres(にかぎらずDBの)の配列は使いにくいよ
アプリケーション側で処理したほうがよっぽど楽
03313282013/11/14(木) 00:51:48.67ID:???
array_aggつかえば?という言葉だけで納得してたわ。
せっかくなんでクエリ。

>>325
select name, cnt, ids[1], ids[2] from
(select name, count(*) as cnt, array_agg(id order by id) as ids from t1 group by name) t1
order by cnt desc
03323282013/11/14(木) 00:56:50.14ID:???
こうも書けたけど、どっちもいまいちかっこよくないね…

select name, count(*) as cnt, (array_agg(id order by id))[1], (array_agg(id order by id))[2]
from t1 group by name order by cnt desc
03333272013/11/14(木) 01:20:40.95ID:???
>>329
動かねぇよ!!(逆ギレ)
すみません書き直しました。
けどテスト環境ないんで動くかどうか自信ありません。
select
t1.name,
t1.cnt,
t2.id[1],
t2.id[2]
from (
select
name,
count(id) as cnt
from table1
group by name
order by cnt
) t1
left join (
select
name,
array_agg(id) as id
from table1
order by id
) t2 on t1.name = t2.name

>>330
それ言ってしまうと。大半の質問がアプリでやれって回答になるんだぜ……。

>>332
id order by idってそこでも書けるの知らなかった……。
そっちのほうが短くていいですね。
0334NAME IS NULL2013/11/14(木) 02:00:56.00ID:???
SQLって、予約語やデータ型は大文字で書くのが主流なんでしょうか?
今までずっと小文字で書いていたんですが、「予約語とそうでない語の区別ができるように、前者は大文字で、後者は小文字で書きましょう」と言われて、ちょっと驚いたので。
みんなどうしてますか?
0335NAME IS NULL2013/11/14(木) 02:47:30.76ID:???
自分でarray_agg調べる気がまったくないんだが
>>333
だから、サブクエリにorder by 要るのか、意味あるのかと
t2については、array_aggとやらがorder by前提であるなら意味がある(必要)かもしれんが
t1にorder by は必要で意味があるのか?しかもorder byに(そのselectで定義された)別名とか使えるのか?

>>334
それぞれの主義による
昔ちょっと話題になってスレまで立ったはず
http://toro.2ch.net/test/read.cgi/db/1272761178/
あんまり流行ってないなw
0336NAME IS NULL2013/11/14(木) 05:16:47.89ID:???
>>335
order byは別名使えるでしょ。SQL標準(たぶん92あたり)の範囲だったような。

んで、サブクエリのorder byは指摘のとおり不要。というか、無意味。
エラーにこそならないが、順序が結合後も保たれる保証はないはず。

あと、array_aggを調べるつもりがないことを散々主張してる理由って、標準じゃないから?
sql:2008には盛り込まれてるようだけど。
03373252013/11/14(木) 19:54:31.87ID:???
group化した要素idを任意の個数だけ表示する>>319, >>325の件につき、色々なアイデアありがとうございました。

>>332さんの方法で、うまくいきました。 (array_agg(id order by id))[2]でnullがあるケースではエラーにならず、
何も表示されずという状態になります。COALESCEを使えばより安全なのかもです。

>>326さんの方法が汎用性がありそうなので、3個表示を目指し、下記2つをやってみたのですが、うまくいきません。
オリジナルの2個表示は上手くできました。
select u.*,(select min(id) from table1 where name=u.name and id>u.min_id) as min3_id
  from (
  select t.*,(select min(id) from table1 where name=t.name and id>t.min_id) as min2_id
  from (select name,count(*) as namecount,min(id) as min_id from table1 group by name) t
  order by t.name
  ) u
order by u.name

select t.*, (select min(id) from table1 where name=t.name and id>t.min_id) as min2_id,
     (select min(id) from table1 where name=t.name and id>t.min2_id) as min3_id,
from (select name,count(*) as namecount,min(id) as min_id from table1 group by name) t
order by t.name
正解を教えて下さい。
0338NAME IS NULL2013/11/14(木) 20:08:06.80ID:???
そもそも任意の数を横に表示しようという考え方をやめた方がいいぞ
0339NAME IS NULL2013/11/14(木) 20:10:25.30ID:???
id>u.min_id じゃなくて
id>u.min2_id だと思うが
つか何やってるか理解してる?
0340NAME IS NULL2013/11/14(木) 20:21:32.95ID:???
>>338
ほんとこれ
DBの使い方おかしい
03413252013/11/14(木) 20:42:12.78ID:???
>>339さま ありがとうございました。これでうまく行きました。
select u.*,(select min(id) from table1 where name=u.name and id>u.min2_id) as min3_id
from (
select t.*,(select min(id) from table1 where name=t.name and id>t.min_id) as min2_id
from (select name,count(*) as namecount,min(id) as min_id from table1 group by name) t
order by t.name
) u
order by u.name
この方法はいま使っているDBでは2分かかり、>>332さんの方法では、2秒で終わります。
DBが大きく、クエリをたびたび出したり、大きなデータをそのまま取り出せない状況ですので、こんなことになってます。
皆様色々とありがとうございました。
0342NAME IS NULL2013/11/14(木) 20:58:54.13ID:???
>>330
アプリケーション側で処理したほうが楽っていうけど、擬似コードでいいから書いてもらえる?
コストもメモリ使用量も酷いものしか思いつかないんだ。
0343NAME IS NULL2013/11/14(木) 21:08:49.38ID:???
連投ごめん。

>>341
ついでにこれも試してみてもらえると嬉しいな。
array_aggの回数が半分で済むから速度は上がると思うんだ。
それに、3 4 と増やすときも楽かなと。エラーにならずにNULLが出力されるのは仕様だから安心していいよ。

with t as (select name, count(*) as cnt, array_agg(id order by id) as ids from t1 group by name)
select name, cnt, ids[1], ids[2] from t order by cnt desc

相関サブクエリの方の速度を上げる方法はちょっと思いつかず。
0344NAME IS NULL2013/11/14(木) 21:12:18.14ID:???
さらに連投。。。
最終出力、出現個数の多い順にソートするものだとばかり思い込んでたけど、よくみたら違った。
まぁ、それはたいした違いじゃないけど、一応。
0345NAME IS NULL2013/11/14(木) 21:13:53.24ID:???
DBとの回線の太さとかにもよるけど、速度求めるならホストアプリで
合計と、それぞれのトップ2行(もしくは任意の行数)別にとる方が早いし汎用的だろうに
0346NAME IS NULL2013/11/14(木) 21:24:26.92ID:???
>>345
クエリは select name, id from table1 order by name, id で、
あとはアプリでやれってことでいいのかな。

一般的にありがちな、nameの昇順に10レコード表示したいというシナリオの場合でも同じクエリ?
0347NAME IS NULL2013/11/14(木) 22:48:41.67ID:???
俺なら、2、3個程度なら>>326でやる

任意に数個ってなら、ホストアプリで
select name, count(*) from table1 group by name order by name
を発行して、このレコードセットをループしながら
select id from table1 where name=???
をtopなりoffsetなり指定して発行する

固定数でも数が多いなら、
select name,id,(select count(*) from table1 where name=t.name) as cnt from table1 order by name,id
を発行して、どうしても横表示したいならアプリで縦横変換かな

何にしてもnameにインデックス張っとかんと早くはないだろうけど
0348NAME IS NULL2013/11/15(金) 00:06:36.35ID:???
OLAPサーバー扱ってる人いないですかね・・・
0349NAME IS NULL2013/11/15(金) 00:50:33.52ID:???
>>347
たとえば10レコードほしいっていう場合、前者は1+10回クエリ発行することになる。
で、クエリ発行回数が増えるのを嫌って後者を出したのかと思うけど、
その場合はLIMITなりTOPなりをつけることなく、全件取得するの?
それとも小難しい計算をはさめば必要なデータだけ抽出できたりする?

>>348
いようがいまいが質問を書かないことにはどうにもならんでしょ。
0350NAME IS NULL2013/11/15(金) 01:54:55.47ID:???
>>349
予想されるnameの件数やnameあたりのid数と必要件数、処理の内容等によりけり
つまり、ケースバイケース
固定数で縦持ちなら1文でできる
nameあたりのid数が多くて必要数の上限が少なく、処理時間が問題になるなら固定で1文で絞るSQL書くかもしれんが
あんまりそう言う想定が浮かばん。バッチ処理ならどうせ全行いるだろうし、対話なら画面に収まる行数なんてしれてるだろ
0351NAME IS NULL2013/11/15(金) 09:21:13.65ID:???
・DBMS名とバージョン
SQLight
・テーブルデータ
table1
_id|year|month|day|・・・・
ーーーーーーーーーーーーーーーー
‥‥‥|‥‥‥‥.|‥‥‥‥‥‥‥|‥‥‥|・・・・
‥‥‥|2013|11 |15 |・・・・
‥‥‥|‥‥‥‥.|‥‥‥‥‥‥..|‥‥‥‥|・・・・

table2
_id|year|month|day|・・・・
ーーーーーーーーーーーーーーーー
‥‥‥|‥‥‥‥.|‥‥‥‥‥‥‥|‥‥‥|・・・・
‥‥‥|2013|11 |15 |・・・・
‥‥‥|‥‥‥‥.|‥‥‥‥‥‥..|‥‥‥‥|・・・・
・欲しい結果
上記のようなテーブルが2つあって
yearとmonthとdayが一致する行のデータ
をtable2から取り出して処理したいです。
・説明
自分はDB自体初心者でAndroidアプリを作成するうえで
SQLightを使うことになりましたが、ネットを参考に
手探りでやってるレベルです。
SQLightのスレにも書いたのですがこちらのほうが良い
と、思い書き込みました。
どなたかご教示願います。
0352NAME IS NULL2013/11/15(金) 09:31:24.90ID:???
idは不一致でいいの?
テーブル1に日付があるレコードをテーブル2から取り出すってことで合ってる?
03533512013/11/15(金) 12:28:35.92ID:???
>>352
はい
日付のみが同じ部分を取り出す
という処理がしたいので
_idは、気にしなくて良いです。
0354NAME IS NULL2013/11/15(金) 12:58:06.65ID:???
それならselect year,month,day from table2 where exists(select X from table1 where table1.year =table2.year and (省略) )
SQLightでもしサブクエリ使えなかったらselect distinct table2.year,table2.month,table2.day from table1,table2 where table1.year =table2.year and (省略)
でいけると思う
試してないけど
03553252013/11/15(金) 21:00:58.42ID:???
>>343さま ありがとうございました。試してみたのですが>>332
と同じでした。CGIを作っている訳ではないので、2sで充分満足です。
0356NAME IS NULL2013/11/16(土) 01:02:08.87ID:???
SQLightて…
0357NAME IS NULL2013/11/16(土) 01:03:20.04ID:???
>>355
With句つかうのは許されるの?
SQLに制限はありますか?
0358NAME IS NULL2013/11/16(土) 03:49:11.52ID:???
SQLightでググったら、上位は全部SQLiteの記事だったんだ
何が起こってるか俺にもわからねぇ
0359NAME IS NULL2013/11/16(土) 07:05:13.02ID:???
>>357
対象RDBMSで使える機能は使えばいいと思うよ
03603572013/11/16(土) 14:47:26.91ID:???
>>359

with v1 as (
select
Row_Number() over(partition by name order by id) as jid,
name,id
from table1
)
select v2.name,v2.cnt,l1.id,l2.id
from (
select count(1) cnt,name from table1 group by name
) v2
left join v1 l1 on l1.name = v2.name and l1.jid = 1
left join v1 l2 on l2.name = v2.name and l2.jid = 2

これでどうですか?
ジョインを増やせば任意の個数を増やせる
後はIDをCoalesceで文字列結合するだけ。
03613512013/11/17(日) 06:28:03.54ID:???
>>354
ありがとうございました。
大変参考になりました。
もっと独学をして知識を積むようにも心がけていきます。
0362NAME IS NULL2013/11/17(日) 09:04:13.91ID:???
質問です
・MySQL5

要件
・並び替え、集計
・主キーは注文番号

注文番号 商品  都道府県
-------------------------------------
1    みかん  東京都
2    りんご  東京都
3    りんご  大阪府
4    りんご  埼玉県
5    なし   北海道
6    なし   北海道
7    なし    東京都

のように膨大な注文番号+注文商品+都道府県が取得できるとき、

みかんが一番売れている都道府県、
りんごが一番売れている都道府県
なしが一番売れている都道府県

を取得するにはどのように設計、クエリを発行すればいいんでしょうか。
0363NAME IS NULL2013/11/17(日) 09:17:14.71ID:???
結果をどういう形で出したいかによるな
>>5の応用でもできるし
0364NAME IS NULL2013/11/17(日) 09:23:11.07ID:???
みかんを注文した後に、みかんを一番買っているのは東京都です!
なしを注文した後に、なしを一番買っているのは北海道です!

って出したいんです。
0365NAME IS NULL2013/11/17(日) 10:07:13.06ID:???
なしを選択した場合、
select count(都道府県), 都道府県 from table where 商品 = なし group by 都道府県 order by count(都道府県) limit 1
とか?
0366NAME IS NULL2013/11/17(日) 10:15:22.46ID:???
訂正。
select 都道府県 from table where 商品 = なし group by 都道府県 order by count(都道府県) desc limit 1
0367NAME IS NULL2013/11/17(日) 11:07:35.59ID:???
MySQLは本当自由だな
そんなことできちゃうんだ・・・
0368NAME IS NULL2013/11/17(日) 12:05:00.54ID:???
>>364
ところで

> みかんを注文した後に、みかんを一番買っているのは東京都です!

なんて表示してなにか嬉しいのか?
どちらかと言うと.、東京都の人がみかんを注文したら、「東京都の人が一番買っているのは りんご です」とか表示した方がいいと思うが。
0369NAME IS NULL2013/11/17(日) 12:06:00.70ID:???
>>367
別にMySQLじゃなくてもできるだろ
0370NAME IS NULL2013/11/18(月) 00:53:41.85ID:???
>>366
ありがとうございます!
大変勉強になりました
GROUP BY ORDER BYをこうやって使うんですね

高速化させるために都道府県カラムのデータを数字の1-47にして、TINYINT型にしました
phpの側で都道府県名に変換することにしましたが、
この程度の違いでも効果はあるんでしょうか
0371NAME IS NULL2013/11/18(月) 01:18:56.10ID:???
それで体感できるぐらい速度差が出るようなら、サーバ替えた方がいいよ
とりあえず遅いなら、(商品)か(商品,都道府県)にインデックス張れ。話はそれからだ
0372NAME IS NULL2013/11/19(火) 02:28:41.29ID:???
>>371
素人丸出しアドバイス
0373NAME IS NULL2013/11/19(火) 22:24:20.47ID:???
そこで玄人さんが華麗なテクニックを披露してくれるんじゃないんですかー
0374NAME IS NULL2013/11/20(水) 00:41:13.97ID:???
一度言ってみたかっただけじゃないの?
0375NAME IS NULL2013/11/20(水) 03:30:09.32ID:???
素人も玄人もそこは都道府県マスタつくりなよってツッコミをいれる場面じゃないの
0376NAME IS NULL2013/11/20(水) 10:30:42.59ID:???
例がその場限りっぽすぎて
そういう具体的な答えは出しにくい
0377NAME IS NULL2013/11/22(金) 07:05:55.23ID:RnJw9fzF
phpmyadminでカラムの非表示ってどう解除するんでしょうか
カラム 'id' と 'syutoku' があるとします
select * from table
でカラム'syutoku'が表示されなくなり、更に追加したカラムも表示されません。
なぜか
select id,syutoku from table
では表示されました。何が原因なのでしょう?

テーブルをコピーし、名前を変えると元に戻りました。
0378NAME IS NULL2013/11/23(土) 10:17:12.94ID:hfIPaKQw
supertype, subtypeについて質問です

http://stackoverflow.com/questions/5466163/same-data-from-different-entities-in-database-best-practice-phone-numbers-ex
http://stackoverflow.com/questions/561576/polymorphism-in-sql-database-tables

サンプルを探すといろいろ見つかるんだけど、
例えば上の2つはなんでtypeをプライマリーキーとforeignキーに含めていると思いますか?
superにだけtypeをつけて、subはsuper_idだけでsuperを参照した方が
シンプルで良いような気がするのですが、どういう違いがあるのでしょうか?

よろしくお願いします!
0379NAME IS NULL2013/11/23(土) 13:04:38.28ID:???
>>378
設計はスレ違いなんだが

タイプが表すのは子の種類
つまり子の属性なんだから、子のテーブルに持つのが普通じゃないか
0380NAME IS NULL2013/11/23(土) 16:01:30.85ID:???
>>378
idとtypeの関係を保証するため。
これがないと、同じidを異なるsubに登録できてしまう。
03813782013/11/23(土) 16:59:42.53ID:???
ありがとうございます!
アプリケーション側に一任せずに、設計上でもちゃんと制限したほうが良いという感じでしょうか
そしてスレ違いごめんなさい。
0382NAME IS NULL2013/11/23(土) 18:07:06.57ID:???
制約で保証するかアプリで保証するかは好きにすればいい。
foreign keyだって別に必須じゃないわけだし。
0383NAME IS NULL2013/11/26(火) 14:49:31.58ID:???
mysql5系の質問です
DBを作る時の「MyISAM」と「InnoDB」の違いがよくわかりません。
ゴミでもわかりやすいように教えて頂けないでしょうか?
0384NAME IS NULL2013/11/26(火) 15:01:08.52ID:???
>>383
少なくともMySQLスレがあるんだからそっちで聞け。
ググれアホで終わる気がするが。
0385NAME IS NULL2013/11/26(火) 15:29:32.03ID:???
すいません。質問スレだったのでここでいいかと思ってました
0386NAME IS NULL2013/11/26(火) 15:30:50.64ID:???
SQLの質問であってMySQLの質問じゃないんだなこれが
0387NAME IS NULL2013/11/26(火) 15:39:38.00ID:???
>>386
ありがとうございます
ググってみたらわかりました
0388NAME IS NULL2013/11/27(水) 10:25:51.50ID:???
sqlserver に newid() というユニークな32バイトバイナリを返す関数がありますが
あれの long 版の関数を作りたいです。
newno() みたいな風で、関数を呼ぶたびに +1 しながら値を返すという風で

それ自体は採番テーブルを使って簡単にできると思いますが
呼び出し元のトランザクションとは別の独立したトランザクションで動かしたいのですが
どうやってやるんでしょうか。

つまり、呼び出し元が
insert into ××× values(newno(), ×,, ×, ×, ×);
みたいに利用したあとで rollback しても newno() の採番テーブルは戻ってほしくないのです。
0389NAME IS NULL2013/11/27(水) 12:05:28.97ID:???
ついでにsqlserverでもうひとつ

SELECT 〜 と結果セットを返すストアドAがあって
ストアドBの中でストアドAを呼ぶと、ストアドBの結果セットにストアドAの結果が出てきますが
内部で他のストアドを呼んだときに戻ってくる結果セットを無視させる(読み落とす)ことはできないですか?
0390NAME IS NULL2013/11/27(水) 13:08:28.99ID:???
どちらもスレ違いです
0391NAME IS NULL2013/11/27(水) 13:38:54.63ID:???
SQLの質問スレであってSQLServerの質問スレじゃないんだなこれが
0392NAME IS NULL2013/11/27(水) 14:12:18.06ID:???
Microsoft SQL Server 総合スレ 10
http://toro.2ch.net/test/read.cgi/db/1385363382/
0393388 3892013/11/27(水) 14:33:21.94ID:???
そっちへ移ります。すみません。
0394NAME IS NULL2013/11/28(木) 21:04:47.69ID:???
シーケンスじゃだめな理由を教えてくれ
>>388
0395NAME IS NULL2013/11/29(金) 19:27:25.48ID:???
シーケンスの使えないバージョンなんじゃないか
0396NAME IS NULL2013/11/29(金) 22:29:02.92ID:???
SELECT 何か
FROM テーブルA


というクエリに、テーブルAのidで検索して、テーブルBの中にデータがあるかどうか(true / false)をSELECTに加えたいんですが
どうすればいいのでしょうか

DBはPostgreSQLです

SELECT
A,
B,
C,
EXISTS ()


ってビルト通るのでしょうか・・・
03973962013/11/29(金) 22:39:29.12ID:???
通りましたがまだよく分かりません


SELECT
テーブルA.id,
EXISTS(SELECT テーブルB.id FROM テーブルB WHERE 外部キー = テーブルA.id)
FROM
テーブルA
WHERE
条件


これって条件に一致したテーブルAのidがEXISTSに送られて、そこでTRUE/FALSEが評価されてるのでしょうか?
0398NAME IS NULL2013/11/29(金) 23:03:47.25ID:???
>>397
結果の列ごとの評価だから、期待した結果になると思うよ。

私だったら、テーブルBを外部結合かな。

select a.id,
case
when max(b.id) is null then true
else false
end
from a, b
where a.id = b.id (+)
group by a.id

とか。
03993962013/11/29(金) 23:59:10.59ID:???
>>398
ありがとうございました

whereで絞ったあとの1行1行に対してselectで更に評価するんですね
0400NAME IS NULL2013/11/30(土) 04:06:37.22ID:???
> DBはPostgreSQLです
>
> SELECT
> A,
> B,
> C,
> EXISTS ()

これに対する>>398の回答は
・PostgreSQLでは使えない方言
・複数カラム抽出したそうな意向を無視したgroup byへの変更
・条件判定ミス
となっている。ここまできたらネタ回答としか思えない。
0401NAME IS NULL2013/11/30(土) 06:02:57.92ID:???
select tableX.A,tableX.B from tableX; と打ったらこんな結果が出てくるテーブルがあるんですが
A   |B
あああ|んんん
かかか|ををを
さささ|わわわ

これに、各検索結果のtableX.AとtableX.Bの値を使い
select count(*) from tableY where tableY.A=tableX.A and tableY.B=tableX.B;
の結果の項目を追加するにはどうしたら良いのでしょうか

A   |B   |追加項目
あああ|んんん|1
かかか|ををを|0
さささ|わわわ|0
0402NAME IS NULL2013/11/30(土) 10:47:00.29ID:???
>>400
ORACLE信者をいじめないでください
0403NAME IS NULL2013/11/30(土) 11:19:39.11ID:???
>>401
select tableX.A,
    tableX.B,
    count(*)
from  tableX,
    tableY
where tableY.A = tableX.A
and  tableY.B = tableX.B
group by tableX.A, tableX.B
;
0404NAME IS NULL2013/11/30(土) 11:25:19.69ID:???
>>400
ん?SQLスレだから、方言による差異を気にする必要あったのかな。
意味が通ればいいだろうと思ってざっくりで書いたんだがなぁ。
そもそも質問主の質問内容を見れば、そこまで求めてないと思うのだが・・

>>401
最近はOracleが多かったので(+)で表現したけど、Oracleは嫌いだ。*にすればよかったかな。
ただ結合条件をWHERE句で書くよう指導されていた世代なのでJOIN句は今でも苦手。
0405NAME IS NULL2013/11/30(土) 11:26:04.79ID:???
あ、すまん。
>>402だった。
0406NAME IS NULL2013/11/30(土) 12:40:42.64ID:???
(+)って外部結合演算子って言うのですね
はじめてみました

標準規格にはないみたいですが、知っとかないとまずいですか?
会社でOracleとSQL Server扱ってますが、今のところ見たことないんです
0407NAME IS NULL2013/11/30(土) 13:09:24.97ID:???
どっちもOUTER JOINで出来るっぽいが使わないなら使わないでも全く問題ない
用途結構限られてるし
0408NAME IS NULL2013/11/30(土) 17:52:40.51ID:???
>>401
select tableX.A,tableX.B,
(select count(*) from tableY where tableY.A=tableX.A and tableY.B=tableX.B) as 追加項目
from tableX

>>406
古いORACLEはその書き方だったから、ORACLE扱うなら覚えておいて損はない
今はその書き方はしない方がいいけど
0409NAME IS NULL2013/12/01(日) 08:19:20.04ID:???
>> 408
スレチだけど・・・

プロジェクト内の11gR1での検証で、Oracle任せの抽出ではJOIN句の方が遅かった。
検証前の想定ではオプティマイザが吸収するので同じ結果になるのでは・・・くらいかんがえていたんだけどな。
結果、コーディングルール上は、(+)を推奨することになった。
できるだけ使わないのが正解ではあるが。

なんだかんだ言いつつも、where句での解析の方が判断しやすいのではと推測している。
0410NAME IS NULL2013/12/01(日) 09:39:17.53ID:???
>>409
オプティマイザを出すならバージョンを書いてくれ
0411NAME IS NULL2013/12/01(日) 10:21:23.80ID:???
>>409
Oracle 9iのときはバグもあったし速度も遅かったから
うちも非推奨にしてた。
10gからは変わらないから(+)を使わないルール。
0412NAME IS NULL2013/12/01(日) 11:45:43.93ID:???
もうオラクルはオワコンだろ、どう見ても
0413NAME IS NULL2013/12/01(日) 12:46:25.95ID:???
>>410
11gR1って書いてあるぞ

11gR1だと同じだと思うんだけどな
0414NAME IS NULL2013/12/01(日) 17:04:40.32ID:???
>>410
ここで細かいVersion出して掘り下げても意味なくないか?
サポートも動かしての検証なので、精度的には間違いないと考えているし、11gR1の頃なので、仮に今更、間違いだったと指摘されても寒い。もう、リプレイス計画進めているし。

>>412
Oracleがオワコン?
商用RDBの中では、Oracleはまだ頑張っているほうだぞ。
12cもカタログ通りだったら、面白い製品になりそうだし・・・
ただ、あそこのスペックは8の頃からの伝統があるしなぁ。

商用RDBオワコンという話であれば、ベンダサポートも含めて商用以外を選択しにくいケースがあるので、どうだろう。
ただ、無条件に商用RDB一択という時代は10年以上前に終わってる。

RDBがオワコンというのであれば、用途次第というところじゃないかな。

いずれにせよスレチなので止めるね。
次からは、論点がずれないように標準的なSQLで答えるようにするわ。
0415NAME IS NULL2013/12/01(日) 18:48:06.91ID:???
おれの周りだとSQLServerに急速シフトしとる
Oracleじゃなきゃって信者と官公庁くらいじゃないか
0416NAME IS NULL2013/12/01(日) 19:18:47.79ID:???
早いとか遅いとかじゃなくて、どういう実行計画だったか見ないと意味ないし
0417NAME IS NULL2013/12/01(日) 21:53:44.79ID:???
>>415
参考に理由教えてもらえるかな?
やっぱ価格?
0418NAME IS NULL2013/12/01(日) 22:08:55.87ID:???
・安い(Expressでもかなりのことが出来る)
・クライアントソフト不要
・チューニングしなくても、そこそこパフォーマンス出る
・ストアドが行を返せる
・T-SQLの中で .Net の言語が書くこともできる
・T-SQLの中でメール送信を書ける(保守に便利)

等々。
シビアなレコードロックはオラクルが上手だけど、それが必要な場面って意外に少ない
0419NAME IS NULL2013/12/01(日) 22:16:23.51ID:???
Oracleなんて無駄にお布施してるだけで使いこなせてないとこが殆ど。
SQL Serverで十分だと馬鹿もやっと気付いたのさ。
0420NAME IS NULL2013/12/01(日) 23:51:12.68ID:???
DB死んだときに生き返らせてくれたからOracle信者続けるわ
金はらっときゃいいんだもの
0421NAME IS NULL2013/12/02(月) 00:22:48.82ID:???
うちの周りでよく話に出るのは
> ・チューニングしなくても、そこそこパフォーマンス出る
これ。
Oracleのチューニングのために人を呼んで高い金払って
やっとSQLServerとほぼ同じ速度になる

まぁ、速度以外でOracle優位になる部分もあるんだけど、それを必要とするかどうか、だよね。

そう考えると、速度を求めるためにOracleを選択する時代ではなくなったのかなと思う。
0422NAME IS NULL2013/12/02(月) 00:23:54.39ID:???
あ、そんなことを書いてる俺はPostgreSQLばかり使ってます。
0423NAME IS NULL2013/12/02(月) 01:28:56.58ID:???
まるでチューニングとかをしないとOracleは使い物にならんような言い方だな
0424NAME IS NULL2013/12/02(月) 01:32:57.74ID:???
使ったこともないやつがちょっと聞きかじった話を信じこんでる間抜けさが…
0425NAME IS NULL2013/12/02(月) 02:04:48.31ID:???
>>423
実際そう。デフォだと遅い。
0426NAME IS NULL2013/12/02(月) 02:14:33.15ID:???
>>425
おまえがアフォだからだろ
0427NAME IS NULL2013/12/02(月) 08:12:50.24ID:???
SQLServerだとミラーリングで待機側はライセンス要らない
それだけで半額だ
0428NAME IS NULL2013/12/02(月) 14:33:05.32ID:???
ObjectBrowserも買わなくていいな、SQLだと
0429NAME IS NULL2013/12/02(月) 14:43:03.33ID:???
sqliteに3DCGを埋め込みたいのですがどうやればいいんですか
また必要なソフトとかありますか
0430NAME IS NULL2013/12/02(月) 17:32:03.36ID:???
>>429

SQLite Part.10
http://toro.2ch.net/test/read.cgi/db/1345121656/l50
0431NAME IS NULL2013/12/04(水) 12:56:16.73ID:???
基礎的なことで申し訳ないんですが、
WHERE句である条件を完全一致させたいときは
普通に「ID = '00001'」みたいにしますけど、
それを「ID LIKE '00001'」としても、完全一致になりますよね?
%付けなければ。
0432NAME IS NULL2013/12/04(水) 14:47:47.63ID:???
なります。あとアンダースコアに気をつければ。
0433NAME IS NULL2013/12/04(水) 17:25:12.10ID:???
ワイルドカード文字とエスケープ文字、比較してるカラムの型あたりに気をつけないと
思わぬ結果になるかもしれんぞ
0434NAME IS NULL2013/12/06(金) 21:20:44.65ID:???
サンコス ナイスガイs
0435NAME IS NULL2013/12/13(金) 18:15:09.33ID:???
ある表の並び順をユーザーが任意に指定できるフィールド sort_key があります。
例)
id,sort_key
1, 3
2, 4
3, 2
4, 5
5, 1
…
この表の任意の行をアプリ側でユーザーが sort_key を変更したあと、
全行の sort_key を振り直すにはどうしたらいいでしょうか?
0436NAME IS NULL2013/12/13(金) 18:49:54.98ID:???
言わんとすることは分かったけど、状況によるよ。
・入れ替えなら、入れ替えればいい
・追加で割り込ませたいのなら、それよりも大きいものを+1
・削除のときにつめたいのなら、それよりも大きいものを-1
0437NAME IS NULL2013/12/13(金) 21:28:36.74ID:???
>>436
言葉足らずですみません。
入れ替えではないです、そんなのなら問題ない。
+1、-1 の方法だと、
update table set sort_key=(sort_key + 1)
と 同 (sort_key - 1) の両方が必要になりますよね?
なので困ってます。
0438NAME IS NULL2013/12/13(金) 21:33:24.99ID:???
つまり、
update table set sort_key=(sort_key + 1) where sort_key > n
と
update table set sort_key=(sort_key - 1) where sort_key < n
みたいなのが二つ
0439NAME IS NULL2013/12/14(土) 01:39:16.67ID:???
 sortkeyでもなんでもいいから前レコードのid入れろ
0440NAME IS NULL2013/12/14(土) 01:54:21.44ID:???
つまり現在のsort_keyと更新値のsort_keyの間にあるsort_keyを持つレコードのsort_keyを1上げるなり下げるなりするってこと?
>>435のテーブル例に、id=3(現在のsort_key=2)のsort_keyを4に変更しようとしたときは、
2〜4の間にあるid=1(sort_key=3)とid=2(sort_key=4)のsort_keyを1減らした後にid=3のsort_keyを更新値である4に変更し、
id,sort_key
1, 2
2, 3
3, 4
4, 5
5, 1
にするってことでいいのかね?
というか俺の読解力がないだけなんだろうけど、どういうUPDATEを作りたいのかさっぱりわからん
0441NAME IS NULL2013/12/14(土) 02:03:21.91ID:???
>>440
はい、ずばりそのとおりです。
それを一回のupdate文でできないかなって…
アプリ側でやろうとすると結局行数分ループ回してインクリメントしなくちゃならないし、
そんなの数百行ならまだしも、数百万行とかなったら…
0442NAME IS NULL2013/12/14(土) 04:57:39.54ID:???
間にあるやつを、上か下にずらせばいいだけじゃん。
なんで2回発行しないといけないとか言い出すのかわからん。

5を2に移したいなら、2 3 4 を+1すればいいし、
1を5に移したいなら、2 3 4 5 を-1すればいい。
0443NAME IS NULL2013/12/14(土) 10:18:00.80ID:???
>>442
間にあるものを+1や-1した後に目当てのidのsort_keyを更新するの忘れてないか
0444NAME IS NULL2013/12/14(土) 16:17:16.45ID:???
それにしたって2個のSQL流せばいいだけで、すくなくとも
>行数分ループ回してインクリメント
なんてアホなことする必要ない
0445NAME IS NULL2013/12/14(土) 21:29:07.01ID:4Nkx3/nr
>>441
sort_key 2 のデータを 4 にし、他を順次繰り上げる場合
update `table`
set sort_key = (
case
when sort_key = 2 then 4
else sort_key - 1
end
)
where sort_key between 2 and 4;
0446NAME IS NULL2013/12/14(土) 22:29:50.22ID:???
上げるときと下げるときで分岐させる必要あるな
2→4だと-1で4→2だと+1にせな
0447NAME IS NULL2013/12/15(日) 00:17:07.98ID:???
sort_keyが2と4って入れられるんであれば、「sort_key - 1」の1の部分もSQL作る時点で入れたらいいんじゃね?
「sort_key +」を固定にして1か-1をどちらか入れる感じ。
0448NAME IS NULL2013/12/15(日) 15:22:47.43ID:???
なんでリスト構造にしないの?
0449NAME IS NULL2013/12/15(日) 23:33:28.00ID:???
>>448
RDBとリスト構造って相性悪い
てか、不倶戴天の敵w
0450NAME IS NULL2013/12/15(日) 23:59:22.55ID:???
>>448
要件次第。
隣が欲しいだけならリストは便利だけど、一覧でソートのようなことをするときは実に面倒
0451NAME IS NULL2013/12/16(月) 00:03:05.31ID:???
ある意味、リスト構造を駆逐するためにできたのがRDB
0452NAME IS NULL2013/12/16(月) 00:10:28.04ID:???
プログラミング言語から入ってきたばっかりで問い合わせ言語(SQL)の本質を正しく理解してないと、どうしてもそうゆう発想(リスト構造やツリーで処理する等)になっちゃうね
0453NAME IS NULL2013/12/16(月) 02:11:28.81ID:???
>>435 です。
色々とありがとうございました。
二つupdate文がいるっていうのは間違いでした。
該当行を前にもっていく場合と後ろにもっていく場合をcase文で振り分けて
インクリメントする場合とデクリメントする場合の両方を記述できました。
ありがとうございました。
でも、こうゆう処理(任意の並び順)ってけっこうあると思うんだけど、
あんまり例文がなかった。どうやるのが正しい?のかなぁ
あと、アプリ側で必要全行分ひとつづつupdate処理するのも試しましたが、
数千行程度なら一瞬ですね、何万何十万だと不安だけど
0454NAME IS NULL2013/12/16(月) 03:42:48.59ID:???
俺なら通番にしないで、10ごととか100ごととかに入力してもらうが
間が詰まったときだけメンテでごっそりずらす
0455NAME IS NULL2013/12/16(月) 04:57:45.81ID:???
>>454
あんまりスマートじゃないな
0456NAME IS NULL2013/12/16(月) 07:41:51.09ID:???
>>455
では、スマートな方法よろしくお願いいたします。
0457NAME IS NULL2013/12/16(月) 10:22:53.97ID:qjREM8Gx
商品テーブル、商品ID、商品名、…
売上テーブル、商品ID、日時、…

こんな感じのテーブルで指定期間に売れた商品名だけを抽出したい場合

SELECT 商品T.商品名
FROM 商品T
WHERE EXISTS (SELECT 売上T.日時
FROM 売上T
WHERE (売上T.日付) Between #01/01/2013# And #02/01/2013#);

ってやると全商品名が出ちゃうのですが、何が間違ってるのでしょうか?
0458NAME IS NULL2013/12/16(月) 10:34:12.33ID:???
これだと何の商品が売れたのか分からないから

SELECT 商品T.商品名
FROM 商品T
WHERE EXISTS (SELECT 商品T.商品名
FROM 商品T INNER JOIN 売上T ON 商品T.商品ID = 売上T.銘柄ID
WHERE (売上T.日付) Between #01/01/2013# And #02/01/2013#);

ってやっても全商品名が出てダメでした
0459NAME IS NULL2013/12/16(月) 10:46:50.36ID:???
SELECT 商品T.商品名
FROM 商品T
WHERE EXISTS (SELECT 売上T.日時
FROM 売上T
WHERE (売上T.日付) BETWEEN #01/01/2013# AND #02/01/2013# AND 商品T.商品ID = 売上T.商品ID);

これで行けましたが、速度はOrderByやDistinctと大して変わらなかったです
他の方法考えます。どうもお騒がせしますた
0460NAME IS NULL2013/12/16(月) 10:50:31.49ID:???
×OrderBy
○GroupBy
0461NAME IS NULL2013/12/16(月) 10:58:23.80ID:???
↓だとスピード変わる?

SELECT 商品T.商品名
FROM 商品T
WHERE 商品T.商品ID IN (SELECT 商品T.商品ID
FROM 売上T
WHERE (売上T.日付) BETWEEN #01/01/2013# AND #02/01/2013#);
0462NAME IS NULL2013/12/16(月) 10:59:13.35ID:???
失礼、コピペミス

SELECT 商品T.商品名
FROM 商品T
WHERE 商品T.商品ID IN (SELECT 売上T.商品ID
FROM 売上T
WHERE (売上T.日付) BETWEEN #01/01/2013# AND #02/01/2013#);
0463NAME IS NULL2013/12/16(月) 11:27:45.29ID:???
>>461
変わるかどうか自分でSQLの実行時間を計測しろよ
あほなの?
0464NAME IS NULL2013/12/16(月) 11:28:49.27ID:???
>>456
評論家ってのは評論するだけ
実演とか求められないのよ
0465NAME IS NULL2013/12/16(月) 12:00:37.99ID:???
>>463
なにあほなこといってるの。>>457氏は10万の売上レコードの用意が
あるかも知れないんだ。まず計測を依頼するのが自然だろ。
0466NAME IS NULL2013/12/16(月) 12:07:13.06ID:???
>>465
どゆこと?
意味わからん
0467NAME IS NULL2013/12/16(月) 12:55:37.44ID:???
>>466
ごめん、全部同じ人のレスが続いているのか。
0468NAME IS NULL2013/12/16(月) 14:30:39.15ID:???
>>462
ありがとうございます。あまり変わらないですね
結局別のアプローチを取りました

全商品IDを総問い合わせで期間中の売れた商品名を抽出
スマートとは程遠いですが、一番速かったです、、、
0469NAME IS NULL2013/12/16(月) 15:03:52.59ID:???
>>464
ごめんね、ここ技術板だから役に立たない評論家は要らんよ。
0470NAME IS NULL2013/12/16(月) 15:29:07.18ID:???
聞くだけのやつも役に立ってない
0471NAME IS NULL2013/12/16(月) 17:32:04.83ID:???
>>468
select大量発行にしたら速くなったってこと?
単なる興味でだけど、前後の速度を知りたい。

インデックスに難があるんじゃないかと思うけど。
0472NAME IS NULL2013/12/16(月) 18:13:54.99ID:???
普通に商品と売上をJOINして絞れば良いと思うんだが
そのうえで速度は実行計画みて考えれ
0473NAME IS NULL2013/12/16(月) 19:05:52.25ID:???
>>471
商品テーブルは8000レコード(商品IDにPK)
売上テーブルの1300万(オートナンバーPK、商品IDと日付に複合Index)

全商品IDは勿論一瞬で出るので8000回ループで拾って完走まで5〜7秒

SELECT 売上T.商品ID
FROM 売上T
WHERE (売上T.商品ID)="8000回" AND (売上T.日付) Between #01/01/2013# And #02/01/2013#)
ORDER BY 売上T.商品ID, 売上T.日付;

>>459や他に商品Tと売上Tを含めると必要分だけ回せるのですが
26〜30秒くらい掛かります
0474NAME IS NULL2013/12/16(月) 19:33:42.49ID:???
>>473
…日付にインデックス貼ってみたら?
0475NAME IS NULL2013/12/16(月) 20:14:45.13ID:???
日付に#って、まさかMDB?
0476NAME IS NULL2013/12/16(月) 20:17:02.59ID:???
>商品IDと日付に複合Index
>WHERE (売上T.日付) BETWEEN #01/01/2013# AND #02/01/2013# AND 商品T.商品ID = 売上T.商品ID);

これ、たぶんインデックスサーチ効いてないよ
日付のみキーのインデックス作って >>459 >>462 を再試
0477NAME IS NULL2013/12/16(月) 20:30:15.60ID:???
>>470
あなたのレスで、役に立ったものを教えて下さい
0478NAME IS NULL2013/12/16(月) 21:04:09.92ID:???
8000回ループで拾ってとか、必要分だけ回せるとか、意味不明なんだが

なぜ素直にJOINしたSQLでやらないの?
なんで実行計画確認しないの?
0479NAME IS NULL2013/12/16(月) 22:00:07.97ID:???
>>474,477
凄いです。ドンピシャでした。
全商品目検査と同じくらいの速度になりました
0480NAME IS NULL2013/12/16(月) 22:00:40.02ID:???
×>>477
○>>476
0481NAME IS NULL2013/12/16(月) 23:35:24.69ID:???
こうしてまた一人、インデックスの魅力に憑かれた男がうまれたのであった。めでたし。
0482NAME IS NULL2013/12/18(水) 04:37:09.87ID:???
SQLightで

テーブルA
ID | DATE01|DATE02| DATE03| DATE04| DATE05|etc・・・
( DATE01,DATE02,DATE03, DATE04,DATE05は、それぞれ
違う日付のtext型の値が入っています。)

テーブルB
ID | DATE|etc・・・

ていうテーブルがあって
B.DATEとA. DATE01, A. DATE02, A. DATE03, A. DATE04, A. DATE05
を、比較して、同じ日付があった時、テーブルBから
その行のデータを取り出すという処理をしたいのですが
or文を使って実行したら、その行のデータを5回取り出して
しまいました。
自分の書いたsql文が間違っていると思うので
適切なsql文をどなたかご教示願います。
(初心者の質問ですみません)
0483NAME IS NULL2013/12/18(水) 05:24:45.47ID:???
またlight君か
0484NAME IS NULL2013/12/18(水) 11:25:33.48ID:EewOgcA5
>>482
まず、自分が書いたsql文をここに晒してみる
0485NAME IS NULL2013/12/19(木) 13:06:53.35ID:???
textを、比較する時
= 文字列
ではなくて
='文字列'
ですか?
0486NAME IS NULL2013/12/19(木) 14:02:46.49ID:???
そりゃSQLでの文字列は '文字列' だからな
0487NAME IS NULL2013/12/20(金) 22:17:33.87ID:7DjcGZuA
次のようなデータがあります。
tozai nihon
関東 関東
関西 関西
−− 関西
関西 関東
−− 関東
−− −−
関東 関東
関西 関西

(−−)は空のデータ


tozaiとnihonではtozaiが優先されます。
例えば、tozai=関西,nihon=関東となっていた場合、tozaiが優先されるので「関西」と見なされます。
この条件で、関東と関西のデータがそれぞれ何件あるか調査する為に次の3つのSQL文を出しました。
これらを一つの文にまとめたいのですが、どのようにしたらよいでしょうか?

select count(*) from hoge where tozai='関東' or (tozai='' and nihon='関東');
結果=3

select count(*) from hoge where tozai='関西' or (tozai='' and nihon='関西');
結果=4

select count(*) from hoge where tozai='' and nihon='';
結果=1
0488NAME IS NULL2013/12/20(金) 22:26:02.95ID:???
つ union all
0489NAME IS NULL2013/12/20(金) 23:05:41.48ID:???
select
sum(case when tozai='関東' or (tozai='' and nihon='関東') then 1 else 0 end) as col1,
sum(case when tozai='関西' or (tozai='' and nihon='関西') then 1 else 0 end) as col2,
sum(case when tozai='' and nihon='' then 1 else 0 end) as col3
from hoge
0490NAME IS NULL2013/12/21(土) 18:03:40.82ID:???
>>487
試してないけど
select x,count(*) from
(select case when tozai is null then nihon else tozai end as x from hoge) t
group by x
0491NAME IS NULL2013/12/21(土) 18:12:47.81ID:???
ああ、空のデータってnullじゃなくて空文字列なのか
nullと空文字列を区別できないDBMSじゃなければ
tozai is null をtozai=''に
0492NAME IS NULL2013/12/21(土) 18:43:39.10ID:???
null にしておけば coalesce とか使えるのにね
0493NAME IS NULL2014/01/11(土) 22:54:06.39ID:???
SQLServer2008R2です.
テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(float型)
の3カラムからなります.各DATEの各CODEに対して過去3か月分の総和を算出したいと思います.
元テーブル
DATE, CODE, VALUE
....
200101, AAA, 1
200102, AAA, 2
200103, AAA, 3
200104, AAA, 4
200101, BBB, 1
....

欲しい結果
200103, AAA, 6
200104, AAA, 9
.......

下記のようなSQLを書いたのですが,同じ結果の行が12か月分でてきます.
何処を修正すればよろしいでしょうか?もしくは全然違うSQLでしょうか?

SELECT A.DATE, A.CODE, SUM(B.VALUE) OVER (PARTITION BY B.DATE, B.CODE)
FROM TABLE A, TABLE B
WHERE A.CODE=B.CODE AND B.DATE>=A.DATE AND B.DATE>=(A.DATEの3か月前←計算式が長いので省略です)
ORDER BY A.DATE, A.CODE

よろしくお願いいたします.
0494NAME IS NULL2014/01/12(日) 21:00:50.67ID:???
>>493
手元に環境無いんでSQL自体は書けないけど、それは再帰SQLでいける。
0495NAME IS NULL2014/01/12(日) 21:28:09.18ID:???
>>493
FROMで結合するのにOVER句とか、どういう覚え方したらそんなSQL書くようになるんだろう

俺ならこう書くけど
select DATE,CODE,
(select SUM(VALUE) from [TABLE] where CODE=t.CODE and [DATE]<= t.DATE and [DATE]>t.DATE - 3)
from [TABLE] t order by DATE,CODE

結合でやりたいならこうじゃね
SELECT A.DATE, A.CODE, SUM(B.VALUE)
FROM [TABLE] A, [TABLE] B
WHERE A.CODE=B.CODE AND B.DATE<=A.DATE AND B.DATE>(A.DATE-3)
GROUP BY A.DATE, A.CODE
ORDER BY A.DATE, A.CODE
join使えよと思うが邪魔くさいので書きなおさない

DATE-3は3か月前のことな←計算式が長いので省略です
0496NAME IS NULL2014/01/12(日) 21:34:41.20ID:???
>>494
累計じゃないからこの程度で再帰とか要らんぜ
0497NAME IS NULL2014/01/13(月) 09:52:07.05ID:???
> A.DATEの3か月前←計算式が長いので省略です
これって、ついでにこれも教えてくれよってことなんだろうなぁ。
0498NAME IS NULL2014/01/13(月) 22:30:19.15ID:???
さすがにそれは深読みし過ぎ
0499NAME IS NULL2014/01/14(火) 10:39:51.24ID:???
回答と質問の区別がついてないだけかと
0500NAME IS NULL2014/01/14(火) 15:32:00.16ID:???
>>499
質問を読んですらない人が口を挟むのはちょっと勘弁
0501NAME IS NULL2014/01/14(火) 16:22:41.78ID:???
>>500
キミは>>495が質問だと思ってるの?
0502NAME IS NULL2014/01/14(火) 16:33:35.77ID:???
>>501
?

>>493
> WHERE A.CODE=B.CODE AND B.DATE>=A.DATE AND B.DATE>=(A.DATEの3か月前←計算式が長いので省略です)
05034932014/01/15(水) 21:22:36.77ID:???
>>495
お返事遅くなりました.
すいません.SQLはあまり詳しくないもので..
webで調べてたら上記のSQLにたどり着きました.
1つ目のシンプルな方法で十分ですね.無事意図した結果を得ることができました
ありがとうございました.

因みに3か月前は
CONVERT(int, CONVERT(nvarchar(6), DATEADD(month, -%d, CONVERT(datetime, CONVERT(varchar, A.DATE) + '01')), 112))
でやってます.長かったので書きませんでした.
もしもっと簡単な計算方法があれば教えていただければ幸いです.
0504NAME IS NULL2014/01/16(木) 03:37:50.70ID:???
Nヶ月前を算数的にやるならこんな?
A.DATE - N - (A.DATE % 100 <= N) * 88
0<=N<=12。

ただ、見てのとおり気持ち悪いし、一番いいのはA.DATEをDate型にすることだと思うよ
0505NAME IS NULL2014/01/16(木) 14:02:00.49ID:???
Oracle10 です

sqlでTというテーブルにある1000個の項目の内
990フィールドの値をそのまま使いたい時、
(残り10個は別テーブルUとJOINしてそっちのテーブルの値を使いたい)

select
T.AA
,T.AB
,〜
,U.ZZ

と1000項目全て書くのと、

select
Y.*
,U.X
,〜
,U.Z

*で全部取って10コだけ別に取るのでは
どちらが良いものなんでしょうか…?
0506NAME IS NULL2014/01/16(木) 15:06:00.00ID:???
1000ってすごいなぁ。
僕なら単にめんどくさいから後者にする
0507NAME IS NULL2014/01/16(木) 15:12:40.60ID:???
1000個も書いてるとSQL文の長さ制限に引っかかるんじゃないか
それにSQLのコンパイルも遅そう
0508NAME IS NULL2014/01/16(木) 22:32:57.32ID:???
てs
0509NAME IS NULL2014/01/16(木) 22:54:33.69ID:???
質問です。
userlistテーブル
userid |name
   1|aaa
   2|bbb

titleテーブル
titleid|title
   1|ccc
   2|ddd

testテーブル
userid |title|test|tst
   1|  1| qwe|asd
   1|  2| asd|zxc
   2|  1| oiu|lkj

上記のテーブルから下記を出力したい
name |title|test|tst
 aaa| ccc| qwe|asd
 aaa| ddd| asd|zxc
 bbb| ccc| oiu|lkj
どのように書けばいいのでしょうか。初歩的な質問で申し訳ございません。よろしくお願いします
0510NAME IS NULL2014/01/16(木) 22:56:52.92ID:???
書き込みミス
testテーブルのところ
userid |title|test|tst
ではなく
userid |titleid|test|tst
です。よろしくお願いします
0511NAME IS NULL2014/01/16(木) 22:58:39.43ID:???
製造業〜サービス業〜金融〜通信と色んな分野の業務に携わってきたけど、
一つのテーブルに千個もフィールドがあるなんてちょっと想像がつかない。
なんか特殊な分野なのかなぁ?
現実の世の中の仕組みの投影としてはありえないでしょ?
0512NAME IS NULL2014/01/16(木) 23:01:34.47ID:???
>>509
初歩的な質問だと自覚してるんだったら、まず、初歩的な勉強をして下さい
05135092014/01/16(木) 23:17:21.61ID:???
>>512
joinってやつ使ったら余裕でできたわ
じゃあなw
0514NAME IS NULL2014/01/16(木) 23:47:23.56ID:???
管理的な意味で普通はテーブル分けるしな
0515NAME IS NULL2014/01/16(木) 23:59:24.90ID:???
>>511
正規化されてないまま運用され、それが拡張され続けた結果かもしれない。
というか、そうとしか考えなかったけど、実際どうなんだろうね
0516NAME IS NULL2014/01/17(金) 00:11:52.49ID:???
1テーブルに千個の列とか(笑)
まったくRDBMSを理解してないシロートだな
いやいくらシロートでもちょっとはおかしいと気づくよなぁ?
0517NAME IS NULL2014/01/17(金) 00:14:04.66ID:???
どんなテーブルか気になるっ
0518NAME IS NULL2014/01/17(金) 00:16:57.69ID:???
>>516
まさかとは思うがアイテム(商品とか会員とか)の数が数百とかあって、
それを列に当てはめてるとか?
それはともかく、列があまりにも多いとパフォーマンスが極端に下がるよね?
0519NAME IS NULL2014/01/17(金) 00:18:33.76ID:???
まあ実際に1000カラムのテーブルがあるわけじゃなくて
どんなにカラム数が多くなったとしても*は避けるべきなのか聞きたかったんでしょ
0520NAME IS NULL2014/01/17(金) 00:22:00.25ID:???
>>519
1000個の項目の内990フィールドの値をそのまま使いたい
残り10個は別テーブルUとJOINしてそっちのテーブルの値を使いたい
って言ってるんだから実際に千個あるんだろ
0521NAME IS NULL2014/01/17(金) 00:34:41.24ID:???
>>516
いつもの何も回答しないけど、他の人のレスを見て煽れると思ったときだけ煽る人?
0522NAME IS NULL2014/01/17(金) 08:27:31.75ID:???
DWHを見て「正規化知らねーのかよw」ってのはよくある話。
0523NAME IS NULL2014/01/17(金) 08:50:16.32ID:???
PHP+mysqliで、csvを読み込ませて中身の値がMySQL側に存在するかを確認したいのですが、

$query = "SELECT * FROM tablename where column 123456;
$result = mysqli_query($link, $query) or die('Error querying database.');
0524NAME IS NULL2014/01/17(金) 08:55:01.17ID:IZ+FJS2e
済みません、間違えました

PHP+mysqliで、csvを読み込ませて中身の値がMySQL側に存在するかを確認したいのですが、

$query = "SELECT * FROM tablename where column 123456";
$result = mysqli_query($link, $query) or die('Error querying database.');

で、指定のテーブルの特定のカラムのデータを検索して、resultの中身が空かどうか、
つまりMySQLに検索を掛けて、指定の値が存在しなかった場合を判断するにはどうすればいいでしょうか?
値が存在すると、その行のデータを引っ張ってこれるのですが、存在しなかった時の返り値の判定でつまづいています。
05255052014/01/17(金) 09:36:57.43ID:???
遅くなりました>>505です

>>506
そうなんです。そうしたいんですけど基幹なんでちょっとでも
パフォーマンス追求しといたほうがいいのかなあと…

>>515
そうですね。恐らくそういう設計だったんだと思います…
多分大昔コボルあたりのシステムを拡張拡張してきたような匂いがします

>>519
そうなんです。聞きたかったのはまさにこれでした
(実際には500項目中450ちょっとがそのまま出力。5個がjoinって感じ)


で、結果ですけどやっぱり指定して書いたほうが速いですね
面倒くさいなあ…
0526NAME IS NULL2014/01/17(金) 12:11:43.09ID:???
基幹で500カラムのテーブル作ってパフォーマンスって
まずテーブル設計が正しいのか検討するべきじゃないのかね

つか*使うだけで速さに差が出るとは思えんが
むしろ解析とコンパイル時間は短くなる気がするんだが
結局はフェッチの時間で、それは単純にデータ量に比例してるだけだろ
0527NAME IS NULL2014/01/17(金) 23:14:41.65ID:???
>>525
なんで面倒くさい?
手打ちするわけじゃあるまいし
500でも1000でも一緒
0528NAME IS NULL2014/01/17(金) 23:33:53.62ID:???
視認性も悪くなるしそういう意味では面倒くさいな
0529NAME IS NULL2014/01/17(金) 23:46:41.88ID:???
こんなのにつきあうほうが面倒くさいわ
0530NAME IS NULL2014/01/18(土) 00:57:24.69ID:???
>>524
スレ違い。
http://kohada.2ch.net/test/read.cgi/php/1384065969/
0531NAME IS NULL2014/01/23(木) 19:53:17.45ID:???
・MySQL5.6.15 MacOSXサーバ10.7
・説明
SQLの勉強をはじめまして、Macにインストールして、ターミナルでコマンドラインで打ち込んでます。

参考書によっては、テーブル名や列名が日本語になっているものがありますが
ex. 商品 登録日
半角英数字で打ち込みたいと思ってます。
ex. Shohin torokubi

質問ですが、データーはShohinと打ち込むのですが、それが日本語で「商品」であることが、解るように、どこかに入力しておくことはできないでしょうか?

プログラム言語であれば、ソースにコメントをいれられますから、Shohin #"商品"などとアンチョコを加えていけるのですが

ターミナルでコマンドラインを逐一入力して行く中で、同じようなことができるのか
調べてもなかなか難しいです。
別名 エイリアス というものがありますが、私のやりたい事とは違ったようです。

こんなことでつまづいてるのか、と思われるかもしれませんが
どうかご教授おねがいします
0532NAME IS NULL2014/01/23(木) 20:35:12.09ID:???
MySQLならcreate tableやalter tableでcommentをつけられる
詳しくはマニュアル(>>2)参照
0533NAME IS NULL2014/01/23(木) 21:37:52.38ID:???
>>532
わかりました。ありがとうございました
0534NAME IS NULL2014/01/25(土) 14:21:18.06ID:???
ディスティンクト オン (なんやら)
と
ディスティンクト なんやら
の違いがよくわかりません
0535NAME IS NULL2014/01/25(土) 14:33:51.07ID:???
何を聞いているのか
よくわかりません
0536NAME IS NULL2014/01/25(土) 14:35:49.30ID:???
>>535
エスキューエルがわからない人はむだなレスしなくていいです
0537NAME IS NULL2014/01/25(土) 15:35:25.53ID:???
ウスラバカは質問しなくていいです
0538NAME IS NULL2014/01/25(土) 15:42:15.57ID:???
真性はタヒんでください ↑
0539NAME IS NULL2014/01/25(土) 15:47:42.02ID:???
>>535
分からなかったら恥をしのんで質問してみましょう
初心者だからと言って馬鹿にする人ばっかりじゃないですよ
あなたさえ素直に「自分は馬鹿だ」と認めさえすれば
0540NAME IS NULL2014/01/25(土) 16:07:18.61ID:???
>>534
distinctはともかくとして、それにonなんて付いたかとおもってググってみたら
ポスグレの独自拡張か
DBMS名も書かないしまともに質問する気はないとみた
自分でググって調べろ
0541NAME IS NULL2014/01/29(水) 22:06:28.81ID:4wS/0iyz
質問です教えてください

データベース = access
テーブル名 = T_DATA

SQLで取得したい結果は、KEYごとに日数を取得したいのですが
重複する日数はカウントから除外したいです。
どんなSQLを書けばいいですか?

・キーは、日数=5日
・キーは、日数=1日

----------------------------------
キー, 開始日, 終了日
----------------------------------
1, 2014/01/01, 2014/01/01 |→ 日数=1日
1, 2014/01/02, 2014/01/02 |→ 日数=1日
1, 2014/01/02, 2014/01/02 |→ 日数=0日(重複)
1, 2014/01/03, 2014/01/03 |→ 日数=1日
1, 2014/01/04, 2014/01/05 |→ 日数=2日、合計=5日
---
2, 2014/01/01, 2014/01/01 |→ 日数=1日
2, 2014/01/01, 2014/01/01 |→ 日数=0日(重複)、合計=1日

↓これだと重複がカウントされてしまいます。
SELECT
キー
,SUM(DATEDIFF('d', 開始日, 終了日)+1) AS 日数
FROM
T_DATA
GROUP BY
キー
0542NAME IS NULL2014/01/29(水) 22:18:12.49ID:???
GROUP BY
キー, 開始日, 終了日
0543NAME IS NULL2014/01/29(水) 22:19:54.05ID:???
開始日、終了日とも一致するものだけ除外するなら簡単だけど
例えば
 1, 2014/01/01, 2014/01/05
 1, 2014/01/03, 2014/01/07
というデータがあったときはどうしたいんだ?
0544NAME IS NULL2014/01/29(水) 22:57:39.75ID:???
>>543を7と数えたいなら
カレンダーテーブル(日付を列挙しただけのテーブル)を
別途用意してJOINだな

select A.キー,
    count(distinct B.日付)
from  T_DATA A,
    カレンダーテーブル B
where  A.開始日 <= B.日付
and   A.終了日 >= B.日付
group by A.キー
;
0545NAME IS NULL2014/01/30(木) 13:33:51.25ID:e3L2IJPl
返信が遅くなってすみません

>>542
 SQLを覚えてから日が浅く、間違ってたようですね。
 訂正ありがとうございます。

>>543
 1, 2014/01/01, 2014/01/05
 1, 2014/01/03, 2014/01/07

キーが同じで開始〜終了間が跨るデータは
存在しませんの大丈夫です。
必ずこんな感じになります。

 1, 2014/01/01, 2014/01/05
 1, 2014/01/05, 2014/01/05
 1, 2014/01/05, 2014/01/08

>>544
やっぱり簡単にはできないんですかね。
SQL実行前にテーブルを作成して終わったら削除する
しかないんですかね。サクっとはできないみたいですね。
初心者には難しいorz
0546NAME IS NULL2014/01/30(木) 15:21:13.83ID:???
> SQLを覚えてから日が浅く
> 簡単にはできないんですか
> 初心者には難しいorz

役満でもねらってんのかと思った。
カレンダー作るのが考え方からも、SQLの見やすさからも簡単だと思うが。

> 必ずこんな感じになります。
を信用するなら、1行前のレコードとの比較を行えばできるけどサブクエリになるよ
0547NAME IS NULL2014/01/30(木) 15:29:01.05ID:???
>>541
重複を除去するクエリをつくる
そのクエリももとに、日数を計算するクエリをつくる
そのクエリをもとに、日数をカウントするクエリをつくる

頑張れば1つのSQLで出来なくもないんだけど
合計三つクエリ作れば、一つ一つは簡単にできるだろ
0548NAME IS NULL2014/02/02(日) 15:38:59.45ID:???
DB
MySQL 5.1

テーブル
date (datetiem) | value(double)
------------------|----------------
2014-02-02 14:28:00 | 20.1
2014-02-02 14:29:00 | 20.1
2014-02-02 14:30:00 | 20.1


時間とデータが格納されたテーブルがあり、1分ごとにデータが追加されます。
ここから最新24時間分のデータを取りだし、1440個の値でグラフを描画しています。
where date > (now() - INTERVAL 24 HOUR)
としています。

毎分データが更新されている間は問題ないのですが、データ更新が止まって
結果が1440個取れない時にグラフ描画が抜けてる分の時間を詰めて書いてしまいます。

グラフを書いているプログラムは手を入れるのが難しいため、SQLでどうにかしたい
と思っています。

取得する時点で、1440固定にして、抜けている間はたとえば99999.99と帰って
くる様なSQLは掛ける物でしょうか?

よろしくお願いします。
0549NAME IS NULL2014/02/02(日) 15:56:10.94ID:???
>>548
>>8
存在しないデータを生成するのはSQLの正しい使い方じゃない

そもそもプログラムに手を入れれないのに、そのプログラムが発行するSQLは修正できるのか?
グラフ書く前にプログラム1本かまして、抜けてるデータ補完すればいいんじゃね
0550NAME IS NULL2014/02/02(日) 15:57:52.51ID:???
抜けてる部分は補完して1440にすればいいのか、抜けたまま1440取ればいいのか分からん
たとえば1,2,3,4,5とあって大きい順3つ取ったときに3,4,5になるだろうが1,2,3,NULL,5になったときに2,3,5を取るのか3,NULL,5を取るのか
0551NAME IS NULL2014/02/02(日) 16:00:03.77ID:???
抜けているところを詰めないグラフの描き方にするほうが簡単だと思うが
Excelで言う散布図
0552NAME IS NULL2014/02/02(日) 16:00:10.53ID:???
1分ごとにデータが追加するプログラムに手を入れてで何とかするとか
05535052014/02/02(日) 16:05:23.92ID:???
描く側で1分以上空いてたら99999.99扱いにする方がいいんでない
05545482014/02/02(日) 16:58:17.47ID:???
>>549-553
やっぱりプログラムに手を入れるのが正しいですよね。

SQLとプログラムは切り離したとかでSQLが外部定義
されているため、そこだけでどうにかなればと思ったの
です。

プログラムの修正が出来なかった場合は、毎日日替わり前に
翌日の1440個分のレコードを追加するバッチ処理を走らせて
外部定義のSQLはINSERT〜ON DUPLICATE UPDATEで
逃げることも検討します。

ありがとうございました。
0555NAME IS NULL2014/02/06(木) 18:43:16.33ID:TQ+RMbfO
>>553
そんなバナナ・・・
0556NAME IS NULL2014/02/07(金) 17:43:12.64ID:6HCqv+Ve
SQLという高レベル言語を使うことで生産性を高めたはずなのに
実際にパフォーマンスを出すためには低レベルの内部実装を知らなければならず
不必要に抽象化されているために逆に生産性が落ちるという矛盾
どうやってこの矛盾を解決したらいいでしょうか?
0557NAME IS NULL2014/02/07(金) 17:57:40.73ID:???
この世から解脱すれば良い
0558NAME IS NULL2014/02/07(金) 18:08:42.48ID:???
プログラマーを辞めれば解決
0559NAME IS NULL2014/02/07(金) 18:38:16.28ID:???
>>556
> 不必要に抽象化されているために逆に生産性が落ちる
ここを解決する。というか、大抵の人はそうならないから、解決するまでもなく矛盾が発生していない
0560NAME IS NULL2014/02/07(金) 19:28:32.08ID:???
>>556
Oracleなんて化石DBを使うからいけない
0561NAME IS NULL2014/02/07(金) 19:37:16.83ID:???
>>556
まず自分の勉強不足を恥じて勉強すればいいんじゃない

>>560
なぜOracle限定
0562NAME IS NULL2014/02/08(土) 00:44:26.58ID:???
>>556
まさかとは思いますが、この「抽象化」とは、あなたの想像上の存在にすぎないのではないでしょうか。
0563NAME IS NULL2014/02/10(月) 18:06:21.15ID:OQp1mlVB
大きな疑惑を残している質疑応答

http://music.geocities.jp/jphope21/0203/31/200_1.html

2008年10月28日に開かれた参院外交防衛委員会でのことだ。

( http://music.geocities.jp/jphope21/0103/33/217.html )
0564NAME IS NULL2014/02/12(水) 12:35:00.27ID:???
>>556
元々、無謀なほど冗長な実装をされているDBだからだと思う。
SQLの問題ではない。
0565NAME IS NULL2014/02/13(木) 09:43:09.66ID:jLeG5sV2
今日、生まれて初めてUNIONを使った
感激したよ!
0566NAME IS NULL2014/02/13(木) 11:09:34.31ID:???
mysql 5.5.19
update教えてください^^;
stock_masterのcomment_textカラム(varchar(50))に
株式分割割当日 yyyy/mm/dd
の形式で入っているものを
権利付最終日 yyyy/mm/dd
に訂正したいと思い
update stock_master
set comment_text = "権利付最終日%"
where comment_text like "株式分割割当日%";
としたら
権利付最終日%
になってしまいました

これ、"株式分割割当日"だけを訂正したいのですが。
0567NAME IS NULL2014/02/13(木) 11:16:20.53ID:???
適当に書いたけど、使うのはREPLACEじゃね

UPDATE stock_master
SET REPLACE (stock_master,"株式分割割当日","権利付最終日")
0568NAME IS NULL2014/02/13(木) 11:27:15.95ID:???
>>566
文章が超絶に読みにくいな…ソースも汚そう
0569NAME IS NULL2014/02/13(木) 11:45:20.26ID:???
>>567
ありがとうです〜 replace初めて知りました

update stock_master
set comment_text = replace(comment_text,"株式分割割当日","権利付最終日");
で修正出来ました。
0570NAME IS NULL2014/02/13(木) 22:55:00.02ID:???
ブログで、とある記事を読んだ人が他に読んでいることが多い記事をレコメンドしたいのですが、
どうすればいいのでしょうか。

あるセッションのユーザーが読んだ記事の主キーを記録。
ユーザーAが記事1,3,4,5を読む。
ユーザーBが記事2,4,5を読む。
ユーザーCが記事1,4,5を読む。

これをこんな風に1レコードずつ記録していって
記事1→記事3
記事1→記事4
記事3→記事5
記事3→記事4
記事3→記事5
記事4→記事5

としたらよく共に読まれている記事が、評価するのは相対値でもいいですし絶対値でもいいんですが、
決められると思います。


問題は
・煩雑過ぎる
・レコードがあっという間にたまる

ということです。

何か他に良いテーブル設計はないのでしょうか?
0571NAME IS NULL2014/02/13(木) 23:01:51.37ID:???
セッション毎に貯めておいて、一気に一連の閲覧履歴を書き込んだら?
0572NAME IS NULL2014/02/14(金) 00:03:28.39ID:???
>>570
どんな規模のサイトか知らないけど、記事を読むたびにリアルタイムでDBに記録しようとしたら
相当重くなるんじゃないかな。
そういう何かをカウンして表示するみたいなのってリアルタイムで処理する必要性はほとんど無い。
だからまずはテキストデータか何かに保存しておいて、10分に1回とか決めて>>571が書いてあるように
一気に閲覧履歴を書き込んでいけば良いと思う。

あと閲覧記録が溜まりすぎるのを防ぐため、今度は1日1回くらいの感覚で古いのを削除していくとか、
データをまとめていくとかしていけば良いと思う。
0573NAME IS NULL2014/02/14(金) 13:40:17.99ID:???
>>572
(人間が)ブログを読む程度の頻度のDB更新が重いわけないじゃんw
0574NAME IS NULL2014/02/14(金) 14:48:05.80ID:HP3AcTSH
>>572
WordpressのWhere did they go from hereっていうプラグインが同じようなことしてるから参考にしてみれば
ただしこれはオススメ表示じゃなくて管理人が参考にするためのデータ取りプラグインな
0575NAME IS NULL2014/02/15(土) 00:31:46.73ID:???
>>570
思いつきで書くけど

記事が読まれる都度、アクセス元IPと記事番号、タイムスタンプをアクセスログに記録

レコメンドは、当該記事番号に一致し、今回のアクセス元に一致しないIPをアクセスログから取得し
アクセスログから、取得したIPリストで絞込み、記事番号とアクセス数上位N番までを表示する

アクセスログは適当なタイミングで古いものを消去

とか
05765702014/02/16(日) 20:10:14.60ID:???
皆さんありがとうございました。

定期処理バッチみたいなものを作ることを視野に入れてみます。
0577NAME IS NULL2014/02/21(金) 11:52:51.67ID:???
こんなSQLがあります。

select id, name, utime
from something
order by utime desc;

このとき、idが、ある指定された値までは読み飛ばし、それ以降のレコードを取得するにはどうしたらいいですか。
ポイントは、
* id順とutime順とで順番が異なること
* ソートキーは utime だが、読み飛ばす条件は id を使っていること

whileループなら簡単な処理ですが、SQLだとどうするのでしょうか。

(使用DB: PostgreSQL 9.3)
0578NAME IS NULL2014/02/21(金) 12:05:47.18ID:???
select s.id, s.name, s.utime
from something as s
where s.id > XXX
order by s.utime desc;
0579NAME IS NULL2014/02/21(金) 12:11:39.80ID:???
>>578
それ以降のレコードに、指定したidより小さい値があったら表示されないんじゃ?
0580NAME IS NULL2014/02/21(金) 12:54:38.08ID:???
>>579
はい、そうなんです。だから困ってるんです。
where句の中で変数を設定できるといいんですが。
0581NAME IS NULL2014/02/21(金) 13:00:13.12ID:???
select id, name, utime
from something
where utime < (select utime from something where id = XXX)
order by utime desc;
0582NAME IS NULL2014/02/21(金) 14:42:26.79ID:???
>>580
where s.id > 指定した値
order by s.id, s.utime desc;
0583NAME IS NULL2014/02/21(金) 14:49:11.06ID:???
idはint、utimeはtimeでいいんよな?
0584NAME IS NULL2014/02/21(金) 15:08:45.27ID:???
>>581
これって、速度的には大丈夫なんでしょうか。
副問い合わせが何回も実行されてしまいそうですが。
あと、utime が同じレコードがあると使えないような。

>>582
ソートキーは utime です。idは使わない。
0585NAME IS NULL2014/02/21(金) 15:29:10.58ID:???
>>577
同じ時刻があるとおかしくなるけど、これが一番近い結果が得られるかな?
utime にINDEXを貼れば実用的な速度で動くはず。

SELECT id,name,utime FROM something WHERE utime>=(SELECT utime FROM something WHERE id=2) ORDER BY utime DESC;
0586NAME IS NULL2014/02/21(金) 15:46:21.05ID:???
>>584
まず、元のやりたいことの説明が下手すぎる。

> 副問い合わせが何回も実行されてしまいそうですが。
ない。不安なら計画見れば。

> あと、utime が同じレコードがあると使えないような。
whileループならできるんでしょ。それならできる。
0587NAME IS NULL2014/02/21(金) 20:17:54.55ID:???
なんでもかんでもSQLでやることないだろ
AP側でやれば何にも問題ない
0588NAME IS NULL2014/02/22(土) 06:56:21.81ID:???
>>587
1億件あって、対象のidが99999990件目にあるとしても同じようにAPでやればいいというのだろうか。
0589NAME IS NULL2014/02/22(土) 08:09:17.36ID:???
>>588
極端なやっちゃなぁ
なんでもかんでもAP側でやれ、とも言ってないだろ
0590NAME IS NULL2014/02/22(土) 08:23:39.94ID:???
>>589
全部でレコードが1億件あったとしても、
抽出したレコードに対して何らかの処理をAP側でやるわけだろ?
その(抽出した)レコードが10件とは限らん。
結果として99999990件抽出されて、捨てられる側が10件になるかも知れんし
0591NAME IS NULL2014/02/22(土) 08:27:02.94ID:???
まぁ、読み直したが、別に上で例が示してあるように、
副問い合わせでidで絞り込んで、utimeでソートするだけのこと
何にも特別な処理じゃないだろ
0592NAME IS NULL2014/02/22(土) 09:27:21.23ID:???
>>588
いいんじゃね?
一億件ぐらいなら、当然 b-tree なりのアルゴリズム使うだろうしり。
まさか、線形サーチしか知らんと言うオチなの?
0593NAME IS NULL2014/02/22(土) 16:11:56.24ID:???
使うだろうしり?
0594NAME IS NULL2014/02/22(土) 16:12:41.33ID:???
お前らってアルゴリズムとか楽しくてやってるの?
それとも仕事だから嫌々?
0595NAME IS NULL2014/02/22(土) 17:25:44.97ID:???
仕事であればできあいのライブラリを選ぶわ
0596NAME IS NULL2014/02/22(土) 17:38:06.49ID:wcM5HXSQ
>>588
人の揚げ足取りばっかやって楽しいか、この糞野郎
0597NAME IS NULL2014/02/22(土) 18:21:29.80ID:???
>>592
対象のIDではソートされてないんだよ。
まぁ別途ツリー作ればいいだけだけど
0598NAME IS NULL2014/02/22(土) 18:42:52.89ID:???
ウワァ。

>>589
どういう基準でAPでやれといっているのかわからんが、この場合はクエリでやるべきでしょ。
質問者の理解度ならそういう、APでやったほうが速いみたいな考えにもなるのかもしれんが。

>>590
君はwhere句を使わない主義なのか?富豪的プログラミングの極地にいるのか?
捨てられる側が何件かによらず、行える絞込みは行っておくべきだろう。

>>591 うん。それだけの話。>>581をかいたら>>584をいただいた。

>>592
さすがにそのオチはないけれど、通常b-treeインデックスを作成してDBMSにやらせるよね。
質問者の理解度ならインデックス相当のツリーをAPで抽出のたびに構築するようなことを考えるのかもしれんが。
0599NAME IS NULL2014/02/22(土) 20:56:52.87ID:???
こういうSQLがあって、
select groups.name as "group", members.name as "member"
from groups
join members on groups.id = members.group_id
order by groups.id, members.id;

実行結果はこうなっています。
group | member
--------------------+-----------------
麦わら | ルフィ
麦わら | ナミ
麦わら | チョッパー
木ノ葉隠れの里 | ナルト
木ノ葉隠れの里 | カカシ

ここで、memberに対してグループごとの連番をつけるにはどうしたらいいですか。
希望する出力結果はつぎのとおり

group | num | member
--------------------+-----+--------------
麦わら | 1 | ルフィ
麦わら | 2 | ナミ
麦わら | 3 | チョッパー
木ノ葉隠れの里 | 1 | ナルト
木ノ葉隠れの里 | 2 | カカシ

なおPostgres 9.2です。よろしくお願いします。
0600NAME IS NULL2014/02/22(土) 22:27:29.94ID:???
>>599
自己レス。
Postgresでは「row_number()」という関数でできるそうです。

select groups.name as "group"
, row_number() over (partition by groups.id order by members.id)
, members.name as "member"
from groups
join members on groups.id = members.group_id
order by groups.id, members.id;
0601NAME IS NULL2014/02/22(土) 23:04:28.03ID:???
>>597
b-tree 知らんのか?
0602NAME IS NULL2014/02/22(土) 23:15:29.26ID:???
>>598
おまえなに偉そうに上から目線で評論家か採点者みたいに
いちいち1つずつをまとめてレスしてんだ?
お前が一番うっぜーやつだな
0603NAME IS NULL2014/02/23(日) 01:28:05.55ID:???
>577
select id, name, utime from
(select * from something where id>指定値) t
order by utime desc;
じゃないのか?
0604NAME IS NULL2014/02/23(日) 01:44:39.93ID:???
だから、こんな別になんでもないSQLになんで大騒ぎしてるんだ?
0605NAME IS NULL2014/02/23(日) 01:47:30.80ID:???
>>603
いまさらで、さらに全く違う結果吐くクエリ書いて何がしたいの?
0606NAME IS NULL2014/02/23(日) 03:45:43.49ID:???
>>577
idとutimeがユニークなのかどうか示されてないから考える気にもならん
0607NAME IS NULL2014/02/23(日) 04:09:28.81ID:???
idって列に対してある条件で読み飛ばした結果に対してutimeって列でソートするだけなのに、こんな質問してるってことは前提条件がそもそも何かおかしいんだろ?
エスパーの俺が想像するに
0608NAME IS NULL2014/02/23(日) 04:14:00.21ID:???
>>607
エスパー失格だわ
0609NAME IS NULL2014/02/23(日) 18:00:35.87ID:???
>>605
>>603が全く違う結果っていうなら、データと欲しい結果の例書いてくれ
0610NAME IS NULL2014/02/23(日) 19:52:40.94ID:???
>>609
>>605じゃないが例を書こう。

ID name utime
10 太郎 2014/02/23 14:00:00
20 二郎 2014/02/23 15:00:00
30 三郎 2014/02/23 16:00:00
15 花子 2014/02/23 17:00:00

例えばID20以降に登録されたレコードが欲しい時、ID15も欲しい対象となる(>>580参照)から、
>>603のSQLは意図しているものとは全く違う結果となる。
つかそれって()で括らなくても普通にwhereで書いてるのと同じじゃね?
0611NAME IS NULL2014/02/23(日) 19:54:41.09ID:???
>>609
>>578と同じ間違いをしてるってことでしょ。
あと、>>603でサブクエリにした意図を教えてほしい。
0612NAME IS NULL2014/02/25(火) 15:10:52.06ID:???
>>610
そんなの、id がユニークじゃなかったら破綻するじゃん。
そもそもだけど、なんらかの条件で id が割り当てられてるんだろ?
その条件のときの utime を素直に記録しておくべき。
前提となるシステムの考え方がクズすぎる。
SQLを解くパズルだったら別だけど
0613NAME IS NULL2014/02/25(火) 16:53:43.94ID:aF4ND4bJ
ユニークにしないシステムがあるのか?
メンテが大変そうだな
0614NAME IS NULL2014/02/25(火) 17:04:58.96ID:???
>>613
自分の想像のなかだけで遊んどけ
0615NAME IS NULL2014/02/25(火) 17:21:03.34ID:???
>>612
著しく本題から外れたレスをするのもエスパーならではなのかい?
0616NAME IS NULL2014/02/25(火) 17:25:45.69ID:aF4ND4bJ
普通はidはユニーク、nameはユニークではない
になるんじゃ?
0617NAME IS NULL2014/02/25(火) 17:38:27.58ID:???
PostgreSQLでidにserialを使わない奴は変態
0618NAME IS NULL2014/02/25(火) 20:00:03.01ID:???
IDの意味を考えたらユニークにするわな、普通
0619NAME IS NULL2014/02/25(火) 20:32:45.43ID:???
おいおい、いつからSQLの列名は"意味"まで定まるようになったんだよ?
0620NAME IS NULL2014/02/25(火) 20:58:09.33ID:???
何らかのアイテムそれぞれに割り振る用途の「ID」といえば一般に「Identifier」の略。
ユニークじゃなかったら identify できない。
SQL関係ない。言葉そのものの意味の話。
0621NAME IS NULL2014/02/25(火) 21:14:18.04ID:???
ほう、文学青年()がいるな
だが、技術者としては失格だな
0622NAME IS NULL2014/02/25(火) 21:29:45.24ID:???
id だから UNIQUE って、もうメチャクチャやなw
あんたら、たとえばサイトにログインする時、
ID と パスワード 入力するやろ?
その ID って UNIQUE と思ってんのか?
0623NAME IS NULL2014/02/25(火) 21:32:19.08ID:???
常識の通じない技術者って困るよな
0624NAME IS NULL2014/02/25(火) 21:36:49.94ID:???
 
普通はIDはユニークだよ。むしろユニークでない例を挙げてみたらいい。
0625NAME IS NULL2014/02/25(火) 21:53:33.76ID:???
小中学校とかの出席番号はクラス内だけではユニークかもしれないけど、
学年・学校とおしてはユニークではないね
UNIQUE ( 年次, クラス, 出席番号 )
とかしないとね
0626NAME IS NULL2014/02/25(火) 21:57:45.10ID:???
>>625
IDに相当するのは学生番号とかじゃないの?
出席番号だと進級したら変わってしまいそう。
0627NAME IS NULL2014/02/25(火) 22:08:38.62ID:???
おまえら名前や見た目で人を判断しちゃいけないって言われてきたろ?
0628NAME IS NULL2014/02/25(火) 22:36:18.83ID:???
>>622
そっか、じゃあ僕がパスワードを間違えたらたまたま他のユーザでログインできちゃうかもしれないのか。
0629NAME IS NULL2014/02/25(火) 22:50:19.08ID:???
お前らいつまでIDがどうとか見当違いな話してんの?
0630NAME IS NULL2014/02/25(火) 22:55:06.63ID:???
次の質問が来るまで
0631NAME IS NULL2014/02/26(水) 00:40:39.68ID:???
まぁ、暇つぶしみたいなもんかな
分かっててやりあってるだろ、おまえらwww
0632NAME IS NULL2014/02/26(水) 00:52:43.16ID:???
妙にかみつき気味の人はたぶん本気でわかってないと思う。
もう終わってる話なのにね
0633NAME IS NULL2014/02/26(水) 03:21:27.17ID:???
id がユニークでなかったら破綻するじゃん、とどや顔で書いたから引っ込みつかなくなってるだけだろ (w
0634NAME IS NULL2014/02/26(水) 16:04:53.02ID:???
>>633
あなたのことでは…
0635NAME IS NULL2014/02/26(水) 18:09:01.21ID:???
早速おでましです (w
0636NAME IS NULL2014/02/27(木) 00:02:49.68ID:???
idは非ユニークだろうと予想してるのはたぶん一人
0637NAME IS NULL2014/02/27(木) 00:06:51.22ID:???
後学のためにも、idを非ユニークとして使うシステムにどういうものがあるか知りたい
0638NAME IS NULL2014/02/27(木) 00:39:44.85ID:???
マジレスしてやろう。
ユーザーとかそういうのを認識するのには確かにユニークなIDが必要。
けど一つ一つのテーブルにユニークなIDが必要なわけではない。
例えばアクセスログを溜め込むテーブルとか。>>577のも多分そういうのだろ。

で、なんでシステムの話してんの?
0639「ガスライティング 集団ストーカー カルト」で検索を!2014/02/27(木) 01:31:37.85ID:nmwQAF0x
★マインドコントロールの手法★

・沢山の人が偏った意見を一貫して支持する
 偏った意見でも、集団の中でその意見が信じられていれば、自分の考え方は間違っているのか、等と思わせる手法

・不利な質問をさせなくしたり、不利な質問には答えない、スルーする
 誰にも質問や反論をさせないことにより、誰もが皆、疑いなど無いんだと信じ込ませる手法


↑マスコミや、カルトのネット工作員がやっていること

TVなどが、偏った思想や考え方に染まっているフリや常識が通じないフリをする人間をよく出演させるのは、
カルトよりキチガイに見える人たちを作ることで批判の矛先をカルトから逸らすことが目的。

リアルでもネットでも、偽装左翼は自分たちの主張に理がないことをわかっているのでまともに議論をしようとしないのが特徴。
,,...
0640NAME IS NULL2014/02/27(木) 02:50:08.56ID:???
>>607
ちょっと違う
順不同なidをソートされたものとして考えてる質問者に対して
できねーよタコと答えない全員がおかしい
0641NAME IS NULL2014/02/27(木) 03:01:47.48ID:???
>>638
Id が非ユニークなものの話してるのに、Id 無しのテーブル持ってきてどや顔でマジレスしてやろうとか、うけるわ〜
0642NAME IS NULL2014/02/27(木) 03:49:04.48ID:???
>>640
> 順不同なidをソートされたものとして考えてる質問者
ダウト
0643NAME IS NULL2014/02/27(木) 04:08:34.76ID:???
>>638
そういうのじゃない。
>>577のテーブルにおいてidがユニークであることはある程度容易に想像できる。

>>577だけじゃわからなかったとしても、その後の流れで気づけそうなもんだけど。
0644NAME IS NULL2014/02/27(木) 08:26:42.56ID:???
ユニークじゃないケースも容易に想像できるぜ。idとutimeの複合キーとか。
0645NAME IS NULL2014/02/27(木) 09:21:38.96ID:???
>>641
元々非ユニークの話をしてねーよ。>>612からこんな話になってるんだよ。

>>643
>>612は想像出来てないんだなこれが。
0646NAME IS NULL2014/02/27(木) 09:35:11.65ID:???
ユニークである必要なんて元々ない話でしょ。
0647NAME IS NULL2014/02/27(木) 09:43:03.67ID:???
お騒がせしてます。
元々の質問者の >>577 です。
質問中の ID はUNIQUEではありません m(_ _)m
0648NAME IS NULL2014/02/27(木) 09:54:34.43ID:???
MySQL 5.5.28を使用しています。

テーブルAとBを対象として
以下の出力結果を取得したいと考えているのですが、
どのようなSQL文を記述すればよいでしょうか?

どなたかお知恵を拝借させてください。

1.テーブルAの「item_cd」と「use_date」を抽出。

2.テーブルBから、以下の条件で「status」を抽出。

  “「item_cd」が一致”
  “「use_date」を起点とした直近の「chg_date」”

  ※条件に該当するレコードがない場合はNULL。

3.1〜2により、テーブルAの各レコードについて
  「item_cd」の「use_date」時点における「status」を出力。


【テーブルA】(キー:id)
------------------------------------------
id item_cd use_date
------------------------------------------
1 111 2012-04-01
2 111 2013-04-01
3 111 2014-04-01
4 222 2014-04-01
5 333 2014-04-01

【テーブルB】(キー:item_cd + chg_date)
------------------------------------------
item_cd status chg_date
------------------------------------------
111 11 2013-01-01
111 12 2014-01-01
222 21 2012-01-01

【出力結果】
------------------------------------------
id item_cd use_date status chg_date
------------------------------------------
1 111 2012-04-01 NULL NULL
2 111 2013-04-01 11 2013-01-01
3 111 2014-04-01 12 2014-01-01
4 222 2014-04-01 21 2012-01-01
5 333 2014-04-01 NULL NULL


以上です。
よろしくお願いします。
0649NAME IS NULL2014/02/27(木) 10:24:32.03ID:???
>>647
本人か?
本人なら、複数あった場合にどの Id (普通は最初か最後だろうが) まで読み飛ばしたいか書かないと答えは出ないぞ。
0650NAME IS NULL2014/02/27(木) 10:27:30.88ID:???
>>645
Id が無いテーブルの話してるのは君だけ
誰でも知ってるようなことなので、いちいち書かなくてもいいよ
0651NAME IS NULL2014/02/27(木) 11:01:06.49ID:???
>>648
>「item_cd」の「use_date」時点における「status」を出力。
(2で該当した)chg_date時点、じゃないのか?
(chg_dateが)use_date時点で、ってなら
出力結果の4行目は
4 222 2014-04-01 NULL 2012-01-01
じゃないとおかしいぞ

とりあえず動くかどうか知らんが、こんなクエリ書いてみた
select
x.id,
x.item_cd,
x.use_date,
y.status,
x.chg_date
from
(select
id,
item_cd,
use_date,
(select max(chg_date) from テーブルB where item_cd=a.item_cd and chg_date<=a.use_date) as chg_date
from テーブルA a ) x
join
テーブルB y
on x.item_cd=y.item_cd and x.chg_date=y.chg_date
もうちょっと綺麗に書ける気がするけど、まあしらん
0652NAME IS NULL2014/02/27(木) 11:08:09.74ID:???
あ、inner joinじゃだめだな
left outer joinにしといてくれ
0653NAME IS NULL2014/02/27(木) 13:56:05.68ID:???
>>651

>(2で該当した)chg_date時点、じゃないのか?

ご指摘のとおり、

3.1〜2により、テーブルAの各レコードについて
  「item_cd」の(2で該当した)「chg_date」時点における「status」を出力。

と書くのが適切でした。

出力結果もばっちりで、SQL文も理解できそうです。
ありがとうございました。
0654NAME IS NULL2014/02/27(木) 15:40:59.45ID:???
・DBMS名とバージョン
  MySQL 5.5.27
・テーブルデータ
  現在のところ無し
・・欲しい結果
  ブログのシステムに酷似しているシステムを構築しようとしています。記事の検索システムも実装しようかと考えております。
  全てのページはPHPページで,、処理の分岐などもPHPによって行うつもりです。
・質問
  データベースにテキストとhtmlタグを保存しようと考えているのですが、この場合、
  もし自分がこの先MySQLを用いた検索機能を実装して検索の時に、
  中のhtmlタグをも検索対象にしてしまうのではないかと危惧しているのですが、どうでしょうか?
  自分の考えたこの問題の解決する方法では、
  検索したくない特定のhtmlタグをあらかじめ指定しておき、検索結果から弾くなどの方法を考えていますが、この方法は可能でしょうか?そして合理的でしょうか?
  何かこの件に関して知っている事がある人に何かしらご教授頂けたら幸いです。
  宜しくお願い致します。
0655NAME IS NULL2014/02/27(木) 15:52:20.69ID:???
>>データベースにテキストとhtmlタグを保存
って1フィールドに生のhtmlぶち込むって話?
それとも本当にタグだけ分けてんの?
0656NAME IS NULL2014/02/27(木) 16:23:08.95ID:???
>>655
>>>>データベースにテキストとhtmlタグを保存
>>って1フィールドに生のhtmlぶち込むって話?
はい、その通りです。ですが、あくまで記事の本文のみです。
日付やタイトルの部分にはデータベースから該当するデータを読み込んで、
それらのデータを、htmlタグの書かれたテンプレート(PHPページ)の各部位、に読み込んで表示させる予定です。

ただ記事本文には途中で画像を入れたり、特定の文字列をハイパーリンク化したりしたいので、
やはりデータベースにテキストとhtmlごと入れざるを得ないのかな、と考えています。
0657NAME IS NULL2014/02/27(木) 16:37:06.78ID:???
>>656
検索用にタグを取り除いたものを用意するとか。スレ違いだけど。
0658NAME IS NULL2014/02/27(木) 16:42:12.43ID:???
>>657
なるほど。それも選択肢の一つとして持っておきたいと思います。
どうやら聞くスレを間違えてしまったようなので、別のスレで聞いてみようかと思います。
有難うございました。
0659NAME IS NULL2014/02/28(金) 07:31:36.68ID:7u/9HN+D
すいません、少々お聞きしたいのですが、

テーブル X(更新用の情報)
ABCD

テーブルY (更新対象のテーブル)
ABCDEFG.....

上記のようにテーブルがあった場合、XのA列とYのA列、XのB列とYのB列を紐付けて、
YのC列、D列の値をXのC列、D列の値へ変更したいのですが、どのようなSQLを組めばよいのでしょうか。
0660NAME IS NULL2014/02/28(金) 07:35:50.68ID:7u/9HN+D
Update Y y
SET
y.C = (
select C from X x
where
y.A = x.A
and
y.B = x.B
),
y.D = (
select D from X x
where
y.A = x.A
and
y.B = x.B
),
想定としてはこんな感じで考えてはいるのですが、これだとうまくいかない気がするため、
ご指摘をお願い致します
0661NAME IS NULL2014/02/28(金) 07:52:14.82ID:???
どのDBなのかも書かず、オマケに「いかない気がする」ってw
0662NAME IS NULL2014/02/28(金) 08:41:20.19ID:7u/9HN+D
失礼しました。
oracleです。

まだ実際に動かしてみることが出来ないので、
想定で必要なSQLを組んでいる状況です。
0663NAME IS NULL2014/02/28(金) 09:39:50.90ID:???
>>662
試用版があるだろう
0664NAME IS NULL2014/02/28(金) 16:06:02.35ID:???
>>660
それでもいいと思うけど。

oracleならこうかけるんじゃないかなぁ。
update
(select x.c xc, x.d xd, y.c yc, y.d yd from x join y using (a, b))
set yc = xc, yd = xd

と、マニュアルを見て思ったんだけど。環境できたら試してみて。
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/statements_10.html#23664
0665NAME IS NULL2014/03/01(土) 07:21:13.98ID:???
>>662
12c でないとダメとか、Enterprise Manager が必要とか、贅沢言わないなら Express Edition でいいんじゃね?
https://blogs.oracle.com/oracle4engineer/entry/column_xe_11g1
0666NY2014/03/09(日) 01:20:10.31ID:TmYJmE4Z
ZUsZhw http://www.QS3PE5ZGdxC9IoVKTAPT2DBYpPkMKqfz.com
0667NAME IS NULL2014/03/11(火) 16:29:15.89ID:???
select id from table1 where .... ;
というselect文では複数のidが返ってきますが、これを「,」で連結して、1つの文字列として取得することは可能でしょうか。
JavaScript でいうところの ['1', '2', '3'].join(',') というイメージです。
DBはPostgreSQL 9.2です。よろしくお願いします。
0668NAME IS NULL2014/03/11(火) 16:54:40.91ID:???
>>667
自己解決しました。
Postgresでは select array_to_join(array_agg(id), ',') from table1 where .... でいけました。
またMySQLにはgroup_concat()という関数があって、これで実現できるようです。
参考:
ttp://stackoverflow.com/questions/194852/concatenate-many-rows-into-a-single-text-string
0669NAME IS NULL2014/03/11(火) 16:59:50.73ID:???
うん。array_to_stringね。
0670NAME IS NULL2014/03/11(火) 17:25:28.41ID:???
横からそれるけど、そういう関数がなければストアドファンクションで連結って事になるんだろうか?
0671NAME IS NULL2014/03/11(火) 17:45:47.95ID:???
うちはいつもアプリでがんばってた。
縦持ちしてる複数のフラグを横並びチェックボックスにするとか、そういう状況のときに。
0672NAME IS NULL2014/03/11(火) 18:33:37.70ID:???
再帰SQLで無理やり書いたことあるな
単に縦横変換するだけならそういう命令があるDBMSもあるけど
文字列にして連結とか普通はアプリでやるんじゃね
アプリの表示の問題以外で連結する理由がみつからんし
0673NAME IS NULL2014/03/11(火) 21:16:13.73ID:???
上位2件を連結するのなら前に作った
limit 外せばそのまま全件になると思う
>>322
0674NAME IS NULL2014/03/11(火) 21:37:27.47ID:???
なんかその辺見覚えある流れだなぁと思ったら >>332 が俺だった。
0675NAME IS NULL2014/03/14(金) 17:41:26.44ID:???
テーブルにある全ての行数を取得したいんだけど
COUNT(テーブル名);はできないよね

たぶん以下のどちらかだと思うんだけど(1)の方がよいよね?
(1). COUNT(主キー) FROM テーブル名;
(2). COUNT(*) FROM テーブル名;
0676NAME IS NULL2014/03/14(金) 17:46:36.27ID:???
>>1
0677>>6752014/03/14(金) 20:10:43.75ID:???
データベースの種類はHSQL ver2.3 です。
0678NAME IS NULL2014/03/15(土) 05:32:20.68ID:???
外部結合すると主キー項目でもNULLで戻ってくる気が
最適化考えてもCOUNT(*)の方が良いような
0679NAME IS NULL2014/03/15(土) 08:49:02.11ID:???
外部結合するなんて>>675のどこにも書いていない
0680NAME IS NULL2014/03/15(土) 09:02:11.54ID:???
ね。
エスパー様かもしれないよ。
0681NAME IS NULL2014/03/15(土) 11:06:54.09ID:???
>>675
主キーならインデックス張られてるだろうから (1) の方が速いらしい
http://www.geocities.jp/mickindex/database/db_optimize.html#LocalLink-count

まあ、気になるなら実データで測定すりゃいいと思うよ
0682NAME IS NULL2014/03/15(土) 12:34:43.45ID:???
中身は問わず純粋にレコード数を知りたいなら、SELECT COUNT(1) でいいと思うけど。
0683NAME IS NULL2014/03/15(土) 16:52:50.36ID:???
>>681-682
そのへんはほとんど過去のバッドノウハウだと思うが

気になるならまずは実行計画確認しろと
0684NAME IS NULL2014/03/15(土) 20:58:32.11ID:???
オプティマイザ信じてやれよ
0685NAME IS NULL2014/03/18(火) 07:43:22.92ID:???
テンプレ>>4を下記のようにした場合、
IDごとの最新日付レコードではなく、全IDのうち最新日付を持つレコード1つが
抽出されるのは何故でしょうか?


SELECT Sheet1.ID, Sheet1.ストック, Sheet1.調査日
FROM Sheet1
WHERE (((Sheet1.調査日)=(select max(Sheet1.調査日)from Sheet1 )))
GROUP BY Sheet1.ID, Sheet1.ストック, Sheet1.調査日;
0686NAME IS NULL2014/03/18(火) 10:17:43.11ID:???
そこから GROUP BY 外して結果見てごらん
その結果を GROUP にまとめてるわけ。
0687NAME IS NULL2014/03/19(水) 11:29:25.34ID:???
テーブルPersonが参照している複数のPersonを取得したいのですが助言ください。

「テーブル」
Person { id, name }
Friend { from, to } // from, to ともにPerson.id

「データ表」
id | name |
--+-----+--
1, "A"
2, "B"
3, "C"
4, "D"
5, "E"

from | to |
----+---+--
1, 3
1, 4
1, 5
2, 4
3, 1
4, 1
4, 2
5, 1

[クエリ結果]
1, 3, "C"
1, 4, "D"
1, 5, "E"
2, 4, "D"
3, 1, "A"
4, 1, "A"
4, 2, "B"
5, 1, "A"

SQL SELECT p1.id, p2.* FROM Person p1, Friend , Person p2 WHERE p1.id = Friend.from and Friend.to = p2.id;
0688NAME IS NULL2014/03/19(水) 12:13:29.18ID:???
途中でポストしちゃったんじゃないのか、、、w
同じテーブルを複数回参照するのは JOIN して別名付けるんだけど
そういう話、なのかな?
06896872014/03/19(水) 12:42:50.14ID:???
SQLは大体こんな感じかなと適当に書いたのですが、
まず大筋の流れとして正しいのかな。

とりあえず目的としては、Javaでこんな感じのクラスにマッピングしたいのですよ。
class Person {
List<Person> friends;
}
0690NAME IS NULL2014/03/19(水) 13:00:03.17ID:???
PersonとFriendをLEFT JOINじゃダメなん?
06916872014/03/19(水) 13:07:05.77ID:???
WHEREをJOIN ONに置き換えられますね。
それよりもまず上記に書いた[クエリ結果] (予定)が出るのか心配です。
0692NAME IS NULL2014/03/19(水) 13:24:11.90ID:???
SELECT friend.from, friend.to, person_1.name
FROM (Person INNER JOIN friend ON Person.id = friend.from)
INNER JOIN person AS person_1 ON friend.to = person_1.id

accessで適当につなげただけだが
0693NAME IS NULL2014/03/19(水) 13:31:10.94ID:???
>>691
ああ、あのような結果が、そのクエリで得られるのかどうかってこと?
ならおk。
0694NAME IS NULL2014/03/19(水) 13:35:46.28ID:???
あんまりテーブル並べて書くこと無いんだけど
これって、「Person 1さんの友人一覧だけ表示」って時
いちいちwhに2つ条件書かないといけないん?
06956872014/03/19(水) 13:47:38.81ID:???
このケースならもっと簡単に出てくることに気づきました。。。

SELECT f.from, p.* FROM Person p INNER JOIN Friend f ON p.id = f.to;
0696NAME IS NULL2014/03/19(水) 13:52:10.62ID:???
>>695
まぁ基本的にはそれで後はwhereで絞り込むのが一般的だろうな
さらに【○○さんの友人は】って言うのまで出すなら>>692
0697NAME IS NULL2014/03/19(水) 15:22:03.23ID:???
つか、from to なのに最初と最後だけとかで良いのかよ
まあ複数必要ならfrom toでもつ設計がどうって話もあるけど
0698NAME IS NULL2014/03/19(水) 15:46:15.92ID:???
なんだって?
06996872014/03/19(水) 16:24:59.00ID:???
友達の友達、友達の友達の友達...は毎回クエリやるしかないよね
無限ループしそうだし
0700NAME IS NULL2014/03/19(水) 16:27:27.44ID:???
元カノの元カレの元カノの元カレの元カレの元カノの…的な
0701NAME IS NULL2014/03/19(水) 16:30:46.77ID:???
ウホ、いいリレーショナル
0702NAME IS NULL2014/03/19(水) 22:54:10.63ID:???
>>699
再帰SQLが使えるDBMSなら1回で出来なくはない
0703NAME IS NULL2014/03/20(木) 00:26:30.23ID:???
>>702
部品みたいに親子が決まってる奴はいいけど、友達関係だと辿ってると無限ループに陥りそう。
定番の回避方法とかあるんだろうか...
0704NAME IS NULL2014/03/20(木) 00:41:32.66ID:???
まあ、だいたいは何層までって限定いれるんじゃね
実際にユニークだったとしても、数万の友達リレーとか必要な場面ないだろ

2層とか3層ぐらいなら別名で普通にSQL書く方が楽かもしれんがw
0705NAME IS NULL2014/03/20(木) 00:54:12.97ID:???
>>703
そのやり方だと同じ友達が無限に出てくることになるね。
だから、そうしない。
0706NAME IS NULL2014/03/20(木) 06:36:13.87ID:???
調べ済み友達リストを作業テーブルに吐いていって
2度目は弾く、くらいか
0707NAME IS NULL2014/03/20(木) 08:57:33.51ID:???
友達の友達はアルカイダ
0708NAME IS NULL2014/03/20(木) 14:13:24.98ID:SUsezco5
SNSでよくある、特定の人の日記を開いたとき、
友達の、その友達の、みたいな繋がり表示かな?
0709NAME IS NULL2014/03/21(金) 15:14:41.41ID:HdJsM8El
友人としての距離(何人ジャンプするか)を数値化できるといいね!
0710NAME IS NULL2014/03/21(金) 19:38:28.06ID:???
>>705
マジで何を言ってるのか理解できねぇ
0711NAME IS NULL2014/03/21(金) 23:53:41.80ID:???
ちゃんとやれば無限ループになんてならないってだけじゃね
0712NAME IS NULL2014/03/22(土) 01:18:00.98ID:???
だからそのちゃんとやる方法の定番ってなによって話なんだが...
0713NAME IS NULL2014/03/22(土) 03:00:40.98ID:9SJ3/olA
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。ひんがら目気色悪すぎこっち見んな死ね。
0714NAME IS NULL2014/03/22(土) 03:20:55.14ID:???
>>712
定番が何かわからんが、状態が飽和したら終わりでいいじゃん。
とりあえずアプリでやれば?
0715NAME IS NULL2014/03/22(土) 07:37:38.52ID:???
>>714
申し訳ないけど、スレの流れを読めない奴には用はないわ

> 再帰 SQL
0716NAME IS NULL2014/03/22(土) 12:12:29.45ID:???
>>715
状態が飽和したことを再帰で記述できないならそういえよ馬鹿。
0717NAME IS NULL2014/03/22(土) 12:26:09.87ID:???
別にアプリでもクエリでも再帰を使うならやることは同じじゃない?
>>715は再帰自体に慣れてないだけかもしれない。ということは無限ループを生みやすい人かも。
0718NAME IS NULL2014/03/22(土) 12:47:34.61ID:???
>>716-717
具体的なこと書けないなら無理すんな
ウザイだけだ
0719NAME IS NULL2014/03/22(土) 13:08:59.09ID:???
>>718
どこがわからないか書けないってこと?
条件なら、新しい友達がそれ以上存在しなくなったときに偽になればいいわけだから、
exists 既存 except 新規 ってするだけだよね。
0720NAME IS NULL2014/03/22(土) 13:13:11.56ID:???
オゥ逆だ。新規(既存込み) except 既存 ね。
0721NAME IS NULL2014/03/22(土) 13:34:34.32ID:???
>>719
ダメだこりゃ
新規とかどっから出てきたんだよ (w
0722NAME IS NULL2014/03/22(土) 13:38:02.52ID:???
>>721
そりゃ友達の友達を発見しないといけないからな。
再帰って知ってる?
0723NAME IS NULL2014/03/22(土) 14:02:55.36ID:???
できるもんなの?
0724NAME IS NULL2014/03/22(土) 14:05:20.46ID:???
>>722
ちょっと意味わからんから SQL で書いてくれない?
0725NAME IS NULL2014/03/22(土) 14:20:54.22ID:???
ゴタクはいい。クエリを書け。
0726NAME IS NULL2014/03/22(土) 14:29:52.63ID:???
再帰SQLでUNION ALLでなくUNIONで結合してしまえば簡単じゃね?
0727NAME IS NULL2014/03/22(土) 14:36:34.84ID:???
再帰と言うからにはファンクション作るのかな?

idを渡してFriendテーブルからfrom=idのto一覧を取得
to一覧を一時テーブルに登録
to一覧の各要素をキーにしてファンクションを呼び出す(再帰)
取得したtoに一時テーブルにない新規を見つける
なければ終わり
あれば、一時テーブルに登録し、ファンクションを呼び出す(再帰)

ファンクションから呼出元に、一時テーブルを返す
こんな感じ?
0728NAME IS NULL2014/03/22(土) 14:44:25.33ID:???
>>724
http://www.postgresql.jp/document/9.2/html/queries-with.html
0729NAME IS NULL2014/03/22(土) 15:32:06.04ID:???
>>716 >>724
http://www.oracle.com/technetwork/jp/articles/otnj-sql-image7-1525407-ja.html
0730NAME IS NULL2014/03/22(土) 15:39:14.16ID:???
SQLの文法の話じゃなくてもいいですか?

自分なりググって説明を読んだつもりなんですが、
ハッシュ結合がネステッドループやソートマージより優秀な(事が多い)
理屈がよくわかりません。
なぜハッシュ値にするとソートやループをしなくてよくなるのでしょうか?

ハッシュ値のメッセージが異なればハッシュ値が同じになる確率は
極めて低いっていう性質は理解しているつもりなんですが。
0731NAME IS NULL2014/03/22(土) 15:40:45.12ID:???
クエリ書けって言われてるのに方法論書いたりマニュアルのURL出すやつは実は何もわかってないんだろうなぁ。
0732NAME IS NULL2014/03/22(土) 15:46:40.98ID:???
postgresqlを使うことが前提でいいの?
0733NAME IS NULL2014/03/22(土) 15:54:17.85ID:???
>>731
マニュアルに答えが出てるレベルの内容だからだろ
>>729の「有向グラフの探索」なんてずばり答えではないか
0734NAME IS NULL2014/03/22(土) 16:17:36.41ID:???
>>730
それぞれ長所短所があってどんな場合にも優れているっていうものはない
(そんなものがあればそれだけが実装されるはず)

ハッシュジョインはソートはしないまでも「ハッシュテーブルを作る」という
一手間がかかるので他の結合方法より遅い場合もある
0735NAME IS NULL2014/03/22(土) 16:26:51.79ID:???
>>730
ハッシュ値生成コストとループコスト、またはソート+二分探索のコストの差。
そういうわけで、場合によってはネステッドループのほうが優秀なこともある。
>>731
日本語を読めないorクエリを読めないor応用できないor同じことだと理解できていない
>>732
SQL標準にしたがって実装されていれば別にどれでもいいよ。
0736NAME IS NULL2014/03/22(土) 16:51:51.47ID:???
>>734

ありがとうございます。
ケースバイケースで優秀な結合方法が変わるというのは分かるんですが、

例えば 売上.顧客ID と 顧客.顧客ID で結合する場合、顧客IDそのままの
テーブルを作るよりハッシュ値のテーブルを作った方が早いというのが
よくわからなくて・・
0737NAME IS NULL2014/03/22(土) 16:59:06.77ID:???
>>735
すみません。新着みてませんでした。

ハッシュ値を出してしまうとその後が楽になる、つまり、
ハッシュ値同士の探索は生値同士の探索より速くなるという
事だと思うのですが、そこの理屈がわかってないです。
0738NAME IS NULL2014/03/22(土) 17:12:19.85ID:???
>>728
これ分かりやすいな、ありがと。

>>731
お前中身見てないだろ。
0739NAME IS NULL2014/03/22(土) 17:13:11.94ID:???
そもそもネステッドループと言っても、インデックススキャンとテーブルスキャンじゃ
天と地だから実行計画を見てみないと一概には言えないが、ハッシュジョインが
選択されるのはたいがいテーブルのほぼ全域を読む必要があって、かつジョインに
使用できる適切なインデックスが見つからない場合じゃないかな。
そういうケースではインデックスページを読む必要がない分ハッシュジョインが速い。
0740NAME IS NULL2014/03/22(土) 17:14:52.20ID:???
>>737
>>736の例だと、どちらも顧客IDにインデックスをはっておけば、そのインデックスがハッシュと同じように低コストで動作するよ。
ループになるとすれば、インデックス外の項目を使用し、かつ、顧客テーブルのレコード数が十分少ない場合など。
0741NAME IS NULL2014/03/22(土) 17:18:37.08ID:???
> ハッシュ値同士の探索は生値同士の探索より速くなる
ここに限定するなら、ハッシュ値を求めて、それを元にテーブルを構築するわけだから、
ある値が合った場合に、ハッシュ値を求めればテーブルの該当行を抜いてくるのは容易。

プログラミング言語を勉強したことがあるなら、構造体配列があって、配列インデックスが判明すれば、
構造体を抜いてくるのが容易なのと同じといえばいいか。
0742NAME IS NULL2014/03/22(土) 17:27:28.86ID:???
>>737
ttp://www.hi-ho.ne.jp/a_ogawa/document/pg_dynahash.pdf
PDF注意
07437302014/03/22(土) 17:49:08.11ID:???
>>739-742
ありがとうございます。
ハッシュテーブルを作る≒その場限りのインデックスを作る
というイメージですかね?

さらに(まだ>>742さんのPDFは理解しきれてないですが)、
リニアハッシュという仕組みで 顧客ID ではなく ハッシュ関数h(顧客ID) の
方が早く探索できるという事でしょうか。
0744NAME IS NULL2014/03/22(土) 20:07:12.70ID:???
>>743
ハッシュテーブルにせずキー値をそのままメモリ上に展開しただけの場合、
そこから特定の値を探すには一々メモリ上のすべてのデータを舐める必要がある。
一方、ハッシュテーブルにしておけば値をハッシュ関数にかけるだけで
ダイレクトにメモリ上の位置を特定できる。

キー値を探索する回数が少なければハッシュテーブルを作る手間の分だけ
ハッシュのほうが不利だが、回数が多ければ多いほどハッシュのほうが有利になる。
07457302014/03/22(土) 20:29:15.54ID:???
>>744

>ハッシュテーブルにしておけば値をハッシュ関数にかけるだけで
>ダイレクトにメモリ上の位置を特定できる。

勉強不足でした。
これがキモなんですね。すっきりしました。

IDが出ないので別の方なのか分かりませんがレスくれた
みなさんありがとうございます。
0746NAME IS NULL2014/03/25(火) 00:17:10.72ID:???
mysql 5.5.15
table testunique
id int primary key,
author varchar(30),
fname varchar(100),
genre int not null,
folder varchar(100)
)
1,'a1','test1',10,'dddddddd',
2,'a1','test1',14,'dddddddd1',
3,'ab','test2',16,'dddddddd',
4,'ac','test3',1,'dddddddd',
5,'ac','test3',4,'dddddddd'

とあると気に author, fname の組み合わせで重複なしを出したい
上記の例で言えば

a1 , test1
ab , test2
ac , test3
の3件を取り出したいのですが…
distinctって複数列に対しては出来ませんよね。どう書けば良いんでしょうか
0747NAME IS NULL2014/03/25(火) 00:57:57.32ID:???
>>746
group by author, fname
0748NAME IS NULL2014/03/25(火) 00:58:27.56ID:???
select distinct * from testunique
group by concat(author,'##',fname); <- ## は適当に
0749NAME IS NULL2014/03/25(火) 01:08:33.23ID:???
748はまずいね
0750NAME IS NULL2014/03/25(火) 01:29:54.97ID:???
>>746を見て、distinctが複数列に対して使えないはずがないと思ったら

MySQLはだめなんね。しらなかったよ
0751NAME IS NULL2014/03/25(火) 04:40:14.55ID:???
そうなんだ。不便だな。
といっても、PostgreSQLも昔はdistinctよりもgroup byのほうが速かったりもしたし、実装面倒なんだろうか。
0752NAME IS NULL2014/03/25(火) 04:47:31.65ID:???
いや、やっぱり普通に出来るんじゃないの。
出来ないことのソースが見つからん。

select distinct author, fname from testunique;

でなにがだめなの。
07537462014/03/25(火) 07:56:53.14ID:???
皆さん、夜遅くにつきあっていただきありがとうございました
出来ないって単純に思い込んでいただけなのか、752さんのであっさり出来ました
勿論、747さんのgroup byでも出来ましたが。
0754NAME IS NULL2014/03/26(水) 20:08:57.26ID:???
時間が経ってしまったけど、687の友達の友達〜
mysqlでやってみた
DROP PROCEDURE friend_level;
DELIMITER //

CREATE PROCEDURE friend_level(IN _d INT)
BEGIN

 DECLARE not_found INT DEFAULT 0;
 DECLARE _id1 INT;
 DECLARE _id2 INT;
 DECLARE _path TEXT;
 DECLARE _name TEXT;
 DECLARE _dist INT;
 DECLARE _ext INT;
 DECLARE _cnt INT;

 DECLARE cur CURSOR FOR
  SELECT f.`from`, t.`to`, t.path, p.name FROM Friend AS f
  INNER JOIN tmpF AS t ON (f.`to` = t.`from` AND f.`from` <> t.`to` AND t.dist = _d)
  INNER JOIN Person AS p ON (p.id = f.`from`)
  ORDER BY `from`,`to`;

 DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1;

 SET _dist = _d + 1;
 SET _ext = 0;

 OPEN cur;
 loop2: LOOP
  FETCH cur INTO _id1, _id2, _path, _name;
  IF not_found THEN
    SET not_found = 0;
    CLOSE cur;
    LEAVE loop2;
  END IF;
  SELECT COUNT(*) FROM tmpF WHERE `from`=_id1 AND `to`=_id2 INTO _cnt;
  IF _cnt = 0 THEN
    SET _ext = 1;
    INSERT INTO tmpF VALUES (_id1, _id2, _dist, CONCAT(_name, '->', _path));
  END IF;
 END LOOP;
 IF _ext = 1 THEN
  CALL friend_level(_dist);
 END IF;
END;
//
DELIMITER ;
0755NAME IS NULL2014/03/26(水) 20:10:34.10ID:???
DROP TABLE IF EXISTS `Person`;
CREATE TABLE `Person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(4) DEFAULT NULL,
PRIMARY KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `Friend`;
CREATE TABLE `Friend` (
`from` int(11) DEFAULT NULL,
`to` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Person` VALUES (1,'A'),(2,'B'),(3,'C'),(4,'D'),(5,'E'),(6,'F'),(7,'G'),(8,'H'),(9,'I');

INSERT INTO `Friend` VALUES (1,3),(1,4),(1,5),(2,4),(3,1),(4,1),(4,2),(5,1);
/*INSERT INTO `Friend` VALUES (1,2),(2,3),(3,4),(4,5),(5,4),(4,3),(3,2),(2,1);*/

CREATE TEMPORARY TABLE IF NOT EXISTS tmpF (`from` INT, `to` INT, dist INT, path TEXT);
TRUNCATE TABLE tmpF;
INSERT INTO tmpF (`from`,`to`,dist,path) SELECT `from`, `to`, 0, CONCAT(p1.name,'->',p2.name)
FROM Friend INNER JOIN Person p1 ON (p1.id=`from`) INNER JOIN Person p2 ON (p2.id=`to`);

SET max_sp_recursion_depth = 255 ;
CALL friend_level(0);

SELECT `from`,p1.name,`to`,p2.name,dist,path FROM tmpF
INNER JOIN Person p1 ON (p1.id=`from`)
INNER JOIN Person p2 ON (p2.id=`to`)
/* order by `from`,`to` */ ;
0756NAME IS NULL2014/03/27(木) 02:57:37.29ID:???
長いからまだ読んでないけど、テンポラリ・テーブルに書き込んで
重複無限ループを回避しながら検索?
0757NAME IS NULL2014/03/27(木) 03:08:01.79ID:???
ほしがってる階層にもよるけど、ストアド作るくらいならアプリで解決したほうが
メンテナンス性が高いことの優位性が勝つような気がするよ。
0758NAME IS NULL2014/03/27(木) 03:34:29.67ID:???
ループして1行ずつ検査してるあたりが回りくどく見える。

新しい友達の情報をtmpに入れればいいんだから、集合的に扱えると思う。
カーソルのクエリでパスを作成するようにして、where句に not exists (select * from tmp where 〜〜) をつけて、
insert into tmp カーソルのクエリ ってやれば、tmpの更新は完了。

再帰終了条件はinsert件数が0件かどうかで判断すれば、
再帰1回あたりのクエリ発行回数は1度で済むとおもうんだけど、どう。
0759NAME IS NULL2014/03/27(木) 09:18:14.26ID:???
>>758のは再帰SQLのUNION方式か
0760NAME IS NULL2014/03/27(木) 21:26:00.95ID:???
>>758
コメントありがとう。前半のselectで力尽きてたw
tmpの更新については、ご意見参考にして見直してみます
0761NAME IS NULL2014/03/27(木) 23:53:23.96ID:???
>>760
うん。
言葉を変えると、「まだ入ってなければ入れ、すでに入ってるなら何もしない」ということをするなら、
まだ入ってないものだけ抜いてくれば無条件で入れられるよねってことです。

mysqlのパフォーマンス特性には明るくないけど、
fetch into 自体のコストも、積み重なると地味に邪魔になることが多いし、
集合を扱うというSQLの強みを最大限活用するとよいはずです。

-- こうやって文章で書いてると、いいからクエリ書いてみろよどうせ書けないんだろって
-- 言われるかと思ったけど、そうでもなくてよかった。
0762NAME IS NULL2014/03/28(金) 00:04:38.09ID:4fFGVIXN
SQL初心者です
かなり低レベルの質問で申し訳ないのですが
DBにOracleやその他いろいろあると思うのですが何が違うのですか?
0763NAME IS NULL2014/03/28(金) 00:40:46.13ID:???
ブラウザの違いを聞くのと似ている。
本質的には同じだけど、あちこち違う。
0764NAME IS NULL2014/03/28(金) 01:27:13.90ID:3SLinpcT
oracleもsqlserverも無料版がでてるし、最初からフリーなのも沢山ある

どれでも良いから自分のPCに入れて触ってみればよろし
0765NAME IS NULL2014/04/01(火) 12:06:05.25ID:???
http://www.nicovideo.jp/watch/sm23207869
http://www.xvideos.com/video7591103/positive_hame_dick_cunt_dick_cunt_dick_cunt_dick_cunt_
http://youtu.be/2FvsBTNwUaY
ちんこまんこ   /⌒\  /⌒\  ちんこまんこ
ちんこまんこ♪((    ; 三    ,,))ちんこまんこ♪
\  (σ) /  ヽ   (  /    ミ  \ (σ)   /
   / 人\    キ   .メ   ./    / 人\
 / /  \\   乂      ノ   / /  \\
(  (*^○^* ) )   (*^○^*)  (((  ( *^○^*) )
 \ \  //)))    )   (⌒)))  \ \  //
   )  Y (      ((__)⌒ ̄   ((()  Y (
  (__Y http://i.imgur.com/3UUUdIg.png Y_)
0766NAME IS NULL2014/04/04(金) 08:10:21.21ID:???
初心者な質問ですが、無料でubuntu系の鯖で動いて1000万件のデータを管理できて一番CPU/HDDに負担の少ないDBソフトは何ですか?
やることは基本的な事です。
0767NAME IS NULL2014/04/04(金) 08:37:40.51ID:???
くだらん事で悩む前にmysqlでもpostgreSQLでも何でもいいから実際に動かして自分の頭で納得したほうがよろし
0768NAME IS NULL2014/04/04(金) 08:46:06.76ID:???
>>766
>>1
0769NAME IS NULL2014/04/05(土) 21:37:04.94ID:???
DBMS は PostgreSQL 9.2 です。

tableA, B , C, ... があります。
それぞれに関連があり、例えば以下のように SQL 文を書いて各テーブルにまたがったデータ抽出を行っています。

select a.ID as id, a.col1 as data1, b.col1 as data2, c.col1 as data3
from tableA a, tableB b, tableC c
where b.ID = a.ID and c.ID = a.ID

ここに tableB と新規の tableZ への関連を追加したいと思います。
ただし tableB には tableZ と関連づけるキーのすべてがあるわけではないので、外部結合としたいと思います。

外部結合でない普通?の書き方はわかるのですが、すでに複数のテーブルが関連づけられている SQL に
新規に外部結合を追加する方法がわかりません。教えていただけないでしょうか。
外部結合に使用したいキーは tableB.ID - tableZ.ID と tableB.ID2 - tableZ.ID2 (仮)です。
当然、以下のように書いてしまうと tableZ に対応するキーのないデータが表示されなくなってしまいます。

select a.ID as id, a.col1 as data1, b.col1 as data2, c.col1 as data3, z.col1 as data4
from tableA a, tableB b, tableC c, tableZ z
where b.ID = a.ID and c.ID = a.ID
and b.ID = z.ID and b.ID2 = z.ID2

SQL は読めはするのですが、複雑な SQL はほとんど書いたことがありません。
上に書いた用語もおかしいところがあるかも知れませんが、ご容赦ください。
よろしくお願いします。
0770NAME IS NULL2014/04/05(土) 21:47:15.41ID:???
よくわからんが inner/left/right/outer join の話し?
0771NAME IS NULL2014/04/05(土) 22:15:57.78ID:???
>>769
select a.ID as id,
    a.col1 as data1,
    b.col1 as data2,
    c.col1 as data3,
    z.col1 as data4
from  tableA a
    inner join
    tableB b
    on a.ID = b.ID
    inner join
    tableC c
    on a.ID = c.ID
    left outer join
    tableZ z
    on b.ID = z.ID
    and b.ID2 = z.ID2
0772NAME IS NULL2014/04/05(土) 22:18:38.61ID:???
>>769
where句は外部結合ではなく検索条件。
外部結合はjoin句。
0773NAME IS NULL2014/04/05(土) 23:05:28.96ID:???
>>772
それってなんか違いでるんだっけ?
07747692014/04/06(日) 00:01:44.92ID:???
>>770
はい。
ただ、外部結合なのでやっぱり inner join とか使うんだろうな、、、くらいにしか分からなかったのですが。

>>771
すばらしいです。
なるほど。部分的にやるのではなくて全部を from 句で条件付け?するように書くべきだったのですね。
まったく発想が追いついてませんでした。
これでなんとか行けそうです。ありがとうございます。

>>772
そのあたりもよく分かっていませんでした。
773 さんと同じなのですが、どういった違いが結果として出るのでしょうか。
0775NAME IS NULL2014/04/06(日) 01:00:22.25ID:???
inner joinなら意味的にはともかく、結果に違いは出ないはず
外部結合すると、結合の順序によって結果が不定になったはず
07767722014/04/06(日) 01:55:14.96ID:???
>>774
言葉が足りんかった。
>>769の文を見る限り、検索条件と外部結合の意味がよく分かってないのかと思った。
だからそれぞれ正確にはこういう意味っていうことを書きたかった。
あと個人的になんだけど、テーブルの個数が2個程度ならともかくそれ以上の場合は、
外部結合はjoin、検索条件はwhereできっちり分けて書いた方が、SQL文を見直したときに
意図が分かりやすくて良いと思う。
0777NAME IS NULL2014/04/06(日) 02:00:49.44ID:???
where句で外部結合が書けるのってOracleだけ?
SQL Serverでも昔はできたけどできなくなったし
0778NAME IS NULL2014/04/06(日) 10:17:33.08ID:???
>>774
> 当然、以下のように書いてしまうと tableZ に対応するキーのないデータが表示されなくなってしまいます。

だから right join の意味調べなよ
ググれば親切に説明してるページいくらでもあるし、ここをちゃんと理解してないと RDB のメリット半減するし
0779NAME IS NULL2014/04/06(日) 14:18:22.96ID:???
>>778
解決後の上になぜright?
rightってよほど事情がないと気持ち悪くて使わないんだけど
0780NAME IS NULL2014/04/06(日) 14:43:20.27ID:???
right が気持ち悪いとか...大丈夫?
0781NAME IS NULL2014/04/06(日) 15:34:48.43ID:???
rightはあまり使ったことがないw
0782NAME IS NULL2014/04/06(日) 15:57:34.97ID:???
通常はどちらかに統一するな
LEFTだと思うけど
0783NAME IS NULL2014/04/06(日) 16:21:46.63ID:???
rightで統一されていたらそれはそれで悪意を感じる
0784NAME IS NULL2014/04/06(日) 17:10:14.97ID:???
right
0785NAME IS NULL2014/04/06(日) 18:03:53.05ID:???
必要に応じて使い分けるもんだと思うが
結果として left が多いと言うならわかるけど
0786NAME IS NULL2014/04/06(日) 18:34:29.81ID:???
複雑なSQL書いたら、どうしてもletfとrightが混在することはあるだろ
どっちかに統一する(できる)ならleftに統一する方が俺の好みではあるが
rightに統一する方が好みの人もまあいるかもしれん
0787NAME IS NULL2014/04/06(日) 19:50:46.27ID:???
なんで統一する話しになってるんだ?
07887692014/04/06(日) 20:01:10.57ID:???
>>775
ありがとうございます。
外部結合の場合の順序について気をつけます。
‥‥お勉強します。

>>776
ありがとうございます。
了解です。
そうですね。後から見たときのわかりやすさって大切ですものね。
いや、今回のの改造前の SQL 文を見るとしみじみ思うのです。。

>>778
お勉強します。
0789NAME IS NULL2014/04/06(日) 23:53:38.30ID:zId7D2Ra
phpMyAdminでテーブルをインポートしようと思ったのですが、
メニューに「インポート」の項目がないのは何故でしょうか?

phpMyAdminのバージョンは2.11.9.5
MySQL クライアントのバージョンは5.0.77
です。
0790NAME IS NULL2014/04/12(土) 20:45:02.80ID:???
SQLの質問じゃないね
MySQLスレですらスレチギリギリだと思うけど、教えてくれるんじゃない
0791NAME IS NULL2014/04/12(土) 21:14:48.16ID:???
PHPの質問でしょ、これ。 MySQLのどこがメニューの問題になるんだかw
0792NAME IS NULL2014/04/12(土) 23:43:01.21ID:???
ツールの問題で
MySQLのツールなんだから、PHPに聞きに行っても困るでしょ
0793NAME IS NULL2014/04/13(日) 00:04:13.42ID:???
MySQLスレが妥当。
0794NAME IS NULL2014/04/13(日) 01:15:57.47ID:???
けったいなツール使わんのがいちばん
0795NAME IS NULL2014/04/13(日) 11:41:12.85ID:???
MySQLならmysqldumpがあるでしょ
0796NAME IS NULL2014/04/13(日) 12:20:44.60ID:???
phpMyAdmin使う人ってSSL入れているのだろうか
0797NAME IS NULL2014/04/13(日) 13:43:10.49ID:UmjXMXiN
>>795
mysqldumpは出力だろ。>>789が言ってるのはインポートでmysqlへの入力だろうが
0798NAME IS NULL2014/04/13(日) 16:53:33.08ID:???
MySQLにはPostgresのpsqlみたいなツールはないの?
SQLをGUIで扱うメリットが全く理解できんのだが?
0799NAME IS NULL2014/04/13(日) 18:01:55.06ID:???
あるよ
おいらはそれしか使ってない
0800NAME IS NULL2014/04/13(日) 18:25:55.42ID:???
>>798
ものによるけど、select の結果が見易いとか、フィールド定義で型をリストから選択できたりとか
0801NAME IS NULL2014/04/13(日) 18:32:10.10ID:???
黒画面に抵抗がある人もいましてね
0802NAME IS NULL2014/04/13(日) 18:40:06.18ID:???
GUIって言っても、SQLは自分で書くんだぞ
0803NAME IS NULL2014/04/13(日) 18:41:20.08ID:???
コマンドプロンプト画面のことなら、プロパティいじれば何色にでもできるだろう
0804NAME IS NULL2014/04/13(日) 18:47:01.93ID:???
流石にhttp経由でDBの管理はできないわぁ
0805NAME IS NULL2014/04/13(日) 19:34:07.62ID:???
>>802
Visual Studio とかなら、マウスでちょこちょこやってると create table 文作ってくれたり (SQL 直すと GUI 側も合わせて変わる) 、Access とかは select 文も作ってくれたりするよ
まあ、それが便利かどうかは人によるけど...
0806NAME IS NULL2014/04/14(月) 10:37:47.90ID:???
>>798
PostgreSQLんもpgAdminIIIがあるじゃない
psqlとpgAdmin併用がいいよ
0807NAME IS NULL2014/04/14(月) 10:51:04.64ID:???
mysqlはCUIの補完が微妙でGUIあるといいなと思うけど使ってないや
postgresqlはCUIの補完が優秀だからGUI使いたいと思ったことないや
0808NAME IS NULL2014/04/14(月) 11:25:58.41ID:???
>>806
pgAdminIIIは試しに使ったことはあるけど、何が便利なのか分からん。
psql ではできないことでもあるのかな?
0809NAME IS NULL2014/04/14(月) 11:48:10.97ID:???
EXPLAINの解析でグラフィカルな図が見られたりするよ
あと現在動作してるバックエンドの一覧とか
管理に使うには便利すぎる
0810NAME IS NULL2014/04/14(月) 12:14:04.45ID:???
mysqlです
testテーブル
id int(11) PK
col varchar(10)

とあるときに最大のidを得たい
そしてそれが未登録状態なら0を返したいと思って
select case max(id)
when max(id) is null then 0
else max(id)
end as Nid from test;
としたんですが、0件の状態でNULLが返ってきます
これを0にしたいんですがどう訂正すればいいんでしょうか
0811NAME IS NULL2014/04/14(月) 12:31:58.37ID:???
810 速攻ですいません

select case max(id) の max(id) が余計でした
0812NAME IS NULL2014/04/14(月) 18:32:49.57ID:???
GUI使わない俺カッケーってだけでしょ?
全部コンソールでやってる人はアホだと思うわ
0813NAME IS NULL2014/04/14(月) 18:49:48.27ID:???
GUI使わないとカッケーの?

初めて知った
0814NAME IS NULL2014/04/14(月) 18:59:24.61ID:???
>>812
ほぉ、
そうなんだ…
凄いね、君
0815NAME IS NULL2014/04/14(月) 19:16:36.73ID:???
>>812
カッケーじゃなくて、それしか知らないだけかも。
分かってるだろうけど、CUIも便利だよ。

どちらも便利な点があるんだから、適材適所で使えばよいだけ。
0816NAME IS NULL2014/04/14(月) 19:18:29.59ID:???
CUIで全部作ってる人はGUIではSQLを打つんじゃなくてドラッグアンドドロップでSQLが自動生成されると思ってる人だよ
0817NAME IS NULL2014/04/14(月) 20:30:27.62ID:???
シェルを使わせない代わりにGUIが使えるというレンタルサーバーはあるな
0818NAME IS NULL2014/04/15(火) 03:16:40.53ID:???
>>810
select
case when max_id is null then 0 else max_id end as Nid
from
(select max(id) as max_id from test) t
とかでどうだ?
まあ、俺ならそんな操作はホストアプリ側でやらせるがな
SQLは存在しないデータを生み出すためのものじゃないから

idの取りうる範囲次第では0とunionしてmax取るとかでも行けるかも

>>812-817
いい加減スレチな話題はやめろ
0819NAME IS NULL2014/04/15(火) 03:36:26.23ID:???
>>818
なんで解決してる話題にドヤ顔で回りくどいクエリを?
スレチ指摘するより先にやることがあるだろ。
0820NAME IS NULL2014/04/15(火) 19:49:24.47ID:???
SQLインジェクション対策したいんですが、

$test = $_GET['data'];

//エスケープ
$test = mysql_real_escape_string($test);

$result = mysql_query("select * from aaa where name = '{$test}'");


このようにmysql_real_escape_stringでエスケープしてれば、SQLインジェクションって防げますよね?
防げない場合どういうパターンがあるのか教えてください
0821NAME IS NULL2014/04/15(火) 21:34:51.16ID:???
↑は解決したんで無視してください
0822NAME IS NULL2014/04/15(火) 22:48:17.23ID:???
A,1,3
というデータを持つ3カラム1レコードのテーブルAから

A,1
A,2
A,3
という2カラム複数レコードに展開したテーブルBを作る方法を知りたいです。
元テーブルの第2カラムが連番FROM、第3カラムが連番TOなので
展開後のレコード数はこれらの値により変化します。
DBMSはAccess2010を想定しますが、なるべく汎用的なSQLがよいです。
0823NAME IS NULL2014/04/15(火) 22:51:07.84ID:???
>>822
連番を作ることに関して >>8
0824NAME IS NULL2014/04/16(水) 07:17:14.26ID:???
>>822
Accessなら素直にVBAで回せば簡単で後々も楽ですよ
0825NAME IS NULL2014/04/16(水) 20:47:37.82ID:???
>>822
Access (のエンジンである Ace) は再帰をサポートしてないようなので、SQL だけでは無理と思う。
Access だけでやりたいなら、>>824 が言うように VBA でやるのがお勧め。
エンジン替えていいなら無償の SQL-Server 入れて
With T (Value, [From], [To], Offset) as (
select Value, [From], [To], 0 from A
union all
select Value, [From], [To], 2 * Offset + 1 from T where [From] + 2 * Offset + 1 <= [To]
union all
select Value, [From], [To], 2 * Offset + 2 from T where [From] + 2 * Offset + 2 <= [To]
)
select Value, [From] + Offset from T;
でいける。
1,000,000行でも 10秒ちょい。
0826NAME IS NULL2014/04/16(水) 21:31:58.01ID:???
サンクスです。
連番作成はSQLには向かない仕事だったのですね。
VBAはまだ身についていないのですが参考にします。
0827NAME IS NULL2014/04/17(木) 01:57:59.92ID:1elrg/bJ
�@テーブルデータ
A|B|C
-+-+-
1|3|-
2|-|5
3|-|8
4|2|-

-はnullとします

�A期待値
1|3
2|5
3|8
4|2

�Bやりたいこと
Aは必ず入っており、BとCは片方のみ入っています。
その場合、AとBCの入っている方を出したいです
Aは昇順ソートもかけたいです



select T1.A, T1.B from aaa T1 where T1.B is not null
select T2.A, T2.C from aaa T2 where T2.C is not null

これで片方ずつは抽出できると思うんですけど
合わせてソートする方法がわかりません
0828NAME IS NULL2014/04/17(木) 02:10:22.79ID:???
>>827
select
A,
case when B is null then C else B end as DATA
from TABLE
order by A
0829NAME IS NULL2014/04/17(木) 02:20:26.93ID:1elrg/bJ
>>828
回答ありがとうございます!

・・・しかし理解できていないので
これから読みといてみます
早く終わらせて寝たい・・・
0830NAME IS NULL2014/04/17(木) 02:21:04.03ID:???
select A, coalesce(B,C) from TABLE:
0831NAME IS NULL2014/04/17(木) 02:30:38.98ID:???
理解出来ました! CASE文は知りませんでした。
一つ勉強になりました、ありがとうございます!


すいませんsageが抜けてました
おやすみなさい!
0832NAME IS NULL2014/04/17(木) 02:31:47.84ID:???
>>831
あれーすごく短いコマンドでできているような…

寝ないでも少し調べますっ。回答ありがとうございます!
0833NAME IS NULL2014/04/17(木) 02:37:57.62ID:???
COALESCEも理解出来ました!
こちらのほうが短くてよさそうですね!
おふたりともありがとうございました!
ねます!おやすみなさい!
0834NAME IS NULL2014/04/17(木) 03:20:55.94ID:???
ほっこりした
0835NAME IS NULL2014/04/17(木) 03:29:28.39ID:???
おなじくほっこりした。

select A, B from aaa where B is not null
union all
select A, C from aaa where C is not null
order by A

に到達してもよさそうな状況だったけど、その前にcoalesceに出会えてよかった。
0836NAME IS NULL2014/04/20(日) 01:27:30.79ID:???
質問1: left outer join や right outer join って、cross joinとwhere句の組み合わせで実現できる?もしできるなら教えて。

質問2: カラム数が可変なクエリって定義できる?やりたいことは、チーム数が可変の対戦表をつくりたい。

チーム1 点数 チーム2 点数
------------------------------------
Japan  1  England 2
Spain  2  Mexico 3
Mexico 0  England 1

↓

    England Mexico Spain Japan
England -    ○   -   ○
Mexico  ×   -    ○  -
Spain  -    ×   -   -
Japan  ×    -   -   -
0837NAME IS NULL2014/04/20(日) 01:37:03.28ID:???
「列の数が可変なクエリは書けない」って>>7に書いてあったorz
0838NAME IS NULL2014/04/20(日) 10:47:41.74ID:???
>>836
>質問1: left outer join や right outer join って、cross joinとwhere句の組み合わせで実現できる?もしできるなら教えて。

これ教えてください
0839NAME IS NULL2014/04/20(日) 11:05:09.94ID:???
>>838
外部結合演算子でぐぐれ
0840NAME IS NULL2014/04/20(日) 11:15:50.50ID:???
>>838
unionとnot exists使えばできる。cross joinは使ってもいいがinner joinで十分。
0841NAME IS NULL2014/04/20(日) 12:10:56.37ID:???
>>839
質問を理解してから回答してください

>>840
ありがとうございます。こんなかんじでしょうか。

(select emp.*, dept.*
from emp, dept
where emp.dept_id = dept.id
)
union
(select emp.*
from emp
where not exists (select * from dept where dept.id = emp.id)
)

これだと、select emp.*, dept.* と select emp.* が違うので、union はできませんね。
2つ目のselect文で、select emp.*, dept.* 相当にするにはどうしたらいいでしょうか。
0842NAME IS NULL2014/04/20(日) 12:28:23.63ID:???
>>841
あら、自分で頑張ってね
0843NAME IS NULL2014/04/20(日) 13:42:17.29ID:???
質問してる立場なのに上から目線でレスするやつの神経がマジ分からない。
0844NAME IS NULL2014/04/20(日) 14:04:00.19ID:???
そりゃ>>839があまりにも不親切だからでしょ
ググれで済むなら質問スレなんて要らないんだし
0845NAME IS NULL2014/04/20(日) 14:05:11.53ID:???
ググるワードまで教えてもらって不親切はないわ
0846NAME IS NULL2014/04/20(日) 14:15:00.92ID:???
>>1のテンプレすら守れないときついわな
>質問するときはDBMS名を必ず付記してください

841はググったのだろうか
外部結合演算子を勘違いしている可能性が一番高そうなんだな
0847NAME IS NULL2014/04/20(日) 14:26:14.20ID:???
ム板に多いが、質問者よりバカなくせに上から目線でとんちんかんな回答する奴はイラッとくるな。
0848NAME IS NULL2014/04/20(日) 14:35:08.59ID:???
今回のはどこに落ち着くかね
DBMS名を書くのと
何故にcorss joinが必要なのかを明記しないと回答はつかないだろうな

外部結合演算子を使うとcross joinとは言えないから難しいところ

>>847
普通にスルーすればよいかと
0849NAME IS NULL2014/04/20(日) 14:41:13.96ID:???
PostgreSQLスレにも似た口調のダメな質問者が湧いてるな
0850NAME IS NULL2014/04/20(日) 14:50:15.62ID:???
回答にならないキーワードを教えて回答したつもりになっている、自称上級者が集まっているのがこちらです
0851NAME IS NULL2014/04/20(日) 14:56:49.30ID:???
>>841
2つめのselectでNULLを補えばいい。
0852NAME IS NULL2014/04/20(日) 15:04:21.76ID:???
>>844
まず調査(ググるなど)して分からなかったら質問するのが普通だと思う。
100歩譲っていきなり質問したとしても、
> 質問を理解してから回答してください
この回答は無いわ。
精々「申し訳ありませんが質問の内容と異なるようです」くらい書けよと。

そういうのうぜぇッて思うなら、
http://nozomi.2ch.net/test/read.cgi/php/1271172618/
ここのスレで聞いたほうが良いと思う。
0853NAME IS NULL2014/04/20(日) 15:16:39.79ID:???
>>838
>質問1: left outer join や right outer join って、cross joinとwhere句の組み合わせで実現できる?もしできるなら教えて。
これがもとの質問。外部結合がクロス結合とWHEREで実現できるかを聞いている。

>> 839
> 外部結合演算子でぐぐれ
的はずれ。外部結合が何かを聞いているんじゃないのに、これで教えた気になっている。

>>840
> unionとnot exists使えばできる。
こっちは質問の答えになっている。

>>841
> 質問を理解してから回答してください
バカを煽るな。バカはスルーするのが一番。

>>848
この質問だとさすがにDBMSによって変わるような内容とは思わないが、
どうしてもDBMSが必要なら、「標準SQLの場合なら」と断って書けばいい。
0854NAME IS NULL2014/04/20(日) 15:42:44.50ID:???
>>853
848だけどさ

何故にクロスジョインにした結果を知りたいかが不明でさ
SQLの初歩的な理解のためってならわかるけどさ
>>841を見ると、その線が濃厚か

>>839は外部結合演算子を使うと
クロスジョインのjoin句の書式で外部結合書けるからだと思うよ
0855NAME IS NULL2014/04/20(日) 16:12:06.67ID:???
outer joinをわざわざDBMS方言の外部結合演算子で書き換えることが元質問者の求めている
回答だと思ったんだとしたら、ちょっと頭が足りないんじゃないか?
0856NAME IS NULL2014/04/20(日) 16:17:51.63ID:???
だろうね
0857NAME IS NULL2014/04/20(日) 23:05:16.99ID:???
DBMS は PostgreSQL の 9.2 です。
たとえば次のようなテーブルがあったとします。

id col1
---------
1   1
2   1
3   2
4   3

このようなテーブルの、col1 の持っている値の種類と、その種類ごとの出現件数を
1回の SQL 実行で取得することは可能でしょうか。
この場合では、 col1=1 が 2 回、2 と 3 が 1 回ずつなので、これを知りたいと思います。

いまは SQL を思いつかなくて、条件に一致するレコードをすべて取得して for ループで
col1 の値ごとの出現回数を取得してますが、もっと上手な方法がありそうに思えました。
0858NAME IS NULL2014/04/20(日) 23:14:18.75ID:???
col1でgroup by してcount すれば良いんじゃないの?
0859NAME IS NULL2014/04/20(日) 23:51:47.24ID:???
ほっこり→イライラ→ほっこり
次の質問はイライラかぁ
0860NAME IS NULL2014/04/21(月) 07:30:47.85ID:???
これからデータベースの勉強をしようと思っているのですがどのデータベースを主に使えばいいのか悩んでいます

選択候補はSQLserver,oracle,postgreの3つを考えているのですがそれぞれのメリットやどんな企業が導入しやすいとかみたいなものはありますか?
0861NAME IS NULL2014/04/21(月) 07:38:04.85ID:???
個人的に oracle は最初に候補から脱落させて良いと思う

linux を触る機会が少なければ sqlserver 一択かな
無料版 express でも、個人で使う範囲ならほぼフルスペックだ
0862NAME IS NULL2014/04/21(月) 10:55:13.62ID:???
以前触った時の感想だけどSQLServerはヘルプが読みやすかった (BooksOnlineだったか)
勿論SQLを勉強した上でないとダメだけど。

postgreは触った事ないから知らない
oracleは、、、資格を取るためとかってならそれもいいんだろうけどなぁ

個人的には861さんの意見に同意
0863NAME IS NULL2014/04/21(月) 12:22:37.66ID:???
インデックスは 張るものですか? 貼るものですか?
0864NAME IS NULL2014/04/21(月) 15:45:26.20ID:???
はるものだけど
貼るではないから張るだろうな
0865NAME IS NULL2014/04/21(月) 16:56:42.63ID:???
>>860
お金をかけたい企業はOracleかSQLServerを使う
お金をかけれない企業はPostgreSQLと(MySQL)を使う

性能はMySQLだけ異質で他はあまり変わらない
0866NAME IS NULL2014/04/21(月) 17:07:24.05ID:???
すれちとは言わないんだ(笑)
0867NAME IS NULL2014/04/21(月) 20:15:36.01ID:???
>>865
>性能はMySQLだけ異質で他はあまり変わらない

その異質ってのは何?
08688572014/04/21(月) 21:41:37.72ID:???
>>858
それでした。なんでか思いつきませんでした。。
ありがとうございました。
0869NAME IS NULL2014/04/22(火) 20:50:54.50ID:???
スレが和やかだと読んでて楽しい
0870NAME IS NULL2014/04/24(木) 00:31:34.81ID:VMhPPiZ3
人物を扱うテーブルがあり、そのテーブルの列には、人物テーブルの主キーを外部キーとして自己参照する列があります。

Persons
id
name
descendant_of

こういう構成になっており、 descendant_ofはPersonsテーブルの主キーが入ります。


id=1にAさんがいます。
id=2にBさんがいて、BさんはAさんの子孫です。
id=3にCさんがいて、CさんはAさんの子孫です。
id=4にDさんがいて、DさんはCさんの子孫です。

この状況で、http://www.hoge.com/persons?id=*というURLがあり、*に則した人物と、それに関係する人物を「全て」見せたいとします。

つまり、http://www.hoge.com/persons?id=1にアクセスしてきたときは、Aさんのidをもとに、BさんとCさんとDさんの情報も拾ってくる。
http://www.hoge.com/persons?id=4にアクセスしてきたときは、Dさんのidをもとに、AさんとBさんとCさんの情報も拾ってくる。


そういう場合に書くクエリーは、どうすればいいのでしょうか?

SELECT * FROM persons WHERE id = 引数 OR descendant_of = 引数;
これだとAさんの場合、つまり自分が子孫関係のトップにいる場合にしか使えません。

サーバー側で何度もクエリー発行すれば幾らでも可能だと思います。

SELECT * FROM persons WHERE id = 引数 OR descendant_of = 引数;
まず、このクエリで取得して、次にサーバー側でdescendant_ofの値を見て値が存在すれば、
SELECT * FROM persons WHERE id = descendant_ofの値 OR descendant_of = descendant_ofの値;
というクエリを流します。これを何回も繰り返していけば、やがて全件取得できると思います。


しかし、明らかに効率が悪いと思います・・・。
もっといい方法はないのでしょうか?
0871NAME IS NULL2014/04/24(木) 02:47:21.61ID:???
>>870
>>1 と 別スレだけどこれを読んでください。
http://nozomi.2ch.net/test/read.cgi/php/1397862294/3
0872NAME IS NULL2014/04/24(木) 08:14:51.94ID:???
>>870
>>1
> 質問するときはDBMS名を必ず付記してください。
0873NAME IS NULL2014/04/24(木) 13:42:56.94ID:uvJm+LdL
>>870
関係する人物テーブル作ってしまう
0874NAME IS NULL2014/04/24(木) 13:44:19.91ID:???
>>870
標準SQLの再帰クエリで簡単に処理できるよ
08758702014/04/24(木) 20:29:51.40ID:VMhPPiZ3
大変失礼しました
DBはMySQLでした

再帰クエリは対応してないようです・・・。
0876NAME IS NULL2014/04/24(木) 20:42:54.78ID:???
>>875
MySQLだと泥臭いことやるのが基本かと
0877NAME IS NULL2014/04/25(金) 17:25:53.15ID:???
PostgreSQLだと思うけど
insert into 〜〜〜(〜〜) values(int, '〜')みたいなのでデータ追加するとき
intの値の範囲によって分けたいんだがどうしたらいいの

〜〜〜 values (1〜30, '小')
〜〜〜 values (31〜60, '中')
〜〜〜 values (61〜90, '大')
みたいに
0878NAME IS NULL2014/04/25(金) 17:34:52.72ID:+Fb19Efw
質問です。
MySQL5です。
テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。
各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。
言っていることが、よくわからなくてすみません。

元テーブル
DATE, CODE, VALUE
....
20140401, 11, A
20140402, 12, B
20140403, 11, C
20140404, 13, D
20140405, 12, E
20140406, 11, F
....

欲しい結果
20140401, 11, A
20140403, 11, C
20140406, 11, F
20140402, 12, B
20140405, 12, E
20140404, 13, D

宜しくお願い致します。
0879NAME IS NULL2014/04/25(金) 17:41:21.67ID:???
>>877
どうも質問が明確じゃないけど、
insert into tname select 〜
の形式にすればとりあえず解決しそうな話に見える。

>>878
order by code, date ということ?
0880NAME IS NULL2014/04/25(金) 17:47:38.30ID:+Fb19Efw
879
分かりずらい
欲しい結果にしてしまいました。

第1キーは、日付です。

元テーブル
DATE, CODE, VALUE
20140401, 13, A
20140402, 11, B
20140403, 12, C
20140404, 13, D
20140405, 12, E
20140406, 11, F

欲しい結果
20140401, 13, A
20140404, 13, D
20140402, 11, B
20140406, 11, F
20140403, 12, C
20140405, 12, E

宜しくお願い致します。
0881NAME IS NULL2014/04/25(金) 18:03:58.58ID:???
>>880
それでもやっぱりよくわからないけど。
select t1.* from tname as t1 join (select min(date), code from tname group by code) as t2 using (code)
order by t2.date, t1.date
とか?
(ずっと昇順だけどそこは気にしてない)
0882NAME IS NULL2014/04/25(金) 18:32:13.82ID:+Fb19Efw
ありがとうございます。
その通りでした。
0883NAME IS NULL2014/04/25(金) 20:30:56.18ID:???
>>879
俺も何が何だかなんだすまない

分類(年収 int, 階級 char(20), primary key (年収))

があったとして
年収 〜300万は下流階級 300万〜800万は中流階級 800万〜上流階級
ってのをinsertしたいとしたとき
valuesだと1万刻みでinsertしていかなきゃいけない気がするんだが
それだとキリがないからどうしたものかということなのです
0884NAME IS NULL2014/04/25(金) 20:46:03.81ID:???
>>883
SELECT "年収",
CASE WHEN "年収" <= 300 THEN '下流階級' WHEN "年収" <= 800 THEN '中流階級' ELSE '上流階級' END "階級"
FROM (SELECT generate_series(1,1000) as "年収") AS sal
0885NAME IS NULL2014/04/25(金) 21:28:36.13ID:???
>>883
その 階級 とやらはデータベースに入れる必要あるのか?
まあ、あるならご愁傷様でした。
0886NAME IS NULL2014/04/26(土) 03:01:50.09ID:???
・postgres 1.81

・http://eow.alc.co.jp/search?q=sort&;ref=sa

このような辞書を作りたいのですが、カラムはどのようにわければいいでしょうか?
また、例文は例文で別にストックして表示する形がベストでしょうか?

よろしくお願いします
0887NAME IS NULL2014/04/26(土) 03:38:49.28ID:???
>>886
スレ違い。
あとpostgreSQLにそのバージョンのものはない。
0888NAME IS NULL2014/04/26(土) 13:15:39.60ID:???
>>886
DB設計を語るスレ 7
http://toro.2ch.net/test/read.cgi/db/1386312737/
0889NAME IS NULL2014/04/28(月) 10:02:45.01ID:???
>>883
階級入れないで、あとでUPDATEした方が速そう
0890NAME IS NULL2014/05/02(金) 20:02:09.57ID:yPuMCXLM
質問させてください。MySQLです。

上位100件を抽出してその中から10件をランダムに抽出したい。
SELECT文はどう書けばいいですか?1行でできますか?
0891NAME IS NULL2014/05/03(土) 14:54:24.11ID:???
「Mysql」「ランダム」
0892NAME IS NULL2014/05/03(土) 16:12:10.33ID:???
>>890
select * from (select * from ranking order by rankno limit 100) sa a order by rand()
0893NAME IS NULL2014/05/03(土) 16:13:27.41ID:???
ミス
select * from (select * from ranking order by rankno limit 100) sa a order by rand() limit 10
0894NAME IS NULL2014/05/03(土) 16:15:21.45ID:???
saってなんだよ
0895NAME IS NULL2014/05/03(土) 16:19:18.56ID:???
なんやろな。
select * from (select * from ranking order by rankno limit 100) as a order by rand() limit 10
0896NAME IS NULL2014/05/04(日) 13:27:58.62ID:DCyCq8w9
質問です。
PostgreSQL9.3

テーブル
DATE, VALUE
20140401,-13
20140402,-11
20140403, 12
20140404, 13
20140405, 12
20140406,-11

欲しい結果
DATE, VALUE ,COUNT
20140401,-13, 1
20140402,-11, 2
20140403, 12, 1
20140404, 13, 2
20140405, 12, 3
20140406,-11, 1

このように、VALUEの値の正負の連続数をCOUNTし出力するようなSQLは書けるのですか?
0897NAME IS NULL2014/05/04(日) 14:35:30.13ID:???
答えです。
書けます。
0898NAME IS NULL2014/05/04(日) 14:55:09.03ID:xQR76yAx
横から失礼します。
>>896を実現するクエリを思いつかないので、クエリ内容を教えてください。
できれば>>897さんにお願いしたいです。
0899NAME IS NULL2014/05/04(日) 15:20:40.38ID:???
>>898
横から失礼します。
お断りします。
0900NAME IS NULL2014/05/04(日) 15:41:08.54ID:???
恥ずかしい人だな
0901NAME IS NULL2014/05/04(日) 15:50:11.87ID:???
>>896
横から失礼するけど
なんでもかんでもSQLでしようとせず受けたプログラム側で処理したら?
ぽすぐれサーバの負荷も考えたほうがいい
0902NAME IS NULL2014/05/04(日) 15:59:27.75ID:???
横から失礼します。
横入りはお止め下さい、シナ人や朝鮮人じゃあるまいし
0903NAME IS NULL2014/05/04(日) 16:02:08.49ID:???
どっちが簡単かによる
0904NAME IS NULL2014/05/04(日) 16:08:21.29ID:???
>>901
プログラム側で処理するにしても、一旦はDBだけで出力する方法を試してみるよ
その上でどっちがベストか考えたらいいし
0905NAME IS NULL2014/05/04(日) 16:16:14.82ID:???
SQLはDBから受ける結果の絞り込みにだけ要いて、
処理やら加工やらは受けるプログラム側でするのが良策。
基本的にDBサーバは1つ、そこへ集中してアクセスがくるのだから、
負荷とかを考えれば自ずとそうなるだろ。ってかそうしろ。
0906NAME IS NULL2014/05/04(日) 16:27:49.73ID:???
バカかコイツ
そんなもん状況によるだろうが
0907NAME IS NULL2014/05/04(日) 16:40:39.66ID:???
>>905
おいおいそんな低レベルな話を人に押し付けるな

DBサーバ1つって

絞り込みにだけって
0908NAME IS NULL2014/05/04(日) 16:42:19.71ID:???
はい、そーでちゅね
0909NAME IS NULL2014/05/04(日) 16:43:04.02ID:???
>>898
Window関数使えばできるよ
0910NAME IS NULL2014/05/04(日) 17:04:07.12ID:???
>>905
ありがとうございました。クライアント側のプログラミングも出来ないくらいの低レベルなので、とりあえずSQLだけでなんとか出来ないかな?と思ったものですから。確かに分けて考えるべきなのかもしれません。

>>909
Window関数では無理っぽいな……、と思ったのですが……。


プロシージャとかいうのを使えば実現できますかね?
0911NAME IS NULL2014/05/04(日) 17:04:27.04ID:???
>>896
こうかな?

select T1."DATE",
    T1.VALUE,
    COUNT(*)
from  TableName T1
    inner join
    TableName T2
    on T1."DATE" >= T2."DATE"
    and ((T1.VALUE > 0 and T2.VALUE > 0) or (T1.VALUE < 0 and T2.VALUE < 0))
where  not exists (
        select *
        from  TableName T3
        where  T1."DATE" > T3."DATE"
        and   T2."DATE" < T3."DATE"
        and   ((T1.VALUE > 0 and T3.VALUE < 0) or (T1.VALUE < 0 and T3.VALUE > 0))
    )
group by T1."DATE", T1.VALUE
order by T1."DATE"
;
09128962014/05/04(日) 17:29:19.64ID:???
>>911
おおっ、すごい!!出来ました!!!
どうなっているのかさっぱり解りませんが、じっくりと見て勉強させて戴きます、ありがとうごさいました。

SQLって奥が深いんだなぁ〜〜。
0913NAME IS NULL2014/05/04(日) 20:29:26.57ID:xQR76yAx
where句が秀逸ですね。ありがとうございます。
0914NAME IS NULL2014/05/04(日) 22:49:28.51ID:???
>>910
Window関数だけだとダメだった。再帰付き

WITH RECURSIVE R AS (
SELECT
"DATE", "VALUE",
row_number() OVER(ORDER BY "DATE") AS "ROW",
lag("VALUE", 1, 0) OVER (ORDER BY "DATE") * "VALUE" <= 0 AS FIRST
FROM TableName
), S AS (
SELECT
R.*, 1 AS "RANK"
FROM R WHERE FIRST
UNION ALL
SELECT
R.*, S."RANK" + 1 AS "RANK"
FROM S, R WHERE R."ROW" = S."ROW" + 1 AND NOT R.FIRST)
SELECT "DATE", "VALUE", "RANK" FROM S ORDER BY "DATE";
0915NAME IS NULL2014/05/05(月) 05:04:59.63ID:???
>>896 出力のここの部分がどうして連続数と看做されているのかわからない。単純な間違えかな。

20140401,-13, 1
20140402,-11, 2
0916NAME IS NULL2014/05/05(月) 06:15:42.31ID:???
>>915
ごめん。意味がわかった。正の集合の連続数。負の集合の連続数ということか。>>915は取り消し。
0917NAME IS NULL2014/05/05(月) 06:19:21.91ID:???
>>916
すみません。またまた訂正。正の一つだけを含む連続した組と負の一つだけを含む連続した組にそれぞれ連続数を与える。ですね。
09188962014/05/05(月) 09:31:00.17ID:???
>>914

Lag関数を使うと歯抜け日数に対応することが出来ないと思っていたのですが、row_number()関数からの自己結合でうまくいくのですね!!勉強になります。
ただ、Lag関数の3つ目の引数0は何を意味するのですか?PostgreSQL9.3では対応していないようです。

再帰部分が理解不能なので良く見て勉強させて頂きます。
ありがとうございました。
0919NAME IS NULL2014/05/05(月) 09:46:18.85ID:???
>>918
lagの2個目がステップ、3個目は初期値
PostgreSQLで対応してるよ
09208962014/05/05(月) 09:47:51.48ID:???
>>917
はぁ〜〜、なるほど、そういう風に考えるのですか!??

直前の行の自己出力列を比較して連続数として+1するようなイメージだったのですが……
09218962014/05/05(月) 09:58:47.74ID:???
>>919
わ、わかりました!?……動きました。
ふぅ〜…、むずかしいな…。
SELECT句の中で比較演算子が使えるのも初めて知りました!!
ありがとうございました。
0922NAME IS NULL2014/05/05(月) 10:43:01.00ID:???
そのレベルじゃ自分で書けないSQL使っても後で苦労するぞ
と書いてみる
0923NAME IS NULL2014/05/05(月) 15:29:58.19ID:tGrX0Jlt
質問失礼します。
たとえば文字列(VARCHAR2)で定義された計算式(足し算や掛け算など)から、
計算結果を取得するにはどうすればいいでしょうか?
0924NAME IS NULL2014/05/05(月) 15:32:45.34ID:???
>>923
アプリ側でやったら?
0925NAME IS NULL2014/05/05(月) 15:37:32.29ID:tGrX0Jlt
>>924
私sql developerを使用しているのですが
計算式が書いてあるテキストを読み込んで
その読み込んだ式の計算結果を取得したのですがTO_NUMBERでは
演算子があると使えないので悩んでいます。
0926NAME IS NULL2014/05/05(月) 15:39:16.54ID:tGrX0Jlt
>>925
誤 式の計算結果を取得したのですが
生 式の計算結果を取得したいのですが
0927NAME IS NULL2014/05/07(水) 11:13:07.70ID:???
eval関数作るしか、、、
0928NAME IS NULL2014/05/07(水) 23:04:05.11ID:???
一旦アプリ側で読み出して動的SQL組み立てて流せばいいような。
セキュリティは気をつけなきゃだけど。
0929NAME IS NULL2014/05/08(木) 08:45:23.13ID:???
>>923
アプリ側でeval
DB側でfunction定義してeval
0930NAME IS NULL2014/05/08(木) 18:46:33.88ID:???
長文失礼postgreSQLです
たとえばですがある大会で1位3P・2位2P・3位1P・4位以下は0Pという風な加点があって
それぞれのチームの競技結果がデータとしてあるとします

というわけでテーブル
・競技結果
順位,チームコード,競技コード
・加点
順位,得点
・チーム
チーム名,チームコード

このとき大会後の各チームの総得点とチーム名を出力させたいわけですが0点のチームがうまく出せません

select チーム名, sum(得点) as 総得点
from (チーム join 競技結果 using (チームコード)) join 加点 using (順位)
where 順位 <= 3
group by チーム名, チームコード

こうすると総得点が0点のチームはチーム名すら出なくなってしまうわけですが上手い方法はありませんか?
超初心者なため色々とツッコミどこがあるかと思いますがなるべく単純にお願いします
0931NAME IS NULL2014/05/08(木) 19:15:59.03ID:???
>>930
外部結合(OUTER JOIN)使え
SUM(NULL)はNULLだから、NULLを0に置き換えるのも必要かもしれん
0932NAME IS NULL2014/05/08(木) 19:47:01.05ID:???
select チーム名, coalesce(総得点, 0) as 総得点
from チーム
left join (
select チームコード, sum(得点) as 総得点
from 競技結果
left join 加点 using (順位)
where 順位 <= 3
) 総得点テーブル using (チームコード)
group by チーム名, チームコード
0933NAME IS NULL2014/05/25(日) 17:19:45.43ID:cvRaurYJ
2chはファイルシステムベースでログを管理しているようだけどデータベースシステムを採用していないのは何故ですか?
管理上RDBMS使った方が良さそうな感じがするのですが
0934NAME IS NULL2014/05/27(火) 19:46:39.54ID:NCmL9RH7
直った?
0935NAME IS NULL2014/05/28(水) 01:49:19.70ID:???
・DBMS名とバージョン Oracle11gR2
PL/SQLのプログラムを作ってるのですが期待通り動作しておらず、その理由を知りたく思ってます

テーブルA
a1 | a2
---------
100 | 1
100 | 2
200 | 3
というテーブルにて、a1='100'のレコードについては、a2に100を加算、といった処理をしたく思っており、
以下のようなPL/SQLのプログラムを作りました

set serveroutput on
declare
cursor c1 is SELECT A1, A2 FROM A WHERE A1='100';
aa1 number;
aa2 number;
aa3 number;
sql1 varchar2(1000);
begin
open c1;
loop
fetch c1 into aa1, aa2;
exit when c1%NOTFOUND;
aa3:=100;
-- NG
-- sql1:='UPDATE A SET A2=A2+:3 WHERE A1=:1 AND A2=:2';
-- execute immediate sql1 using aa1, aa2, aa3;
-- OK
sql1:='UPDATE A SET A2=A2+100 WHERE A1=:1 AND A2=:2';
execute immediate sql1 using aa1, aa2;
if (SQL%FOUND) then
dbms_output.put_line('updated');
end if;
end loop;
commit;
end;
/
exit

ここでコメントに「OK」と「NG」とありますが、「OK」部のようにSQLに「A2=A2+100」と記述して
execute immediateすると期待通り動作するのですが、「NG」部のように「A2=A2+:3」と
バインド変数を使うと、エラーは出ないけど、何かの処理もされてない、という状態となります
execute immediate後にsqlcodeやsqlerrmを見ても、エラー類も出力されていません

なぜ「NG」部のような書き方だと、うまくいかないのでしょうか?

また、最終的には後者のようなバインド変数を使ったコードにしたく思っているのですが、
バインド変数を使っても前者のように動作させる方法はありますか?
0936NAME IS NULL2014/05/28(水) 05:59:39.08ID:???
PL/SQLってこのスレの範疇か?

>>935
バインド変数は名前に関係ないから
:3,:1,:2に対してaa1,aa2,aa3の指定だと
:3=aa1
:1=aa2
:2=aa3
って展開されてると思われ
結局whereに一致する条件がないから何も更新されない

つかこれ、この程度でPL/SQL使う必要ないよな。例として上げてるだけ?
0937NAME IS NULL2014/05/29(木) 00:24:18.85ID:???
>>936
情報ありがとうございました
いただいた情報を基に、バインド変数を並び替えたところ、期待通りの動作をしました
ありがとうございました

なお、PL/SQLのスレが無かったので、SQLでいいのかな?と思って書き込んでしまいました
また、実際には、もうちょっと色々なデータの加工をする処理となっているのですが、
書き込んだコードは事象を端的に示したく思って作った例です
失礼いたしました…
0938NAME IS NULL2014/05/29(木) 22:34:28.70ID:IEd/ec0c
SQLserverのSQLについて質問させてください。

仕事上困っておりまして、どうしても本日中、又は明日の朝までに
回答が欲しいので、SQLserverのスレにも質問させてもらってます。
派遣なので質問する人がいないので何卒お願い申しあげます。

テーブルBにカラム1に”1”、カラム2に"CODE='12345'"が入っています。
※カラム2は条件式が入ってます

やりたいことは、テーブルAをSELECTしたときにテーブルBをINNER JOINして
テーブルAのカラム1とテーブルBのカラム1が一致した場合
WHERE句の条件にテーブルBのカラム2の文字列条件式を条件として使いたいのですが
うまくいきません。
ご教示ねがえませんでしょうか?

SELECT * FROM テーブルA as A INNER JOIN テーブルB as B
ON A.カラム1=B.カラム1
WHERE
---ここからがわかりません
CASE A.カラム1 WHEN B.カラム1 THEN B.カラム2 END

カラム2に"AND CODE='12345'"を条件に追加したいのですが
どうすればできますでしょうか


発行したいsqlは以下になります

SELECT * FROM テーブルA as A INNER JOIN テーブルB as B
ON A.カラム1=B.カラム1
WHERE
CODE='12345'

テーブルBに入った文字列条件式を
現実の条件にしたいのです。
テーブルA、Bのカラム1同士が一致した場合

困ってます
なにとぞよろしくお願いします
0939NAME IS NULL2014/05/29(木) 23:20:39.69ID:???
>>938
SELECT 'SELECT * FROM テーブルA as A INNER JOIN テーブルB as B
ON A.カラム1=B.カラム1
WHERE ' + A.カラム2
FROM テーブルA
INNER JOIN テーブルB
ON テーブルA.カラム1=テーブルB.カラム1
WHERE A.カラム1=B.カラム1

みたいにSQLを出力するSQL書いて、その出力をT-SQLに食わせりゃいいんじゃね?
0940NAME IS NULL2014/05/29(木) 23:25:54.07ID:IEd/ec0c
>>939様
回答ありがとうございます
机上だけではいけるか判断できないので
明日さっそく会社でSQL作ってみます

できるといいのですが・・・
0941NAME IS NULL2014/05/30(金) 07:58:28.50ID:???
>>938
マルチかよ、しかも1分違いとか常識ないんか
http://peace.2ch.net/test/read.cgi/db/1385363382/138
0942NAME IS NULL2014/05/30(金) 14:46:31.21ID:???
マイナージャンルかもしれないけど質問させてくれ。列指向DBについて。

今まで行指向のDBしか触ったことがなかったんだが、SELECTが早くなるという話を聞いて
なんとなく列指向のDBに手を出してみたんだが、いまいち早くなった気がしない。
というか、INDEXを使わない機構のせいでだいたい列指向のほうが遅いように思える。

行指向の場合はINDEXを使うようにチューンしてやれば早くなる、という常識はあったけど、
列指向の場合は〇〇するようにすれば早くなるよ、というのはあるんだろうか?
曖昧な問いかけで申し訳ない。
0943NAME IS NULL2014/05/30(金) 16:47:33.19ID:???
SybaseIQとかか?
どっちにしろスレチだと思うが
0944NAME IS NULL2014/05/30(金) 21:58:39.96ID:???
列指向DBって、従来のRDBMSだと糞遅いDWH向けだろ。
列指向DBを速くしたいというなら、それに向いた問題を持ってこなきゃいけない。
0945NAME IS NULL2014/05/31(土) 00:53:51.07ID:???
>SELECTが早くなるという話を聞いて

限られた条件だけだよ
0946NAME IS NULL2014/05/31(土) 10:26:14.62ID:???
1年目のDBAですが結合とか副問い合わせの理解が乏しいです。
SQLをマスターするためにオススメの書籍あれば教えて欲しいです。データベースはOracleがメインです。
0947NAME IS NULL2014/05/31(土) 10:33:26.28ID:???
>>946
Oracle Master Bronzeの参考書
0948NAME IS NULL2014/05/31(土) 11:24:10.16ID:???
>>947
その他の良本をお願いします
0949NAME IS NULL2014/05/31(土) 14:30:28.66ID:???
俺のチンポをしゃぶってれば副問い合わせは分かるようになる
結合は、俺がチンポはめながら教えてやる
0950NAME IS NULL2014/05/31(土) 17:26:33.09ID:???
>>946
よくDBA名乗ってるな
どんな基準だろ?
0951NAME IS NULL2014/05/31(土) 17:42:18.74ID:???
Database Assistantか
0952NAME IS NULL2014/05/31(土) 18:40:52.36ID:???
>>948
図書館に行ってSQLの入門書片っ端から借りて読めよ
結合とか副問い合わせ云々言ってるレベルだったらOracleとか関係ないだろw
0953NAME IS NULL2014/05/31(土) 23:04:04.92ID:???
てかOracleの管理者って、AWRレポート作ってサポートに投げる、
サポートに言われたSQLをコピペし結果をコピペする、を
無駄なく速やかにこなすことが一番重要なスキルなのではないか
0954NAME IS NULL2014/05/31(土) 23:19:28.10ID:???
いや、AWRレポートぐらい自分で読めよ
0955NAME IS NULL2014/06/01(日) 12:11:59.55ID:???
DBMSのセットアップやチューニングの本はたくさんあるけど、
クエリの書き方や、スキーマの設計に関わる本の鉄板って知らないなぁ。

以前読んだ SQLアンチパターン って本はなかなかおもしろかったけど、
得られるものはあまりなかったし、かなりピンポイントだからなぁ。
0956NAME IS NULL2014/06/01(日) 12:25:12.83ID:???
>>954
現場での独自の判断が、初動のまずさのきっかけとなり、システムの復旧が遅延した、という
始末書を書く破目になるか

それともサポートベンダの対応の遅れにより、システムの復旧が遅延した、という報告を
ベンダの始末書添付してまとめる側となるか

その違いは大きい
後々の残業時間的に
0957NAME IS NULL2014/06/01(日) 13:33:37.29ID:???
おいやめろ
0958NAME IS NULL2014/06/01(日) 13:36:21.82ID:???
さすがOracler
0959nntarou2014/06/01(日) 18:20:32.53ID:otWRvot4
稲城市立向陽台小学校評判
http://tn.en.fishki.net/26/upload/en/201406/01/1273947/adlrk258.jpg
稲城市立向陽台小学校評判
0960NAME IS NULL2014/06/02(月) 12:19:54.47ID:???
>>943-945
いやDB2なんだ…
ありがとう。条件限られてるんだな。もっと調べてみるよ
0961NAME IS NULL2014/06/02(月) 20:01:07.33ID:???
mysql 5.5です
コードマスター codeMaster
code int(11) not null primary key,
weeklymake int default 0, ←週間累計データ作成対象は1
dat1 varchar(20) default null

週間累計データ weeklydata
code_w int(11) not null,
date_ws date not null,
date_we date not null,
ruikei int default 0,
PRIMARY KEY (code_w,date_ws)

となっているんですが、コードマスターのweeklymakeが1となっていて週間累計データにデータが無いコードを出したいのですが、どのように書けば良いのでしょうか
0962NAME IS NULL2014/06/02(月) 21:21:31.06ID:???
codeMasterには日付情報がないのか?
0963NAME IS NULL2014/06/02(月) 21:26:03.41ID:+lU7QBbR
>>961
select code where weeklymake = 1 and code not in (select code_w from weeklydata);
0964NAME IS NULL2014/06/02(月) 21:49:11.49ID:???
>>962
codeMasterには日付に関する情報は入れてません。例えばデータの登録日付とかですよね?
今後考えてみます。

>>963
ありがとうございます。
0965NAME IS NULL2014/06/02(月) 22:50:31.94ID:+lU7QBbR
codeMaster.code と weeklydata.code_w が同じものであるという記述がないから混乱を招いたのです。

ところで、 not in だとパフォーマンスが悪いかもしれない
(というか、データが増えるにつれ、よくない結果を招く場合がほとんどな)ので、
そのあたりは随時プランナとにらめっこしながら検討してみてください。

まずは直感的に分かりやすい not in からと思いそうしてます。
0966NAME IS NULL2014/06/02(月) 23:24:49.72ID:???
直感的にわかりにくいものを選ぶとは
0967NAME IS NULL2014/06/03(火) 00:10:25.36ID:m5j4pUi4
そう?
not existsのような相関サブクエリって最初は苦手だったよ。
それとも外部結合やexcept?
個人的にはexceptが次点ではあるけど。

ともあれ、主観を伴うので、直感的に分かりやすいものを書いてあげるとよいのでは。
0968NAME IS NULL2014/06/03(火) 00:55:35.18ID:???
>>963のはdistinctをつけたほうが良い気がする。
0969NAME IS NULL2014/06/03(火) 02:03:44.36ID:???
>>963
from書いとけよw

>>968
メインのクエリはcodeが主キーなんだからdistinct意味なし
サブクエリは結果に影響しないから、distinct意味なし
っていうか、ホントにdistinct処理されたらその分遅くなる可能性が高い

mysqlがどうか知らんが、いまどきのオプティマイザならこのぐらいのnot inは綺麗に展開するんじゃないかな
まずはわかりやすいSQLでnot inからって>>965の意見には同意する
0970NAME IS NULL2014/06/03(火) 09:29:34.68ID:???
not inを綺麗に展開できるオプティマイザがあれば教えて欲しい
EXPLAIN結果もな

not existsはmysqlは綺麗に展開できないらしいが
他の有名どころは展開できるな

直感的にはどっちでもいい。
code_wにnot nullついてるし、処理順番の違いだけ
0971NAME IS NULL2014/06/03(火) 16:06:59.19ID:???
相関サブクエリじゃないnot inって展開のしようがないかもしれんな

SQL Server2008でテーブルだけつくって試したらどっちも
codeMasterスキャンしてネステッドループでweeklydataのインデックスシークだったわ
not inが相関サブクエリじゃなくてもちゃんと親のcodeでシークしてる

weeklymakeにインデックスないからcodeMasterフルスキャンは妥当?
codeMasterがそうとうな件数とかじゃないとこのプランじゃないかなぁ
0972NAME IS NULL2014/06/03(火) 20:51:24.92ID:???
オラクルマスター12cブロンズのSQLは合格しましたが、
12cDVAで何を参考書にすれば良いか分かりません。
0973NAME IS NULL2014/06/05(木) 10:17:57.98ID:???
テーブル設計の質問です

・MySQL 5.1.66
・テキスト管理の掲示板のツリー構造を一つのテーブルに格納

1,16,23,3 (1から始まるスレッド)
220,325,459,23,125 (220から始まるスレッド)

一行が掲示板の一スレッドとなるデータがテキストで保管されています
番号はユニークな発言番号です
例では220を親として325→459→23とつながります
順番を入れ替える必要性があり、必ずしも昇順として保存されません
この場合どんなテーブル構造が望ましいでしょうか?

ユニーク番号/先頭の番号/スレッド内の位置

こういう形でしょうか?

よろしくお願いします
0974NAME IS NULL2014/06/05(木) 10:59:12.92ID:???
DB設計を語るスレ 7
http://peace.2ch.net/test/read.cgi/db/1386312737/l50
0975NAME IS NULL2014/06/16(月) 17:38:52.08ID:mYpkaepD
0時をまたぐ時間(18時〜2時とか)をselectで抽出する場合、
どういうSQL文を書けばいいのでしょうか?
今は↓しているのですが、これだと上記の事が出来ません。

フィールド名:hour_start(時間・開始)、hour_end(時間・終了)
WHERE `hour_start` >=10 && `hour_end` <= 23

※10時〜23時ならこの書き方でも出来ます。

MySQL5.0.8を使用しています。
0976NAME IS NULL2014/06/16(月) 17:55:49.99ID:???
>>975
>WHERE `hour_start` >=10 && `hour_end` <= 23
これ、スタートが23時で終了が0時の場合も抽出されると思うけどいいの?
開始時間と終了まで何時間だったかをもたせたほうが楽なんじゃない?
09779742014/06/16(月) 18:30:59.74ID:???
>>976
確かに23時〜0時の登録が表示されますね・・・

>開始時間と終了まで何時間だったかをもたせたほうが楽なんじゃない?
の意味がわからないのですが、どういう設計になるのでしょうか?
09789752014/06/16(月) 18:31:41.22ID:???
番号間違えました。>>977は>>975のレスです。
0979NAME IS NULL2014/06/16(月) 18:39:52.76ID:???
? >>976へのレスで合ってるんじゃね?
>>975は自分自身だろ?
0980NAME IS NULL2014/06/16(月) 18:52:18.31ID:???
>>979
名前欄じゃ?
0981NAME IS NULL2014/06/16(月) 18:53:27.14ID:???
>>977
23時から0時なら
スタートが23で時間が1
18時から2時なら
スタートが18で時間が8
09829752014/06/16(月) 19:57:45.38ID:???
>>981
その意味は分かるのですが、それがDBの設計と結び付けません。

>フィールド名:hour_start(時間・開始)、hour_end(時間・終了)

というフィールド自体は保持するんですよね?
開始と終了の数値を求めたからって、それがどうデータ抽出に繋がるのでしょうか?
0983NAME IS NULL2014/06/16(月) 20:33:57.96ID:???
>>981が言いたいのは
フィールド名:hour_start(時間・開始)、duration(経過時間)
にしろってことだろ
0984NAME IS NULL2014/06/16(月) 20:39:22.38ID:???
開始、終了ともdatetime型にして日付ももたせるって手もあるが
0985NAME IS NULL2014/06/16(月) 21:18:36.57ID:???
次スレ
http://peace.2ch.net/test/read.cgi/db/1402919549/
09869752014/06/16(月) 21:30:07.93ID:???
>>983
それは分かるのですが、経過時間という概念が
どうWHEREの抽出条件になるかさっぱり分かりません
0987NAME IS NULL2014/06/16(月) 21:41:45.94ID:???
開始時間に経過時間を足して24より大きいか小さいかだろ
0988NAME IS NULL2014/06/16(月) 23:52:48.24ID:fMWsymIS
日付またぎのものをとりたいという話ではないと思うよ。
それなら、開始〜終了が24時間以内という条件を仮定した上で、終了 < 開始のものを抜けばいいだけだし。

>>975
期間データに対して期間条件をつけることになってるんだけど、包含関係はどうするの?
完全に含む場合のみ抽出?
09899752014/06/17(火) 00:38:18.32ID:???
もう一度やりたい事を整理して書きたいと思います。

目的:
お店の営業時間のように、20時〜1時というデータがあり、
SELECTでアクセスした時間に一致するデータを抽出したい

フィールド名:
id、hour_start(時間・開始)、hour_end(時間・終了)

登録レコード:
id|hour_start|hour_end
1|20|1
2|10|18
3|22|3

求める結果:
SELECTを実行した時間が21時として、idが1のみ抽出される

DBはMySQL5.0.8を使用し、出来ればフィールド名を変えずに
SQL文の工夫で目的の結果が得られるようにしたい。

何度もすみませんが、よろしくお願いします。
0990NAME IS NULL2014/06/17(火) 00:58:19.79ID:???
>>989
select id from tab where 21 <= hour_start and hour_end <= 21
union
select id from tab where 21 <= hour_start and hour_end+24 <= 21 and hour_start < hour_end
0991NAME IS NULL2014/06/17(火) 10:07:03.07ID:???
>>989
(
hour_start < hour_end and
((hour_start < 指定時刻 and 指定時刻 < hour_end) or (指定時刻 < hour_start and 指定時刻 < hour_end ))
)or(
hour_start > hour_end and
((hour_start < 指定時刻 and 指定時刻 < hour_end + 24) or (指定時刻 < hour_start and 指定時刻 < hour_end + 24))
)
じゃないかな
時刻がイコールのときはどうするかは考えて

必ず hour_start < hour_end になるように、hour_endを25時とかで格納するの検討した方がいいんじゃね
09929752014/06/17(火) 12:14:03.93ID:???
>>990-991
お二人ともありがとうございます。
MySQLではIFが使えるので、終了時刻が開始時刻より小さい場合は
+24する方法で何とか出来ないものかと悩んでいました。

アドバイスしていただいたSQLを元に、自分なりに勉強します。
0993NAME IS NULL2014/06/17(火) 13:50:34.74ID:aNFXRh4J
>>990
hour_start = 20 hour end = 22 のデータに対して、21指定で抜けない

>>991
指定時刻 < hour_end + 24 が常に真になるので
((hour_start < 指定時刻 and 指定時刻 < hour_end + 24) or (指定時刻 < hour_start and 指定時刻 < hour_end + 24))
↓
(hour_start < 指定時刻 or 指定時刻 < hour_start)
こうなる気がする。

>>975
-- 日付またがりのないデータ
hour_start < hour_end and
 指定時刻 between hour_start and hour_end
or
hour_start > hour_end and
(
 -- 日付またがりデータに対して当日指定時刻
 指定時刻 between hour_start and hour_end + 24
 or
 -- 日付またがりデータに対して翌日指定時刻
 指定時刻 + 24 between hour_start and hour_end + 24
)
0994NAME IS NULL2014/06/17(火) 13:54:52.58ID:aNFXRh4J
あと、擬似コードだけど、

指定時刻 between hour_start and if (hour_start < hour_end) then hour_end else hour_end + 24
or
指定時刻 + 24 between hour_start and if (hour_start < hour_end) then hour_end else hour_end + 24

みたいな書き方ができて、かつ条件付インデックスを貼れるなら速度的にも問題なくなるかもしれない。
蛇足かも。
0995NAME IS NULL2014/06/17(火) 20:02:17.40ID:???
>>991
後半は
((hour_start < 指定時刻 and 指定時刻 < hour_end + 24) or (指定時刻 < hour_start and 指定時刻 < hour_end))
だな
21時指定に対して、23時開始22時終了を引っかけるための条件だから
前半は、
(指定時刻 < hour_start and 指定時刻 < hour_end )はいらないな
場合分けで思いつくままに書いてたわ

between で書くと綺麗にまとまるけど、開始終了を含むかどうかによるからなぁ
そして未だに開始終了含むかどうか覚えていないw
0996NAME IS NULL2014/06/17(火) 20:28:53.44ID:aNFXRh4J
+24とかやんなくてもこれでよかった。やっぱ>>994は蛇足でした。

-- またがらず(or 1時間しか開いてないお店)
hour_start <= hour_end and
 -- 範囲の内側
 hour_start <= 指定時刻 and 指定時刻 <= hour_end
or
(
 -- またがり
 hour_start > hour_end and
  -- 範囲の外側
  (指定時刻 <= hour_end or hour_start <= 指定時刻)
)

>>995
between は閉区間だよ。両端含む。
要件的にはそのほうが適しているかと。
8時開店のお店を8時で抽出できないのはイマイチ。

終了時間については、指定時刻のとりうる値次第で変わるので要検討。
(というかそのへんの枝葉は本人がうまくやると思う。)

あと、1時間しか空いてないお店は考えにくいけど、hour_start <= hour_end にしてみた。
09979752014/06/18(水) 00:37:38.18ID:???
重ね重ね参考にさせていただきます。ありがとうございました。
0998NAME IS NULL2014/06/18(水) 03:55:02.94ID:RNcn8JR/
ひと段落
0999NAME IS NULL2014/06/18(水) 03:55:42.80ID:RNcn8JR/
したので
1000NAME IS NULL2014/06/18(水) 03:56:12.34ID:RNcn8JR/
埋めよっか。
10011001Over 1000Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。