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

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

SQL質疑応答スレ 12問目

1 :NAME IS NULL:2011/09/23(金) 18:22:58.35 ID:???
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

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

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

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

前スレ:
SQL質疑応答スレ 11問目
http://hibari.2ch.net/test/read.cgi/db/1299305530/

2 :NAME IS NULL:2011/09/23(金) 18:26:10.78 ID:???
SQL言語リファレンス一覧
Oracle Database
http://download.oracle.com/docs/cd/E16338_01/server.112/b56299/toc.htm
Microsoft SQL Server
http://msdn.microsoft.com/ja-jp/library/bb510741%28v=SQL.105%29.aspx
IBM DB2 Database
http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/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/

3 :NAME IS NULL:2011/09/23(金) 18:27:12.05 ID:???
過去スレ
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/

4 :NAME IS NULL:2011/09/23(金) 18:28:25.17 ID:???
よくある質問1

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

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

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

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

(答)
select A.ID,
    A.DATE,
    A.DATA
from TableName A
   inner join
   (select ID, max(DATE) as MAX_DATE
    from TableName
    group by ID
   ) B
   on A.ID = B.ID
   and A.DATE = B.MAX_DATE
;

5 :NAME IS NULL:2011/09/23(金) 18:29:28.53 ID:???
よくある質問2

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

というテーブルから

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

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

(答)
SELECT key,
    SUM(CASE data WHEN 'a' THEN 1 END) AS a,
    SUM(CASE data WHEN 'b' THEN 1 END) AS b
FROM table
GROUP BY key
ORDER BY key
;

6 :NAME IS NULL:2011/09/23(金) 18:30:37.54 ID:???
よくある質問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によって文法がかなり違うので注意

7 :NAME IS NULL:2011/09/23(金) 18:31:41.93 ID:???
よくある質問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

8 :NAME IS NULL:2011/09/23(金) 18:32:44.35 ID:???
よくある質問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ならこれを適当に改変すれば動きますが
 どのみちお奨めしません。

9 :NAME IS NULL:2011/09/23(金) 18:33:51.81 ID:???
以上、テンプレ終わり

10 :NAME IS NULL:2011/09/23(金) 18:50:00.23 ID:???
終了

11 :NAME IS NULL:2011/09/23(金) 19:07:06.06 ID:???
おつ

12 :NAME IS NULL:2011/09/23(金) 19:23:15.50 ID:???
ちん

13 :NAME IS NULL:2011/09/24(土) 22:57:23.29 ID:???
ぽこの

14 :NAME IS NULL:2011/09/24(土) 23:21:55.10 ID:???
さき

15 :NAME IS NULL:2011/09/25(日) 02:56:19.86 ID:???
っちょ

16 :NAME IS NULL:2011/09/25(日) 05:12:27.01 ID:???
ペロ

17 :NAME IS NULL:2011/09/25(日) 13:14:59.87 ID:???
なめ

18 :NAME IS NULL:2011/09/25(日) 14:59:49.75 ID:???
たい

19 :NAME IS NULL:2011/09/25(日) 17:52:40.43 ID:???
いいよ

20 :NAME IS NULL:2011/09/25(日) 18:10:01.89 ID:???
SQLマジSQL

21 :NAME IS NULL:2011/09/26(月) 02:22:08.21 ID:???
SQLマゾSQL

22 :NAME IS NULL:2011/09/27(火) 19:27:40.41 ID:???
まん

23 :NAME IS NULL:2011/09/27(火) 20:26:27.50 ID:???
ぼっ!!

24 :NAME IS NULL:2011/09/28(水) 01:27:57.03 ID:???
なめ

25 :NAME IS NULL:2011/09/28(水) 02:17:41.30 ID:???
よかった、SQLで悩んでる人はいなかったんだ

26 :NAME IS NULL:2011/09/28(水) 03:58:12.31 ID:???
いく

27 :NAME IS NULL:2011/09/28(水) 04:39:07.10 ID:???
でる

28 :NAME IS NULL:2011/09/28(水) 16:16:40.94 ID:???
のんで

29 :NAME IS NULL:2011/09/28(水) 17:46:52.33 ID:???
・DBMS名とバージョン
MySQL 5.0

・テーブルデータ
userテーブル

id int
name varchar

・欲しい結果&説明
nameはユニークではないので、値が同じレコードが複数存在します。
nameの値が自分と同じ値を持つレコードが存在するレコードだけ全件抽出したいです

例)
id  name
1   aaa
2   bbb
3   ccc
4   bbb

この場合idが2と4のレコードだけ抽出したいです。

どのようなSQLを書けばいいでしょうか。
よろしくお願いします。

30 :NAME IS NULL:2011/09/28(水) 18:56:10.19 ID:???
select * from user where name = 'bbb';

31 :NAME IS NULL:2011/09/28(水) 18:58:25.94 ID:???
ああー、意味がわかった
select * from user where id in (select id from user group by name having count(*) > 1)
こうかな

32 :NAME IS NULL:2011/09/28(水) 20:03:46.78 ID:???
where name in (select name以下略
の間違いだろ

existsでもいい

select *
from user T1
where exists (select *
       from user T2
       where T1.id <> T2.id
       and T1.name = T2.name)
;

33 :NAME IS NULL:2011/09/29(木) 02:06:55.87 ID:???
>>32
MySQLって無茶苦茶なSQL通すから、間違いじゃないのかもしれん
が、それを堂々と回答されてもなぁ

34 :NAME IS NULL:2011/09/29(木) 02:20:05.86 ID:???
>>32って無茶苦茶なSQLなの?

35 :NAME IS NULL:2011/09/29(木) 02:28:43.31 ID:???
>>34
>>32じゃなくて>>31

36 :NAME IS NULL:2011/09/29(木) 03:47:43.88 ID:???
>>35
>>33じゃなくて>>32

37 :NAME IS NULL:2011/09/29(木) 10:04:07.13 ID:wcoCYq1V
すみません。WebPG板より誘導していただいてきました。質問させてください。
mysqlver5.1.6で

update tbTest set flg=1 where seq_host = 524 AND non_printable=0 ORDER BY seq LIMIT 0 ,10
というのを実行しようとしたらmysqlではupdate文のoffsetができない?らしくエラーになりました。
これを実行(seqが特定のものから10個をフラグ建てたい)
するにはどうしたらいいでしょうか?



38 :NAME IS NULL:2011/09/29(木) 10:14:28.26 ID:???
update文にORDER BYって

39 :NAME IS NULL:2011/09/29(木) 10:33:32.84 ID:???
またMySQLか

40 :NAME IS NULL:2011/09/29(木) 10:51:08.82 ID:???
>>37
ためしてないけど
update tbTest set flg=1 where seq_host = 524 AND non_printable=0 AND seq in(
select seq from tbTest t where
(select COUNT(*) from tbTest where seq<t.seq)<10
)

updateのテーブルに別名付けれたり、updateにfromかけたりするともうちょっとすっきりするかもしれんが
それは多分標準的なSQLじゃないだろうし

41 :NAME IS NULL:2011/09/29(木) 11:44:08.94 ID:???
・DBMS名とバージョン : SQL-Server 2008

売り上げ
ID | AMOUNT     |
--+----------------------
1,200
1,300
1,400
2,100
4,100
5,200
5,300
6,400

得意先マスタ
ID | NAME     | OYA_CODE
--+----------------------+--------------
1,abc商事 本店,1
2,abc商事 い支店,1
3,abc商事 う支店,1
4,def工務店 本店,4
5,def工務店 い支店,4
6,ghiサービス,6
7,jklシステム,7

・欲しい結果
1,abc商事 本店,900
4,def工務店 本店,600
6,ghiサービス,6
7,jklシステム,400

・説明
会社ごとに、売り上げ合計を出したいです。
得意先マスタに親会社コードを持っているので、親会社がある場合は親会社に合算したいです。
自分が親会社の場合は自らのコードが入っています。




42 :NAME IS NULL:2011/09/29(木) 11:47:13.99 ID:???
すみません結果の訂正です
6,ghiサービス,400

自らが子会社の場合は親会社に合算するので、子会社としては表示しません。
お願いします。

43 :NAME IS NULL:2011/09/29(木) 12:15:39.26 ID:???
>>41
ID=1,2,3がabc商事なら、結果の1行目は200+300+400+100で1000じゃないのか?
売上テーブルに7,400の行が無いのは抜けてるだけか?
子会社の子会社はあり得るのか?

44 :NAME IS NULL:2011/09/29(木) 12:47:17.27 ID:???
>>41

抜けていたのと、計算違いすみません。
子会社の子会社(孫)はありません。
よろしくお願いします。




45 :NAME IS NULL:2011/09/29(木) 13:06:05.41 ID:???
>>44
select
ID,
NAME,
(select sum(AMOUNT) from 売り上げ where ID in (select ID from 得意先マスタwhere OYA_CODE=t.ID) ) as 合計
from 得意先マスタ t
where ID=OYA_CODE
とかでどうだ

46 :29:2011/09/29(木) 13:54:27.91 ID:???
>>31-32
教えていただいたSQLでほしい情報を取得できました。
ありがとうございました。

47 :NAME IS NULL:2011/09/29(木) 13:58:13.47 ID:???
>>45
ありがとうございます。
ちょっとテーブル構成がより複雑なので修正してやってみます。

副問い合わせがよくわからなかったものでして。

48 :NAME IS NULL:2011/09/29(木) 17:34:55.87 ID:???
お安い御用です。

49 :NAME IS NULL:2011/09/30(金) 13:38:16.93 ID:???
いみません、41の続きです。

○売伝(既に結合したビュー)
売伝番号,得意先名,得意先コード,親得意先コード
1000,A商事 本店,20000,20000
1001,A商事 あ店,20001,20000
1002,A商事 い店,20002,20000
1003,B工務店,30000,30000

○売伝明細(既に結合したビュー)
売伝番号,売掛締年月,明細金額
1000,2011/09,1000
1000,2011/09,2000
1000,2011/09,3000
1001,2011/09,500
1001,2011/09,500
1002,2011/09,100
1003,2011/08,300

■期待する結果
A商事 本店,5100
B工務店,300


■試してみたSQL

SELECT
dbo.売伝.得意先名,
dbo.売伝明細.売掛締年月,
(SELECT sum(dbo.売伝明細.明細金額)
FROM
dbo.売伝明細
WHERE
dbo.売伝.得意先コード
in
( SELECT dbo.売伝.得意先コード
FROM
dbo.売伝
WHERE
dbo.売伝.親得意先コード = t.得意先コード))
AS 合計
FROM
dbo.売伝 t,
dbo.売伝 CROSS JOIN
dbo.売伝明細
WHERE
dbo.売伝.得意先コード=dbo.売伝.親得意先コード


■問題点?
CROSS JOINのせいで同じ結果がたくさん出てきてしまいます。
ビュー同士の結合とかはダメなんでしょうか?
うまく親会社ごとに合計したいです。お願いします。

50 :NAME IS NULL:2011/09/30(金) 19:34:57.48 ID:???
dbo.売伝 CROSS JOIN
dbo.売伝明細
の部分が要らないと思う

51 :NAME IS NULL:2011/09/30(金) 19:51:55.39 ID:???
>>49
A商事 本店,5100
どういう計算だ?

52 :NAME IS NULL:2011/09/30(金) 20:15:10.05 ID:???
>>49
いろいろと突っ込みどころ満載なんだがとりあえず
SELECT
得意先名,
(SELECT sum(明細金額) FROM 売伝明細
WHERE 売伝番号 in
(SELECT 売伝番号 FROM 売伝 WHERE 親得意先コード = t.得意先コード)
) as 合計
FROM
売伝 t,
WHERE
得意先コード=親得意先コード

とか

JOINでやりたいなら、得意先名いらなければ
select
売伝.親得意先コード,
sum(明細金額) as 合計
from 売伝
 join 売伝明細 on 売伝.売伝番号=売伝明細.売伝番号
group by 売伝.親得意先コード

とかでできるんじゃないか
得意先名ほしければ、これに得意先マスタ(あるだろ?)JOINしろ

売掛締年月はどうしたいのかわからん

サブクエリにしてもJOINにしても、テーブルが紐付く条件よく考えてみることだ


53 :NAME IS NULL:2011/10/03(月) 14:22:55.85 ID:???
52様、何度もすみません。
結合とか、サブクエリでの集計がよくわからないのでビューを結合してみました。

テーブル名 : 単純結合
売伝番号 金額 得意先コード 売上伝票番号 得意先名 親得意先コード
1000 5000 101 1000 モナー商事 本社 101
1001 2000 102 1001 斉藤製作所 102
1000 1000 101 1000 モナー商事 本社 101
1000 3000 101 1000 モナー商事 本社 101
1002 600 105 1002 モナー商事 岩槻事業所 101
1002 700 105 1002 モナー商事 岩槻事業所 101
1002 900 105 1002 モナー商事 岩槻事業所 101
1003 10000 106 1003 モナー商事 浦和事業所 101

これで親会社結合して
モナー商事 本社 21200
斉藤製作所 2000

とするにはどうしたらよいでしょうか?



54 :NAME IS NULL:2011/10/03(月) 17:45:31.04 ID:???
なぜそんなビューを作るのか理解できん
すなおに個々のテーブル定義と欲しい結果書け

55 :NAME IS NULL:2011/10/03(月) 17:55:28.61 ID:???
>>54
すみません。
ここのテーブルは多すぎて。
ただ1つのテーブルに親得意先コードと親得意先コードがあるため
集計のときとかとてもやっかいです。

1つの方法としては親得意先コードで、得意先名を再取得してしまえば
望むようなことができるかな?と考えています。

私のSQL知識不足もありますが、元々DBのないCOBOLからの入れ替えで
かつ途中参加になったもので苦労しています。
今回は開発側ではないけど、ちょっと作って・・・と言われました。

あとでテーブルまとめます。


56 :NAME IS NULL:2011/10/03(月) 20:46:46.84 ID:???
これだけ見ると、Group Byでよさげ。

57 :NAME IS NULL:2011/10/03(月) 21:46:16.60 ID:???
なんで出てくるたびに例のデータが変わってんだよw
今までにあげられたSQLではどうダメだったのか書かないと釣りかと思うぜ

58 :57:2011/10/03(月) 21:48:09.14 ID:???
考え方は、親でgroup化して、合算値を出して、得意先と結合して出力する、だよ。
それを求めるための方法がいくつかあるけれど、みんなそういうSQL書いてくれてるはず。

59 : 忍法帖【Lv=7,xxxP】 :2011/10/03(月) 23:57:09.71 ID:???


60 :NAME IS NULL:2011/10/08(土) 01:04:08.04 ID:???
この2つのSQLは等価だと思っていますが、まちがっていますか?
mysql5.1

select
*
from
tblA inner join (tblB left join tblC on tblB.out_c = tblC.key_c) on tblA.out_b = tblB.key_b

select
*
from
tblA inner join tblB on tblA.out_b = tblB.key_b left join tblC on tblB.out_c = tblC.key_c

61 :NAME IS NULL:2011/10/08(土) 01:15:41.42 ID:???
・DBMS名とバージョン
PostgreSQL 9.0

・テーブルデータ
posts
 id

post_tags
 post_id
 tag_id

tags
 id
 tag(タグ文字列)

・欲しい結果
複数のタグ(tags.tag)を指定してAND検索でpostsを取得

・説明
実際にはユーザテーブルも絡んだりしてもうちょっと複雑なのですが、タグ一つでの検索の場合は以下のような感じになると思います。

SELECT posts.* FROM posts
JOIN post_tags ON post_tags.post_id = posts.id
JOIN tags ON tags.id = post_tags.tag_id
WHERE tags.tag = 'javascript'

これを例えばタグ「javascript」とタグ「php」両方を持つpostを取得するにはどうしたら良いでしょうか?


62 :NAME IS NULL:2011/10/08(土) 02:51:44.33 ID:???
>>61
>>6は見たかな?

63 :NAME IS NULL:2011/10/08(土) 04:06:16.33 ID:???
>>61
かな〜り特殊な書き方だけどやってみた。

select * from (
select *
from crosstab('SELECT posts.id,post_tags.tag_id, tags.tag FROM posts
JOIN post_tags ON post_tags.post_id = posts.id
JOIN tags ON tags.id = post_tags.tag_id ORDER BY 1, 2' ) AS
ct( id integer, tag1 character varying, tag2 character varying,tag3 character varying, tag4 character varying)
) as t
WHERE concat(tag1,tag2,tag3,tag4) LIKE '%javascript%'
AND concat(tag1,tag2,tag3,tag4) LIKE '%php%'

ちなみにconcatの部分は9.1じゃない場合はnullを除外して連結しなおす必要がある。
あと、crosstabを使ってるから、tablefuncモジュールインストールしないといけない。

最後のWHERE句は以下のように変更してもいける
WHERE (tag1 = 'javascript' OR tag2 = 'javascript' OR tag3 = 'javascript' OR tag4 = 'javascript')
AND (tag1 = 'php' OR tag2 = 'php' OR tag3 = 'php' OR tag4 = 'php')


64 :NAME IS NULL:2011/10/08(土) 12:41:02.81 ID:???
すなおに
WHERE post_tags.tag_id in (SELECT id FROM tags where tag = 'javascript' )
 AND  post_tags.tag_id in (SELECT id FROM tags where tag = 'php' )
とかじゃいかんのか?

65 :61:2011/10/08(土) 19:49:37.40 ID:???
>>62
JOINが増えてるだけでやろうとしてることは同じような感じでした!
参考にします、ありがとうございます

>>63
crosstab初めて聞きました!
まだSQL文を理解できてないですが、勉強してみます、ありがとうございます

>>64
post_tagsを2回JOINすれば大丈夫そうです!
SELECT posts.* FROM posts
JOIN post_tags AS pt1 ON pt1.post_id = posts.id
JOIN post_tags AS pt2 ON pt2.post_id = posts.id
WHERE pt1.tag_id in (SELECT id FROM tags where tag = 'javascript' )
AND pt2.tag_id in (SELECT id FROM tags where tag = 'php' )

もしくはJOINだけでもいけました。
SELECT posts.* FROM posts
JOIN post_tags AS pt1 ON pt1.post_id = posts.id
JOIN tags AS t1 ON t1.id = pt1.tag_id
JOIN post_tags AS pt2 ON pt2.post_id = posts.id
JOIN tags AS t2 ON t2.id = pt2.tag_id
WHERE t1.tag = 'javascript' AND t2.tag = 'php'

パフォーマンステストをして方法を検討したいと思います
皆さんありがとうございました!

66 :NAME IS NULL:2011/10/08(土) 20:31:16.03 ID:???
post_tagsを2回もJOINする必要あるの?


67 :NAME IS NULL:2011/10/08(土) 20:41:15.24 ID:???
ない。

68 :NAME IS NULL:2011/10/09(日) 03:19:30.94 ID:q9Vzai3H
掲示板のスクリプトをつくっています。
投稿のテーブルをつくり、
そこに1つの投稿へのレスもまとめて1つのテーブルに収めています。
設計としては以下のようになっています(説明のため多少シンプルにしています)

投稿テーブル
・id ID
・parent_id 上記のIDを外部キーとしたもの
・message 投稿内容

現在は
1.投稿テーブルから1ページに表示したい行を取得する
  SELECT * FROM posts WHERE parent_id IS NULL LIMIT 10
2.上記で取得した行の id を parent_id としている行を取得する
  SELECT * FROM posts WHERE parent_id = 1001;
  SELECT * FROM posts WHERE parent_id = 1002;
  SELECT * FROM posts WHERE parent_id = 1003;
                  :

つまり投稿1つに対してレスを探すためにSELECT文が1つ発行されており、
1ページ表示するのに 表示する投稿数+1 のSQL文が発行されてしまっています。
これを1つのSQL文で取得したいです。
別テーブルだとJOINでできるかと思いますが、同じテーブルでどうするのかがわかりません。
どういうSQL文にしたらよいでしょうか?
MySQL 5.1.51です。

69 :NAME IS NULL:2011/10/09(日) 06:58:37.42 ID:???
再帰的な検索しないなら、同じテーブルでも別名つけてJOINすれば良いだけ

再帰的に、レスのレスのレス...も欲しいとなると
・再帰SQLをつかう
・ストアドプロシジャで処理する
辺りが通常の手段だが、MySQLでサポートされてるかどうかはしらね
どっちもダメならホストアプリでやるかデータ形式工夫するかしないとダメだね


70 :NAME IS NULL:2011/10/10(月) 00:48:14.10 ID:???
SQLサーバーで、FROM 句のテーブル名をカンマ区切りで列記した場合は
INNER JOIN になる、であってるでしょうか??

71 :NAME IS NULL:2011/10/10(月) 01:20:51.35 ID:???
CROSS JOINだろ

72 :NAME IS NULL:2011/10/10(月) 01:28:27.16 ID:???
WHEREで結合条件指定しないならCROSS JOINじゃないか

と言っておいて考えると、CROSS JOINしてからWHEREで絞っても同じだから
結合条件があろうとなかろうとCROSS JOINと等価なのか

73 :NAME IS NULL:2011/10/12(水) 23:55:32.82 ID:qJQCBXRw
mysql5.1

なんだけどデータを挿入か上書きのどちらかをしたいときって
重複するデータの存在を調べたうえでif文で分岐させてUPDATE、REPLACEするのと
とりあえず重複があるかどうか分からない状態でDELETEさせてINSERTするのと
どっちが早い?



74 :NAME IS NULL:2011/10/13(木) 01:15:33.52 ID:???
知るかよ。それぐらい自分で試せばいいだろ。いちいち人に聞くな

75 :NAME IS NULL:2011/10/13(木) 01:28:17.44 ID:???
テーブル次第。

76 :NAME IS NULL:2011/10/13(木) 03:47:19.96 ID:???
> REPLACEは、もしテーブル内の古い行が PRIMARY KEY か
> UNIQUEインデックスの新しい行と同じ値を持っていれば、
> 古い行は新しい行が挿入される前に削除されるという事以外、
> INSERTと全く同じように機能します。

ふぅん

77 :NAME IS NULL:2011/10/13(木) 08:13:23.36 ID:???
>>73
俺ならいきなりINSERTする。
ON DUPLICATE KEY UPDATE 〜 付きで。

78 :NAME IS NULL:2011/10/13(木) 13:49:24.76 ID:???
>>77
なんでREPLACEじゃないの?

79 :NAME IS NULL:2011/10/14(金) 13:57:07.71 ID:efaJhCig
一つのデータに複数のキーワードを関連付ける物を作成しているのですが、
指定したすべてのキーワードが関連づけられているデータを探し出すSQL文はどのように書けばいいでしょうか?
データ構造はdata, keyの二つで、
data=1に20と30のkeyが関連づけられていたら、
(1,20),(1,30)
のようなデータが入っています。


80 :NAME IS NULL:2011/10/14(金) 14:48:17.47 ID:???
>>79
>>6

81 :NAME IS NULL:2011/10/14(金) 21:24:14.75 ID:i+DDWHmc
tblがひとつあり列は3つあります
jinbutu、no、orderplan
A 1 M
A 2 N
A 7 M
B 3 N
B 8 N
B 9 N
C 13 M
C 14 N
C 15 M
C 16 N
C 17 M

このtblをdelete文で整理したいんですが
jinbutuのなかでorderplanが同じ場合は
noが一番小さいやつだけを残したいです

↓このようにしたい
A 1 M
A 2 N
B 3 N
C 13 M
C 14 N

よろしくお願いします

82 :NAME IS NULL:2011/10/14(金) 22:26:39.85 ID:???
delete from tbl
where exists (select *
       from  tbl T2
       where tbl.jinbutu = T2.jinbutu
       and  tbl.orderplan = T2.orderplan
       and  tbl.no > T2.no)
;

83 :NAME IS NULL:2011/10/15(土) 12:49:36.09 ID:5cbPt9KL
ありがとうございます。deleteできました

84 :NAME IS NULL:2011/10/15(土) 14:21:21.13 ID:???
 宜しくお願いします
DBのバージョン  PupSQLite 1.9.13.5
テーブル     datetime INTEGER PRIMARY KEY, ymdhm text
MT4 というFX のトレードや、バックテストといった、過去の検証を行ったりするプログラムを、SQLiteを
用いて保存しているのですが、文字列フィールドのエスケープシーケンスについて教えてください。

string Table = "MATRIX_"+Period();
sqlite_exec (DB, "create table "+Table+" (datetime INTEGER PRIMARY KEY, ymdhm text)");

YMDHM[0] = "201010140730";
query = "insert into "+Table+" (datetime,yymmdd ) values (" + t1 + "," + YMDHM[0] + ");";

上記の(" + t1 + "," + YMDHM[0] + ");"; このあたりで、
sqllite error code 1
#define SQLITE_ERROR 1 /* データベースが間違っています、または存在していません */
このエラーが出ます、文字列のエスケープシーケンスのやり方が間違っていると思うのですが、分かりません
教えて頂けないでしょうか。

85 :NAME IS NULL:2011/10/15(土) 14:29:24.35 ID:???
スレ違い

86 :NAME IS NULL:2011/10/15(土) 14:30:23.00 ID:???
>>84です
どこで聞いたらいいでしょうか?

87 :NAME IS NULL:2011/10/15(土) 14:52:37.32 ID:???
言語のスレ

88 :NAME IS NULL:2011/10/15(土) 14:54:18.39 ID:???
「ymdhm」でCREATEして「yymmdd」でINSERTかよ?
VALUE句もTEXTならシングルクォートで囲えよ・・・まあSQLiteなら数値なら通るだろうけど。


89 :NAME IS NULL:2011/10/17(月) 15:00:20.57 ID:???
データベースを選べるように設計したいのですが、
そうなると独自実装みたいなSQLは排除する必要があります。
主要なフリーのRDBMS
MySQL PostgreSQL SQLiteあたりでどれでも動くような書き方をするのに、
参考になるサイトや文献があったら教えてもらえませんでしょうか?

90 :NAME IS NULL:2011/10/17(月) 15:16:59.16 ID:???
そういうライブラリを使う
or
標準SQLの範囲で記述するのはもちろん、各RDBMSが実装できていない部分を調べて、それらを使わないようにする。
これはマニュアルを見るのが楽。

91 :NAME IS NULL:2011/10/17(月) 16:14:22.94 ID:???
sqliteでアプリを起動した日のみ
insert into TableName (datetime) values (datetime('now', 'localtime'));
このようにその日の日付(2011-10-17)をもったレコードを1日1回挿入しているのですが
90日まで遡ってまでのレコードを取得したい場合どう書くのが適切でしょうか?

92 :NAME IS NULL:2011/10/17(月) 16:21:20.95 ID:???
日付関数あるなら簡単でしょう
where 日付レコード > 現在時刻-90日分の時刻

93 :NAME IS NULL:2011/10/17(月) 16:42:21.50 ID:???
ありがとう
今日から遡って取得したいから
SELECT * FROM TableName ORDER BY id DESC
WHERE datetime > datetime('2011-10-17', '-90 days');
で大丈夫かな

94 :NAME IS NULL:2011/10/17(月) 17:46:07.93 ID:???
その調子で全部確認していく気かい

95 :NAME IS NULL:2011/10/17(月) 18:15:30.41 ID:???
91,93どっちもdatetime()→date()だった
>>94
SQL初めて触ったけど純粋に datetime > 'yyyy-MM-DD' の比較が成り立つのが不思議でして


96 :NAME IS NULL:2011/10/17(月) 18:35:17.32 ID:???
unixタイムに変換すればいいじゃない

97 :NAME IS NULL:2011/10/17(月) 20:44:54.63 ID:???
>>95
型毎に演算子をオーバーロードしているようなものです

98 :NAME IS NULL:2011/10/17(月) 23:43:56.84 ID:???
この場合は暗黙の型変換だろ

99 :NAME IS NULL:2011/10/18(火) 15:28:21.23 ID:???
お安い御用です。

100 :NAME IS NULL:2011/10/19(水) 00:03:34.08 ID:???
Androidでアプリを作っています。
データを抽出する条件が分からないので、助けてください。
DBはSQLiteです。

テーブル構成は次の通りです。
id:integer
wdate:text
wtime:text
weight:real
other:integer
memo:text

抽出するときの条件:
日付はグループ化する
グループ化されたデータは、最も遅い時刻であること。

次のようなSQLを書いて見ましたが、上手くいきませんでした。

select * from (
select * from weight_table
where wdate <= julianday(datetime('now', 'localtime')
) order by wdate desc, wtime desc
) result group by result.wdate;

上記SQLだと最も早い時刻でグループ化されてしまいます。
よろしくお願いします。

101 :NAME IS NULL:2011/10/19(水) 02:45:24.52 ID:???
>>100
一般的にサブクエリでorder byは無効だぞ(オフセット操作等除いて)
group by書いて列リストに*も無効だ。SQLiteも嘘SQL通すのか...

最も早い時刻でグループ化するとか意味わからんのだが
データと欲しい結果の例書いてみ

エスパーするなら
select wdate,max(wtime) from weight_table group by wdate
で良いような気がする

102 :NAME IS NULL:2011/10/19(水) 05:10:43.03 ID:???
どう考えても>>4

103 :NAME IS NULL:2011/10/19(水) 05:11:26.40 ID:???
とおもったら日付でグループだった無念

104 :NAME IS NULL:2011/10/19(水) 10:32:30.80 ID:???
Androidでアプリを作ってんのか。すげぇな。

105 :100:2011/10/19(水) 13:32:07.01 ID:???
>>100
先ほど自己解決しました。

106 :NAME IS NULL:2011/10/19(水) 16:11:59.74 ID:???
>>105
解決したなら解決策を示しなよ。
>>101を始め、何人かがあんたのために考えてやったんだからさ。

107 :NAME IS NULL:2011/10/19(水) 16:36:27.46 ID:???
MySQLの質問です
SELECTする際、レコードの状態によって取得するカラムを動的に変えることは可能 でしょうか
例えば id stage stage1_param stage2_param とカ ラムがあって stageの値が1ならstage1_param、2ならstage2_paramの値を取りたい これを1回のクエリで済ます方法があれば知りたいです
一気に全カラム取った方が速ければそれでも良いのですがカラム数が60ぐらいだとどうなんでしょう

108 :NAME IS NULL:2011/10/19(水) 16:57:47.88 ID:???
そのSQLを生成するホスト言語側で場合分けしたらいいんでわ?
しかし、

id   stage   param_value
----------------------------
1    1      15
1    3      8
2    1      32
1    6      1
2    2      2

とかしといた方が、ステージ数がいくつになっても対応できるんじゃないの?

109 :NAME IS NULL:2011/10/19(水) 17:51:17.87 ID:???
>>107
select case stage
when 1 then stage1_param
when 2 then stage2_param

end as stage_param

補足、stageの値によってカラム数を変えるのは無理

110 :NAME IS NULL:2011/10/19(水) 19:33:11.44 ID:???
お安い御用です。

111 :NAME IS NULL:2011/10/22(土) 13:59:45.63 ID:???
>>107に近い質問だと思いますが、
レコードが0件の時に、全部のカラムをnullにしたのをinsertしたいのですが、
どういうinsert文を書けばいいでしょうか?
MySQLとSQLiteで使用可能な文だとありがたいです。

112 :NAME IS NULL:2011/10/22(土) 14:02:02.43 ID:???
when 0 then null

113 :NAME IS NULL:2011/10/22(土) 18:50:32.04 ID:???
助けて下さい頭がパンクしそうです。

CARD
|CARDID|HOWMANYLEVEL|
|   1 |        |
|   2 |        |

CARDLEVEL
|CARDID|LV1|LV2|LV3|LV4|LV5|
|   1 |0 | 0| 23 | 28 | 0| 
|   2 |0 | 0| 0 | 30 | 55|
|   1 |0 | 0| 25 | 29 | 0|

CARDテーブルの HOWMANYLEVELに
CARDLEVELから0以外の個数を入れたいです。
CARDLEVELのCARDIDは複数あります。

114 :NAME IS NULL:2011/10/22(土) 18:55:02.86 ID:???
その例でいうとCARDID 1 のHOWMANYLEVELは 2 なのか 4 なのか

115 :113:2011/10/22(土) 18:57:13.72 ID:???
4です!

116 :NAME IS NULL:2011/10/22(土) 19:00:48.09 ID:???
insert into CARD
select CARDID,
    sum(case when LV1 <> 0 then 1 else 0 end
      + case when LV2 <> 0 then 1 else 0 end
      + case when LV3 <> 0 then 1 else 0 end
      + case when LV4 <> 0 then 1 else 0 end
      + case when LV5 <> 0 then 1 else 0 end)
from  CARDLEVEL
group by CARDID
;

117 :113:2011/10/22(土) 19:06:31.59 ID:???
>>116
ありがとうございます、sum文でも出来るんですね
非常に感謝してます


118 :111:2011/10/23(日) 01:24:51.45 ID:???
どなたか>>111お願いします。

119 :NAME IS NULL:2011/10/23(日) 01:47:39.01 ID:???
お安い御用です。

120 :NAME IS NULL:2011/10/23(日) 16:14:17.70 ID:???
>>118
レコードがあるときどうするのか書いてないけど、共通のロジックにしたいのならアプリでやる。

121 :NAME IS NULL:2011/10/23(日) 16:17:00.47 ID:???
そもそも num > 10 and num < 100.123 という条件だったらの間に何レコードあると教えるのさ

122 :NAME IS NULL:2011/10/23(日) 20:30:42.43 ID:???
>>118
insert into テーブル名 select null,null,... from テーブル名 having count(*)=0

null,...のとこは、テーブルの項目数と同じだけnullな
デフォルト値が指定されてないなら、insertに列1個だけ指定してselectで1個だけnullでも良いけど

123 :111:2011/10/23(日) 20:52:06.62 ID:???
>>120 >>122
レスありがとうございます。
詳細な情報出さないですみませんでした。

テーブルを最初に作ったとき1度だけinsert文をしたいのですが、
(それ以降はupdateはするがinsert、deleteは行わないテーブルです)

create table if not exists t1 ( c1 int, c2 int, c3 int)
insert into t1 (null, null, null)

本来はこれだけでいいのですが、
このSQLをテーブルを作る初回のみに行うわけではなく、
それ以降も行う可能性があるため、
create tableのところは if not existsがあるので影響はないのですが、
insertはこのままだと挿入されてしまうので困っていました。

>>122さんのSQLで早速試してみます。

124 :NAME IS NULL:2011/10/23(日) 21:42:18.16 ID:???
>>122
なにこのトンデモ回答?

>>123
MySQL/SQLite専用ならcreate table if not existsとか
replace文とか使えるけど、汎用を目指すならそんな変な構文は使わず、
アプリ側で条件分岐すべき

125 :NAME IS NULL:2011/10/23(日) 22:00:33.49 ID:???
>>124
どこかどうトンデモ回答なのかkwsk

126 :124:2011/10/23(日) 22:34:45.65 ID:???
>>125
一点目はnullがリテラルとして使えるかという点
二点目はgroup byなしでhavingが使えるかという点

だったが、二点目は俺の誤りだった(gropu byがなくてもhavingは使える)

一点目はちょっと確証がもてないがやはり使えないのが正しそう

127 :122:2011/10/24(月) 00:17:07.35 ID:???
>>126
1点目は、たしかに純粋なSQL規格ではできないと俺も思う
が、これができない実装もみたことない
ほとんどのDBMSでNULLをリテラルとして書けるようになってると思う
(ちなみにSQL Serverで試して動いてるのは確認してる)

そこまで解ってるならトンデモ回答とか言わずにちゃんとそう指摘しろよ

128 :NAME IS NULL:2011/10/24(月) 01:17:47.83 ID:???
NULLがリテラルとして使えない実装だとどうするの?カラム指定をしないってことかな

129 :NAME IS NULL:2011/10/24(月) 03:40:19.16 ID:???
>>128
CASTのソース(NULLをCASTする)や、CASEでのNULLはOKらしいから、それでやるんじゃね

まあ、実際はテーブルには主キーがあるべきで、主キーがあれば、
列リストに主キーだけ指定したinsert文ながせば
主キー以外はデフォルト値入るからそうするべきじゃないかと

130 :NAME IS NULL:2011/10/24(月) 03:45:26.47 ID:???
>>128
念のために言っておくが、insertで指定されなかったカラムに入るのは
あくまでもそのカラムのデフォルト値な

明示的にNULL以外をデフォルト値にしてる場合はその値になるし、
デフォルト値が指定されていない場合は多分NULLがデフォルト値になってると思うが
これが既定の動作かどうかはしらん

131 :NAME IS NULL:2011/10/24(月) 05:47:45.09 ID:???
そういやPostgreSQLのダンプファイルとか見ると\nって書いてるな。

132 :NAME IS NULL:2011/10/25(火) 07:17:45.15 ID:???
お安い御用です。

133 :NAME IS NULL:2011/10/26(水) 01:23:08.63 ID:???
SQLの質問です。

DBMSはOracle11gR2です。

MST_A

ID VALUE
---- -----
1 MA1
2 MA2
3 MA3

MST_B

ID1 ID2 VALUE
---- ---- -----
1 1 MB1
2 2 MB2
3 3 MB3

DAT_A

ID1 ID2 VALUE
---- ---- -----
1 1 DA1
2 DA2
3 4 DA3


SELECT
ma.VALUE,mb.VALUE.da.VALUE
FROM
MST_A ma,MST_B mb,DAT_A da
WHERE da.ID1 = ma.ID
AND ma.ID = mb.ID1
AND da.ID2 = mb.ID2;

のSQL結果に、
DAT_AのID2がnullになっているデータ(VALUE=DA2)
を含めたいのです。

MST_AとMST_Bはデータ件数が非常に多い(1〜2億件)ので、
できればUNIONで複数回読み込むのは避けたいです。

アドバイスよろしくお願いいたします。

134 :NAME IS NULL:2011/10/26(水) 02:32:06.80 ID:???
オラクルならコレでよかったかなぁ。

SELECT
ma.VALUE,mb.VALUE.da.VALUE
FROM
MST_A ma,MST_B mb,DAT_A da
WHERE da.ID1 = ma.ID
AND ma.ID = mb.ID1
AND da.ID2 = mb.ID2(+);

135 :NAME IS NULL:2011/10/26(水) 04:28:43.15 ID:???
DAT_AのID2がnullのとき、mb.VALUEはどうしたいんだ?
(+)でもouter joinでもいいけど、普通にDAT_Aに外部結合するだけでいいとおもうんだが?


136 :NAME IS NULL:2011/10/26(水) 21:31:55.45 ID:???
SQLserverの質問です

以下のようなテーブルがあります
*はユニークキーです。

DATE* ID1* ID2* VALUE
_______________

200103 AAA 111 20
200103 AAA 112 10
200103 AAA 113 55
200103 AAA 121 60
200103 AAA 122 54
200103 AAA 123 44
200103 BBB 111 24
200103 BBB 113 43
200103 BBB 114 11
200103 BBB 121 11



200104 AAA 111 20
200104 AAA 112 10
200104 AAA 114 5
200104 AAA 122 54
200104 AAA 123 4
200104 BBB 111 24
200104 BBB 113 43
200104 BBB 112 21
200104 BBB 121 11
200105 AAA 122 54
200105 BBB 113 43
200105 BBB 112 21
200106 AAA 123 4
200106 BBB 111 24
200106 BBB 112 21

これをDATE=200103とDATE=200104だけとってきて
いかのように外部結合したいのですがどのようにすればよいでしょうか?
FULL JOINを利用したのですがうまくいきません。

ID1 ID2 VALUE_201103 VALUE_201104
_________________________________________
AAA 111 20 20
AAA 112 10 10
AAA 113 55 NULL
AAA 114 NULL 5
AAA 121 60 NULL




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

137 :NAME IS NULL:2011/10/26(水) 21:48:41.42 ID:???
DATE=200103とDATE=200104でそれぞれ抽出、
ID1とID2でfull outer joinすればいい。

138 :NAME IS NULL:2011/10/26(水) 21:55:09.90 ID:???
select case when T1.ID1 is not null then T1.ID1 else T2.ID1 end,
    case when T1.ID2 is not null then T1.ID2 else T2.ID2 end,
    T1.VALUE as VALUE_201103,
    T2.VALUE as VALUE_201104
from  (select ID1,
        ID2,
        VALUE
     from  TableName
     where DATE = 200103
    ) T1
    full outer join
    (select ID1,
        ID2,
        VALUE
     from  TableName
     where DATE = 200104
    ) T2
    on   T1.ID1 = T2.ID1
    and   T1.ID2 = T2.ID2
;

139 :NAME IS NULL:2011/10/27(木) 04:47:47.46 ID:???
SQLiteを使用しています。
DEFAULT値で、現在のレコード数count(*)を指定したいのですが、どう書けばいいでしょうか?

create table t1 (
 id integer primary key autoincrement,
 test integer default select count(*) from t1
)

的なことをしたいです。

140 :NAME IS NULL:2011/10/27(木) 06:12:30.27 ID:???
つ trigger

141 :NAME IS NULL:2011/10/27(木) 06:15:31.69 ID:???
なるほど!
こういうときにtrigger使うんですね。
言葉だけは聞いたことはあったのですが、
難しそうなのでスルーしてました。
調べてみます。どうもありがとうございます。

142 :NAME IS NULL:2011/10/27(木) 19:45:31.79 ID:HJWr1HNd
あるカラムのMAXから+1した値をとりたいのですが
SELECT (SELECT MAX(column) FROM t) + 1
で問題ないでしょうか?

143 :NAME IS NULL:2011/10/27(木) 19:57:17.87 ID:???
SELECT MAX(column) + 1 FROM t
でいいだろ

144 :NAME IS NULL:2011/10/27(木) 19:59:10.53 ID:???
>>143
ありがとう!

145 :NAME IS NULL:2011/10/27(木) 21:53:43.97 ID:???
お安い御用です。

146 :NAME IS NULL:2011/10/27(木) 22:26:46.39 ID:???
そして、ありがとう!

147 :NAME IS NULL:2011/10/28(金) 04:30:32.26 ID:???
特定のidが持つintカラムから最も近いかつ小さい数字を持つidを求めたいのですが、

select id from t1 where int_col < (select int_col from t1 where id=特定のid) order by int_col desc
でできたのですが
もっとよいSQLありませんか?

148 :NAME IS NULL:2011/10/28(金) 20:24:26.88 ID:???
まず日本語でちゃんと説明できるようになってくれ

149 :NAME IS NULL:2011/10/28(金) 21:34:13.14 ID:???
intカラムとidの差の絶対値がもっとも小さいものを取得しないとだめじゃないか?
なので>>147はうまく動かない場合があるのでは。

150 :>>147:2011/10/29(土) 17:55:38.45 ID:dmfGtvmP
簡単にできるよ。主問い合わせでmax(id)とすれば、サブクエリのid未満かつ最も近いidがSELECTできるよ。


151 :NAME IS NULL:2011/10/29(土) 18:16:04.85 ID:???
order by int_col desc だから、max(id)じゃなくて
int_col=max(int_col)な行のidが欲しいんじゃないかと
元のSQLの何が気に食わんかしらんが、目的行だけ欲しいってなら
having使えばいいんじゃね


152 :NAME IS NULL:2011/10/29(土) 18:47:35.28 ID:???
すまん。よくよまずこたえてしまった

153 :NAME IS NULL:2011/10/31(月) 00:13:14.95 ID:???
if select * from t where id=1
then update t set foo=bar where id=1

これをSQLで表現したいのですが可能でしょうか?

154 :NAME IS NULL:2011/10/31(月) 00:46:24.09 ID:???
なにがしたいのか、さっぱりわからん

155 :NAME IS NULL:2011/10/31(月) 01:19:52.99 ID:aQyfoOov
SQL命令で表(TABLE)を作る
1、本(コード・題名・著者名・出版社名・価格・在庫冊数)

2、出納(費用・本のコード・冊数・日付)

3、顧客(顧客コード・氏名・連絡先)

4、予約本(顧客コード・本のコード・予約日付・入荷日付)

このまんまの問題がでたんだけど意味が全く分からない

156 :NAME IS NULL:2011/10/31(月) 02:02:09.11 ID:???
>>153
レコードがあればアップデートってことだと思うんだけど、
それなら
update t set foo=bar where id=1
だけでよくって。

157 :NAME IS NULL:2011/10/31(月) 02:03:02.99 ID:???
>>155
create table を4つ書けってこと。それでもまったくわからないのなら、基礎を勉強してくること。

158 :NAME IS NULL:2011/10/31(月) 04:36:12.47 ID:aQyfoOov
>>157
例えば1の場合だと
CREATE TABLE 商品表
みたいに書けばいいのか?

159 :NAME IS NULL:2011/10/31(月) 04:39:16.08 ID:???
>>158
え?商品表って言葉どっからでてきたん?

160 :NAME IS NULL:2011/10/31(月) 04:46:55.70 ID:aQyfoOov
>>159
カオスになってきたのでヒントか答えくださいまし

161 :153:2011/10/31(月) 05:07:19.45 ID:???
>>156
ありがとうございます。
確かにそれで問題はないのですが、
id=1がなかったらエラーが返ってきて、
それをログに書き込むようにしてるため、
それを無くす前に、update前にid=1があるかを確かめたい感じです。
selectとupdateを分ければ可能ですが、
1度に書くことはできないかな?と思って質問しました。

162 :NAME IS NULL:2011/10/31(月) 05:08:05.53 ID:???
>それを無くす前に
それを無くす為にです。
日本語おかしくてすみません。

163 :NAME IS NULL:2011/10/31(月) 05:45:22.57 ID:???
>>162
問題がないと言いつつエラーが返るという表現はおかしくないのかな
まずそのあやふやなエラーが何なのか聞く方が先だと思う

164 :NAME IS NULL:2011/10/31(月) 05:53:51.35 ID:???
>>160
カオスも何も。
create table 本 〜
日本語が気に入らないなら create table books 〜 とかにすればいい。

>>161
なかった場合は、正常に0件更新されるはずだよ。

165 :NAME IS NULL:2011/10/31(月) 05:55:08.19 ID:???
>>163
動作上は内部でエラーが出ても、
それを出力して動作を停止させるわけではないので問題がないといったのです。
Apacheでfavicon.icoがなかったらエラーログが書きこまれまくりますが、
イメージとしてはあれみたいな感じです。

166 :NAME IS NULL:2011/10/31(月) 05:56:52.78 ID:???
>>165
エラーを貼る。
エラーが実は出力されていなかったら>>155に君が回答してあげると良い。

167 :NAME IS NULL:2011/10/31(月) 11:50:10.66 ID:???
oracle11gのsqlplusで列名のみ表示したいのですがどうすればいいですか?

desc テーブル名だと列名とタイプなどが表示されますが
これを列名のみにしたいです。

いろいろ調べたら
select * from user_tab_columns where table_name = 'テーブル名';
select column_name from user_tab_columns where table_name = 'テーブル名';
select * from all_tab_columns where table_name = 'テーブル名';
select column_name from all_tab_columns where table_name = 'テーブル名';

などでできると書いてましたが結果は
no rows selectedになります。

よろしくお願いします

168 :NAME IS NULL:2011/10/31(月) 13:14:17.19 ID:???
desc テーブル名
じゃだめかな

169 :NAME IS NULL:2011/10/31(月) 16:06:33.76 ID:???
テーブル名を大文字で書いてないとか

170 :NAME IS NULL:2011/11/01(火) 03:53:41.32 ID:???
>>161
普通updateがゼロ件更新してもエラーは返さんと思うが
誰がどんなエラー返してるのか書け

>>167
そういうDBMS固有の問題はそのDBMSのスレで聞け
標準的なSQLにテーブル定義を表示する文はない

171 :NAME IS NULL:2011/11/01(火) 06:07:04.75 ID:???
> 標準的なSQLにテーブル定義を表示する文はない

え?

172 :NAME IS NULL:2011/11/01(火) 06:22:05.53 ID:???
ORACLEが始めたあの高名な問い合わせは今は使えないのかな。
30年近く前はこれだった。

select cname from col where tname='テーブル名';

173 :NAME IS NULL:2011/11/01(火) 06:32:32.54 ID:???
INFORMATION_SCHEMA 使えよ・・・ せっかくANSIにあるんだからさ。

174 :NAME IS NULL:2011/11/01(火) 09:00:04.34 ID:???
>>170
RDBの根本から覆しちゃったよw

175 :NAME IS NULL:2011/11/01(火) 16:22:23.83 ID:???
>>174
えっ

176 :NAME IS NULL:2011/11/01(火) 17:58:07.27 ID:???
>>172
そういう独自実装をまとめるためにsql2003で定義された。
sql標準への準拠なんてまちまちだから、自分が使ってるRDBMSが対応してるかどうか調べてからじゃないと使えないけどな。

>>174
えっ

177 :NAME IS NULL:2011/11/01(火) 21:41:00.09 ID:???
nullじゃないというのはどういう条件を指定すればいいのでしょう?@SQLite

testはnull可能な項目で、

select test from t where test <> null
ではだめでした。

178 :NAME IS NULL:2011/11/01(火) 21:55:01.35 ID:???
is not null

179 :NAME IS NULL:2011/11/04(金) 21:45:03.99 ID:gwC8AWlb
メールリストのメールに任意の個数のタグをつける場合の設計について教えてください。
以下のテーブルBのように、単純なメールIDとタグIDの対応表にすると、テーブルBが膨大な行数になるんですけど、気にしなくてOK?
テーブルA:メールID,SendTo,本文,...
テーブルB:メールID,タグID
テーブルC:タグID,タグ名
アホな質問かもしれませんが、一般的にこうやってるもんですか?

以下のように、タグIDを10個くらい用意しておくのに比べてかなり遅くなりますか?
(10個以下にしろと運用制限したら以下でも十分ではありますが)
テーブルA:メールID,SendTo,本文,タグID1,タグID2,タグID3,...タグID10
テーブルC:タグID,タグ名

180 :NAME IS NULL:2011/11/04(金) 21:55:42.44 ID:???
>>179
十分だといってるそのテーブルレイアウトで、あるタグが指定されているメールを抽出するのはどうするつもり。
DBを信じるんだ。そんで、数十億件とかになるなら考えよっか。

181 :NAME IS NULL:2011/11/04(金) 22:05:04.02 ID:???
>>179
学問上、「正規化」と呼ばれる観点から言えば前者が正しい。

学問上正しい設計が実用に耐えうるかというのはまた別の話。

182 :NAME IS NULL:2011/11/04(金) 22:06:27.62 ID:???
設計スレ行った方がいいな。

DB設計を語るスレ 4
http://hibari.2ch.net/test/read.cgi/db/1309828440/

183 :179:2011/11/04(金) 23:19:30.78 ID:???
>>180-182
ありがとう。
なんか馬鹿な設計をしてるんじゃないかと心配になってた。

184 :NAME IS NULL:2011/11/05(土) 01:47:23.07 ID:???
ついでに質問。>>179 のような例で、
テーブルA:メールID,SendTo,本文,...,タグ名
テーブルB:メールID,タグID,タグ名
テーブルC:タグID,タグ名
上のように(たとえばタグ名で)データベースを重複させるのは御法度?それとも良くある話?
データ密度的に無駄でバグ要因でもあるけど、場合によっては効率は上がりそう。

185 :NAME IS NULL:2011/11/05(土) 02:25:09.03 ID:???
スレ違いだって言ってる相手にお礼をいってる人間のなすこととは思えんな。

186 :NAME IS NULL:2011/11/05(土) 08:29:34.52 ID:???
>>184
御法度。「場合によっては」なんて要件もクエリもろくに決まっていない
時点で無駄に効率云々に気を取られている時点で御法度。
教科書通り正規化しておけばよし。そして大抵はそれが一番無難に速い。

187 :NAME IS NULL:2011/11/05(土) 09:35:41.90 ID:???
必ずしも正規化が良い結果を生むとは言い切れない.
高度に抽象化するとあとで他の人の理解を妨げることもある.
どんくさくてもデータ量が少ないなら視認性の高いほうがいい.

188 :NAME IS NULL:2011/11/05(土) 09:46:54.64 ID:???
スレ違いだっつーの。

189 :NAME IS NULL:2011/11/05(土) 10:04:16.04 ID:???
すまん.

190 :NAME IS NULL:2011/11/07(月) 09:09:27.31 ID:???
Oracle 10g R2を使用しておりまして、以下のようなSQL文を作り、結果をcsvに出力しようと思いました。

[例1]
select テーブル1.名前,テーブル2.解法,テーブル3.手順
from テーブル1 LEFT JOIN テーブル2 ON テーブル1.解法フラグ = テーブル2.解法フラグ LEFT JOIN テーブル3 ON テーブル1.手順フラグ = テーブル3.手順フラグ;
ところが、上記[例1]を使用して出力したところ、「テーブル1が全件出力されていない(気がする)」という旨のことを言われました。
それについて知人に聞いたところ、知人はいつも以下[例2]のような形で出力している、とのことでした。

[例2]
select テーブル1.名前,テーブル2.解法,テーブル3.手順
from テーブル1,テーブル2,テーブル3 where テーブル1.解法フラグ = テーブル2.解法フラグ(+) and テーブル1.手順フラグ = テーブル3.手順フラグ(+);

自分で調べた限り、[例1]と[例2]で得られる結果は同一ではないかと思うのですが違うのでしょうか。

因みに、自分の環境での検証では同じ結果が得られていると思います。

191 :NAME IS NULL:2011/11/07(月) 11:38:41.42 ID:???
select テーブル1.名前
from テーブル1 LEFT JOIN テーブル2 ON テーブル1.解法フラグ = テーブル2.解法フラグ LEFT JOIN テーブル3 ON テーブル1.手順フラグ = テーブル3.手順フラグ;

select テーブル1.名前
from テーブル1;

この結果を比較して、全件出ていない気がする人に見せる

192 :NAME IS NULL:2011/11/07(月) 11:39:46.73 ID:???
今後、全件でてない気がするといわれるたびに同じことを繰り返し、
めんどくさくなったらSQLの勉強してくださいという。

193 :NAME IS NULL:2011/11/07(月) 14:01:29.29 ID:???
知人の例にある(+)はOracle方言の外部結合演算子。
例1の場合テーブル1にはあっても解法テーブルや手順テーブルに対応する行が
無い場合は出力されない。

例2の場合はテーブル1は常に全件出力される。解法テーブルや手順テーブルに
対応する行が無い場合はそこにNULLがセットされる。

後者の様な動作が必要なのであれば例1のLEFT JOINを全てLEFT OUTER JOINに
書き換えれば同じ動作をする。

あといつも外部結合を使う様な知人の言うこともイマイチ信用できないので要注意。

194 :NAME IS NULL:2011/11/07(月) 15:22:10.46 ID:???
left join と left outer join が等価でないソース希望

195 :NAME IS NULL:2011/11/07(月) 17:41:20.61 ID:???
例1でテーブル1が全件出力されていないなら、ORACLEにバグがあるとしか思えん
ORACLEってouter join周りはバグが多いと聞いたことがあるぞ
その知人はそれ嫌って(+)で外部結合してるのかもしれん(昔の人でそれしか知らんのかもしれんが)
とりあえずテーブル1の件数と出力件数比べてみればすぐわかるだろ

あと外部結合使う人は信用できないって人もイマイチ信用できないので要注意

196 :NAME IS NULL:2011/11/07(月) 18:05:09.78 ID:zwU0XuxP
PHPでMySQLかsqlite3を使おうと思っています。
表の先頭に新しい行を追加して、行の総数が指定した数(たとえば10)よりも多くなった場合は
多くなった分を表の末尾から削除して行数を一定以上に増やさないようにしたいのですがどうすればいいですか?
ロケット鉛筆みたいに最大数が決まっていてはみ出たら押し出すみたいなことをしたいです。
表の先頭に追加して上限を超えたら最後尾から削除するんじゃなくて
表の最後尾に追加して上限を超えたら先頭から削除するのでもいいです。
どちらのほうが簡単かどうかもわかっていませんがよろしくお願いします。

197 :NAME IS NULL:2011/11/07(月) 18:26:22.91 ID:???
>>196
まずRDBの表に先頭とか最後尾とかいう概念はないと理解してくれ

たとえば挿入日時とか、連番カウントアップの項目を作って
挿入日時や連番みて行を削除するのは可能

MySQLかsqlite3ってトリガ使えたっけ?

198 :196:2011/11/07(月) 18:54:58.85 ID:???
レスどうもありがとうございます。
順番とかないんですね・・・あまりに無知すぎて恥ずかしい。
ということは行の追加は普通に挿入すればいいんですよね。
で古い新しいの目印は、連番数字だとどんどん大きくなりすぎるから行を削除するたびにすべての行の連番数字をインクリメントしないといけないっぽいから
ミリ秒かマイクロ秒の時間にして、
行数の取得は
SELECT COUNT(*) FROM table
で、最大数よりもはみ出ているかどうかはPHP側でチェックして、
はみ出ていたら時間がもっとも小さいものを削除してまた行数を取得して最大数よりも大きいかチェックして・・・の繰り返しですか?
最小の行の削除は
DELETE MIN(time) FROM table
でいいですか?

199 :NAME IS NULL:2011/11/07(月) 20:10:55.40 ID:???
RDBMSによっては、循環型の連番を作ることができる。
けれど、数字が大きくなりすぎたからといって何の問題もないので連番でいいよ。
もし最大値まで使い切るような快挙を成し遂げた場合には、ここで報告してくれるとうれしい。

200 :196:2011/11/07(月) 20:43:44.60 ID:???
よくよく考えればミリ秒やマイクロ秒も数字がどんどん大きくなっていきますね・・・桁数に気をとられていました

行の総数が指定した数よりも大きいかとかの比較もSQLだけでできますか?
行数を取得(SQL)→指定した数と比較(PHP)→行数のほうが大きければ連番フィールドが最小の数字の行を削除(SQL)→
行数を取得(SQL)→指定した数と比較(PHP)→・・・の流れは無駄ですよね
今のところ行の追加は一行ずつなのでこの流れも一周だけで済みますが
それでもすべてまとめてSQLでできるならSQL→PHP→SQLとするよりもいいですよね

201 :NAME IS NULL:2011/11/07(月) 22:46:30.23 ID:HMXQlM9n
こんなsqlをmysqlで書いたんだけど、sql文が正しくないって出てくる
何が間違ってるのか教えてください
SELECT * FROM mycloud WHERE F_NAME = test.txt

202 :NAME IS NULL:2011/11/07(月) 22:49:03.10 ID:???
スレ立てるまでもない質問はここで 114匹目
http://hibari.2ch.net/test/read.cgi/tech/1318162690/453

203 :NAME IS NULL:2011/11/07(月) 22:53:19.02 ID:???
SELECT * FROM mycloud WHERE F_NAME = 'test.txt'

204 :NAME IS NULL:2011/11/07(月) 22:53:43.81 ID:???
>>200
どうしてもDB側でやりたければトリガーを使うしかない
アプリでやるのとそう変わらん

>>201
エスパーするとtest.txtが識別子じゃないんだろう
文字列リテラルならシングルクォートで括る

205 :NAME IS NULL:2011/11/07(月) 23:05:10.72 ID:HMXQlM9n
>>203,>>204
おお!とおりました!!ありがとうございます。
ここで聞いていいのか分からないのですが、
さっきの 'test.txt' をphpで変数に置き換えて↓のようなsql文を通したいのですが、
この場合どうすればいいのでしょう?

SELECT * FROM mycloud WHERE F_NAME = ".basename($_FILES['userfile']['name'])
basename($_FILES['userfile']['name'])をシングルコーテーションでくくるとエラーになってしまいます・・・

206 :NAME IS NULL:2011/11/07(月) 23:05:52.22 ID:???
スレ違いだよハゲ

207 :NAME IS NULL:2011/11/07(月) 23:13:16.00 ID:???
>>206
すいませんでした・・・
そして自己解決できました、お騒がせして申し訳なかったです

208 :NAME IS NULL:2011/11/07(月) 23:49:00.07 ID:???
>>200
連番 サイクル 列1 列2 として

insert or update t1
連番 = select max(連番) + 1 from t1,
サイクル = (select max(連番) + 1 from t1) % 最大行数,
列1 = …
where
サイクル = (select max(連番) + 1 from t1) % 最大行数

的なアプローチがあるかもしれない。
サイクルってのは、存在する行の中で、
サイクリックに使われる連番で、最大10行としたら、0から9が使われて、それは連番を10で割ったあまり。

209 :NAME IS NULL:2011/11/08(火) 00:23:58.10 ID:???
行数が決まってるなら、更新日時♪が最小の行をupdateすればよくね?

アプリ起動(orインストール)時にダミーデータいれとく必要あるけど


210 :NAME IS NULL:2011/11/08(火) 00:25:05.86 ID:???
なんだこの音符は

211 :NAME IS NULL:2011/11/08(火) 02:23:18.00 ID:???
select * from test order by hoge desc
ってのは構文としてよくないんですか?
where 1とかちゃんといれたほうがいいんでしょうか?

212 :NAME IS NULL:2011/11/08(火) 02:31:00.68 ID:???
Where は別にいらん
むしろ*がだめ

213 :NAME IS NULL:2011/11/08(火) 03:20:00.93 ID:???
>>212
ありがとう
*使わないように気をつけます

214 :NAME IS NULL:2011/11/08(火) 04:09:50.87 ID:???
>>200
ためしてないけど、たとえばIDの順で10行のこすなら
delete from table t where
(select count(*) from table where id<=t.id) > 10
とかで行けるはず
これをトリガで仕込めばまあ自動的に10行に保たれるかな

>>211
構文としては問題ない。不要なwhere条件書く必要はないし、*がダメってこともない
ただ、実際にアプリ作る時に、不必要な列までselectするのは無駄が多いから
なるべく*使うなっていう考え方はある

215 :NAME IS NULL:2011/11/08(火) 05:08:25.95 ID:???
count(*)っていけないのかなとふとおもった
count(id)とかしてる例題あんまみないよね

216 :NAME IS NULL:2011/11/08(火) 05:20:49.04 ID:???
count(id)よりcount(1)よりcount(*)がいい

217 :NAME IS NULL:2011/11/08(火) 05:54:13.60 ID:???
>>215
count(id)とcount(*)では意味が違う

続きはwebで

218 :NAME IS NULL:2011/11/08(火) 06:06:10.43 ID:???
結果は同じでしょう

219 :196:2011/11/08(火) 20:06:55.87 ID:???
>>204,208-214
レスどうもありがとうございます
調べたり試したりしてみます

220 :NAME IS NULL:2011/11/08(火) 20:26:04.30 ID:???
>>217 
なぜ引っ張る?つか続きも何も本文もwebだぞ、ここw
>>218
項目の数を数えるのと行の数を数えるという意味的な違いはさておくとしても
idがnot nullなら同じ数字になるが、必ずしも同じになる保証はないのだよ

昔はcount(*)よりcount(1)ってした方が早い処理系が存在したらしいが
今ではおそらくバッドノウハウだと思われ

221 :NAME IS NULL:2011/11/09(水) 00:03:42.26 ID:???
DBMSはMysqlの5.0.87です。

+------+------------+---------+----------+
| id   | product_id | assy_id | parts_id |
+------+------------+---------+----------+
|    1 |          1 |      12 |        1 |
|    2 |          1 |      12 |        2 |
|    3 |          1 |      12 |        3 |
|    4 |          1 |      12 |        3 |
|    5 |          1 |      12 |        5 |
+------+------------+---------+----------+

上記のテーブルで、product_id、assy_id、parts_idが同じレコードが2行以上有るものを抽出したいのです。
上記の例だとidが3と4のレコードになります。


222 :NAME IS NULL:2011/11/09(水) 00:57:48.80 ID:???
>>221
ためしてないけど

select id from テーブル t where
(select count(*) from テーブル product_id=t.product_id and assy_id=t.assy_id and parts_id=t.parts_id ) >=2

とか

select id from テーブル t1 join
(select product_id,assy_id,parts_id from テーブル group by product_id,assy_id,parts_id having count(*)>=2) t2
on t1.product_id=t2.product_id and t1.assy_id=t2.assy_id and t1.parts_id=t2.parts_id

とかでいけるんじゃね


223 :NAME IS NULL:2011/11/09(水) 03:04:54.28 ID:???
select * from t1 where exists(select * from t2 where t1.id <> t2.id and t1.product_id = t2.product_id and t1.assy_id = t2.assy_id and t1.parts_id = t2.parts_id);

224 :NAME IS NULL:2011/11/09(水) 20:51:56.87 ID:ViYEpCpP
行数の増減はほとんどなくても(たとえば1000行前後で推移してても)INSERTとDELETEを繰り返していると
断片化か何かで処理速度が落ちてきますか?
あとこういう行数はほぼ一定だけど行の挿入削除が激しい場合はindexはあまり意味ないですか?
いずれもデータベースによりますか?

225 :NAME IS NULL:2011/11/09(水) 21:22:11.72 ID:???
RDBMSによるんだけど、大抵それに対する解決方法がある
インデックスはそれが有効かどうかは行数に依存しない

226 :NAME IS NULL:2011/11/09(水) 21:33:59.91 ID:ViYEpCpP
レスありがとうございます
解決策というのはVACUUMやOPTIMIZEをしろということですか?それとも
断片化しにくいorしても速度が落ちにくい方法があるってことですか?

227 :NAME IS NULL:2011/11/09(水) 21:39:05.03 ID:???
スレ違いだからさっさとひっこめ
RDBMSによるっていってんのにRDBMSも指定しないとか脳みそ足りてんのか

228 :NAME IS NULL:2011/11/09(水) 21:40:53.45 ID:???
行の入れ替わりが激しい場合はどうなのかわからないけど
行数が少ないとインデックスの有効性はあまりなくない?

229 :NAME IS NULL:2011/11/09(水) 21:41:18.49 ID:???
スレ違い。

230 :NAME IS NULL:2011/11/11(金) 00:25:24.76 ID:???
・DBMS名とバージョン
oracle11g

・テーブルデータ
userテーブル

id int
name varchar

・欲しい結果&説明
idを外からバインド変数で渡し、
IDが一致するレコードと、
その一致したレコードとnameが一致するレコードの2レコードを取得したいです。

例)
バインド変数:1
id  name
1   aaa
2   bbb
3  aaa
idが1と3のレコードを抽出したいです。

自己結合して1レコードとして取得することはできるのですが2レコード取得する方法が思いつきません。
宜しくお願いします。


231 :NAME IS NULL:2011/11/11(金) 00:45:22.35 ID:???
select * from user
where name in (select name from user where id = @id)

232 :230:2011/11/12(土) 09:36:24.85 ID:???
>>231
行けましたありがとうございます!

233 :NAME IS NULL:2011/11/12(土) 13:42:29.85 ID:???
http://www.geocities.jp/mickindex/database/db_optimize.html

orはINに置きかえろとあるのですが、
key1 = 1 or key1 = 2 なら key1 IN (1,2)と書けるのはわかるのですが、このサイトでは
異なるkeyをorしているsqlに対してinが書けるかのような記述になっています。

どうにかして書ける方法があるのでしょうかl

234 :NAME IS NULL:2011/11/12(土) 14:01:37.48 ID:???
動的SQLでセレクトした結果をカーソルに入れて返したいんですが、可能でしょうか?

235 :NAME IS NULL:2011/11/12(土) 16:22:24.54 ID:???
>>233
無理だな
どうしても書き換えるならUNIONだろうが、そっちのほうが速いとは限らない

>>234
普通はできるがプロシージャはDBMSによって全然違うので断言できない

236 :NAME IS NULL:2011/11/12(土) 16:26:31.59 ID:???
>>233
そのサイトもそろそろ時代遅れになってるな

237 :NAME IS NULL:2011/11/13(日) 01:02:02.53 ID:???
>>233
どうしてもORを使いたい場合ってのは、どうしてもORを使わざるを得ない場合を指してるんだよ。

>>236
たしかにね。すこし残念な気持ちに

238 :NAME IS NULL:2011/11/13(日) 14:57:33.43 ID:???
>>235
oracle11gです

239 :NAME IS NULL:2011/11/13(日) 14:59:10.20 ID:???
Oracleスレ行け。

240 :NAME IS NULL:2011/11/13(日) 18:56:02.92 ID:BfOCLmZi
・DBMS名とバージョン
SQLite3

・説明
SQLiteは、データベースを開くとき、指定したファイルがあればそれを開いて、
指定したファイルがなければそのファイル名のデータベースを作成してから開きますが、
そんな感じで、指定したテーブルがあればそのテーブルに対してinsert等の操作をして、
指定したテーブルがなければテーブルを作成してから操作をする、
みたいなことをしたいのですがどう書けばいいですか?

テーブルの有無は、検索したら
(SELECT count(*) FROM sqlite_master WHERE type='table' AND name='テーブル名') = 0
で判断できるとありましたが、
sqlite_masterテーブルはSQLite独自らしいので、一般的なテーブルの有無の確認方法があれば
教えてください。

テーブルが無いかもしれないのは、テーブルを削除しない限り初回の一回だけなのに、
毎回テーブルの有無を確認するのは変な気もするので、もし
やりたいことを実現できる別のアプローチがあればその書き方を教えてください。
データベース自体をあらかじめ作っておくことは出来ません。

241 :NAME IS NULL:2011/11/13(日) 19:20:38.47 ID:???
常にCreateを投げてエラーを無視すればいい。

242 :NAME IS NULL:2011/11/13(日) 19:22:58.68 ID:???
>>241
レスどうもありがとうございます
エラーが出ないようにしないといけないものだと思っていましたが
そういうやりかたでいいんですね

243 :NAME IS NULL:2011/11/14(月) 06:21:49.08 ID:???
SQLiteならcreate table if not existsなんていう構文もあるが

244 :NAME IS NULL:2011/11/14(月) 12:12:37.77 ID:+RxR3+y0
MySQL5です。

shop
id name
1 Aカンパニー
2 Bカンパニー
3 Cカンパニー

area
1 北海道
2 青森
3 岩手
4 秋田

shop_area
shop_id area_id
1 1
1 2
1 3
2 2
2 4
3 2
3 3

青森と岩手、両方に支店のある会社を抽出したいです。
shop_id name
1 Aカンパニー
3 Cカンパニー

「青森、岩手のどちらかに店舗のある」という条件でしたら
SELECT shop.id AS shop_id, shop.name FROM shop_area INNER JOIN shop ON shop_area.shop_id = shop.id WHERE shop_area.area_id IN (2, 3) ORDER BY shop.id
というので出来たのですが、「両方にある」という条件になったら書き方がわかりません。

よろしくお願いします。

245 :NAME IS NULL:2011/11/14(月) 13:58:55.11 ID:???
>>244

>>6 じゃなかろか。

246 :244:2011/11/14(月) 16:21:41.99 ID:+RxR3+y0
>>245
その1でできそうです。
ありがとうございます。


247 :240:2011/11/14(月) 18:49:33.36 ID:???
>>243
どうもありがとうございます
その方法でやってみます

248 :233:2011/11/14(月) 21:58:39.21 ID:???
ありがとうございました。

249 :NAME IS NULL:2011/11/15(火) 02:39:47.73 ID:nW9WdTUJ
・MySQL5です
・テーブルデータ
 ID|名前|データ
 01|鈴木|0001
 02|佐藤|0002
 01|鈴木|0003
・欲しい結果
 ID|名前|*|DATA1|DATA2
 01|鈴木|2|0001 |0003
 02|佐藤|1|0002 |

・説明:group by と count(*) を使うと↓のように、グループ化され消えてしまう列の値を(この場合`0003`の部分)、↑みたく、行に書出す方法はありますか?
 ID|名前|*|データ
 01|鈴木|2|0001
 02|佐藤|1|0002

・補足:IDは1~1400、count数は1~97、DATAは1~4000位あります。

250 :NAME IS NULL:2011/11/15(火) 03:32:37.58 ID:???
方言での実装になるのでMySQLスレにいくといいかも

251 :NAME IS NULL:2011/11/15(火) 03:41:30.27 ID:???
GROUP_CONCATで1列にしてしまうとか簡単だぞ

252 :NAME IS NULL:2011/11/15(火) 19:54:33.52 ID:???
カウント数が97とか、データが4000とか、97列とか4000列とかのデータが欲しいってか?
要件と設計みなおした方がいいんじゃねえか

253 :NAME IS NULL:2011/11/15(火) 20:19:56.54 ID:???
まず>>7

254 :249:2011/11/15(火) 23:53:31.31 ID:???
ありがとうございました。諦めます。

255 :249:2011/11/16(水) 00:00:59.45 ID:???
あ、>>251 さんの group_concat でイケそうです。
重ねて、ありがとうございました。

256 :249:2011/11/16(水) 00:16:50.67 ID:???
group_concat で欲しい結果を得る事ができました。(>>249の件 終了)

皆さん、本当にありがとうございました。諦めずに続けていきます。

257 :NAME IS NULL:2011/11/18(金) 11:37:31.67 ID:???
初心者です。よろしくお願いします。
使用DBはMS-ACCESSですが専用スレがないのでここで質問してみます。

犬の誕生日が記録してあるデータが入ったテーブルがあります。
兄弟犬を抽出したいという要望です。

兄弟の定義は「母が同一かつ同時に出産した個体(同胎)」だとします。
母親は各データが持っていますが、同時出産でも誕生日が日付をまたぐことがあります。
2日にまたがる難産の場合もあると思われます。
ただし、出産は数ヶ月に一度です。

このような事象をグループ化して抽出するうまい方法はありますでしょうか?
よろしくお願いいたします。

258 :NAME IS NULL:2011/11/18(金) 11:46:13.96 ID:???
申し訳ありません。
自己解決しました。
とりあえずターゲットの犬がいてその犬の兄弟だけ抽出ということだそうなので
ターゲットの犬の誕生日前後数日で検索すればよいことになりました。

259 :NAME IS NULL:2011/11/26(土) 20:49:22.26 ID:???
【質問テンプレ】
・DBMS名とバージョン:MySQL server 5.0
・テーブルデータ
unigram(elem1 text, probability double); (レコード数:500万件)
bigram(elem1 text, elem2 text, probability double); (レコード数:1億件)
trigram(elem1 text, elem3 text, probability double); (レコード数:4億件)
・欲しい結果
入力された文字列の組み合わせを1〜3のngramから検索し、その出現数を返す
・説明
例えば、A-B-C-D-Eという組み合わせがあったら
unigramから[A][B][C][D][E]、5つの出現件数を
bigramから[A-B][B-C][C-D][D-E]、4つの出現件数を
trigramから[A-B-C][B-C-D][C-D-E]、3つの出現件数を
それぞれ参照し、シェルに返します。

現状では、SQL文をループで回していて、
unigramでは5回、bigramでは4回、trigramでは3回、レコードを全件探索しています。
実行結果には満足しているのですが、探索件数が膨大であるため、A〜Eという簡単な組み合わせでも、
平均で40〜50分程度かかっています。

これを高速化(可能ならば10分以内に探索を終了させたい)させるとしたら、どのような方法が考えられますでしょうか?
文字列を全て一度に送って、全件探索を一度で済ませるようなことは出来るのでしょうか?
ご教示願います。

260 :NAME IS NULL:2011/11/26(土) 20:53:54.39 ID:???
trigramのテーブルが間違っていました。
trigram(elem1 text, elem3 text, probability double);
となっていましたが、

正しくは
trigram(elem1 text, elem2 text, elem3 text, probability double);
:-elem2 text, を追加
です。宜しくお願いします。


261 :NAME IS NULL:2011/11/26(土) 21:04:33.72 ID:???
orとunionで結べば1文にはなると思うけど

262 :NAME IS NULL:2011/11/26(土) 21:23:11.04 ID:???
とりあえず、index使って全件検索しないようにしてみたら?

263 :NAME IS NULL:2011/11/27(日) 17:43:51.99 ID:???
elem1にA-BとかA-B-Cとかいう文字列が格納されてるのか?
とりあえずループまわしてるSQL書いてみ


264 :NAME IS NULL:2011/11/27(日) 21:21:45.46 ID:???
>>259

>>261>>262
が正解を出してるぞ。

フルスキャンの原因はどうせ左辺の列を合体させてるとかいうオチだろ…
elem1 || elem2 || elem3 = 'ABC'  みたいな…知らんけど…
こういう場合は左辺はいじらずに右辺を工夫して索引検索させる。PGで条件となるWHERE句を可変にするとかして。
あとSQL発行は1回でもテーブルが3つあるから内部的には3回走るんでSQL3回発行とそんなに差は出ないかもしれない。
ただのカンだけどね…。



265 :NAME IS NULL:2011/11/28(月) 01:34:43.46 ID:???
Aが出現しなければA-Bも出現しないので、そういうところで減らせたりしないのだろうか

266 :NAME IS NULL:2011/11/28(月) 02:03:37.30 ID:???
今のSQLも実行計画もださないで今より早くって言われてもな
>SQL文をループで回していて、unigramでは5回
まさかとおもうが、elem1='A'を検索するSQLを発行して、elem1='B'を検索するSQLを発行して...じゃないだろうな


267 :NAME IS NULL:2011/11/28(月) 02:34:26.35 ID:???
関数つきのインデックス(だったかな?)、 なんて言ったかなあ、あらかじめ関数の結果をインデックス化しておくやつ
それやっとけば速くなるかもね。

268 :NAME IS NULL:2011/11/28(月) 22:22:37.66 ID:???
それって結局関数の結果をDBに収めてるのと同じだろ
関数の意味ねぇな

269 :NAME IS NULL:2011/11/28(月) 23:00:49.79 ID:???
>>267
まんま、ファンクションインデックス

>>268
インデックスだからデータが更新されれば当然インデックスも更新されるわけで
マテリアライズドビューみたいな原則非同期更新のものとは違うという意味はあると思うけど

270 :NAME IS NULL:2011/11/28(月) 23:13:49.78 ID:???
使ったことないけど気にはなっていたマテリアライズドビューが非同期ということに驚いた
ありがとう

271 :NAME IS NULL:2011/11/29(火) 00:59:00.02 ID:???
マテリアライズドビューが原則非同期ってのが気になって調べてみたら
これって昔はレプリケーション用のスナップショットと呼ばれてた、らしい
なるほど
インデックス付きのビューとは用途が違ってるわけか

272 :NAME IS NULL:2011/12/03(土) 00:08:31.30 ID:IuWrM6xt
【質問テンプレ】
・DBMS名とバージョン
SQLite3

テーブル作成時についての質問です。
複合NOT NULL制約みたいのはありますか?
例えば、

CREATE TABLE t (
a INTEGER NOT NULL PRIMARY KEY,
b TEXT,
c TEXT
)

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

bとcはNULLでもよいのですが、
例えばbかcの片方がNOT NULLだった場合、
もう片方もNOT NULLでなくてはならないというような制約をつけたいです。
言い換えれば、両方NULLか両方NOT NULLかでないとだめということです。

そういうことはできますでしょうか?

273 :NAME IS NULL:2011/12/03(土) 07:20:50.05 ID:???
CREATE TABLE t (
    a INTEGER NOT NULL PRIMARY KEY,
    b TEXT,
    c TEXT,
    CONSTRAINT null_check CHECK (
        (b IS NULL AND c IS NULL)
        OR
        (b IS NOT NULL AND c IS NOT NULL)
    )
)

274 :272:2011/12/03(土) 20:35:39.61 ID:???
>>273
ありがとうございます。

アプリケーション側ではできるのですが、DB側でも二重にしたかったので助かりました。

275 :NAME IS NULL:2011/12/03(土) 21:00:45.04 ID:???
データバインディングされる値によっては、自己結合になるリレーションをする為に、
普通の結合の時も自己結合の式をかけてデータを取りだそうと思っているのですが、
やはりかなり処理が重くなるでしょうか?

普通
select * from tbl1 inner join tbl2 on tbl1.tbl2id = tbl2.id;

今回
select * from tbl1 a inner join tbl2 b on a.tbl2id = b.id;

276 :NAME IS NULL:2011/12/03(土) 21:11:03.67 ID:???
>>275
ちょっとその日本語が何言ってるのかよくわからんが
その普通と今回とで実行計画とってみれば?
同じ実行計画なら同じ重さ

つかその二つで違う実行計画出すDBMSあったらびっくりだが

277 :NAME IS NULL:2011/12/03(土) 22:34:05.26 ID:???
>>276
サイキック回答ありがとうございます。
「実行計画」と言うのが初耳でした調べて見ます。

278 :NAME IS NULL:2011/12/04(日) 03:01:37.13 ID:???
>>275
その二つは別名の有無の差しかないけれど、上の日本語の内容を見ると、実際は実行計画の異なるクエリになるはずだな。

279 :NAME IS NULL:2011/12/04(日) 21:23:27.65 ID:mtTsMo28
MySQL5.2、ストレージエンジンInnoDB、トランザクション分離レベルREPEATABLE READの場合の話ですが、

例えば先行トランザクションとして
set autocommit = 0;
update t set c2 = 'b' where c1 = 30

後発のトランザクションとして
set autocommit = 0;
select * from t where c1 = 30

このようなトランザクションを考えますと後発のトランザクションは待たされることなく処理されるのですが、
MySQLのドキュメントには「UPDATE ... WHERE ... は、検索が直面するすべてのレコード上に排他ネクストキーロックを設定します。」
と書かれています。
先行のトランザクションでは行に排他的ロックがかかってるはずですが、何故後発のトランザクションが読み取りに成功しているのでしょうか

280 :NAME IS NULL:2011/12/04(日) 22:11:51.12 ID:???
InnoDBってバージョニングでしょ?
更新前のデータを読むんだろ

281 :NAME IS NULL:2011/12/04(日) 22:39:54.81 ID:???
>>279
技術的興味で質問しているんだとしたら残念ながら回答にはならないけど、
もしこのことで何か困っているんだとすれば、ロックされるかされないかに
依存するようなプログラミングはしないこと。
頼っていいのはトランザクション分離レベルだけ。

282 :NAME IS NULL:2011/12/04(日) 22:40:06.74 ID:???
>>280
ありがとうございます

283 :NAME IS NULL:2011/12/04(日) 22:56:42.67 ID:???
>>281
更新の激しいテーブルをFOR UPDATEで確実に処理したいと思い、詳しく調べてみたら先述のような疑問が浮かんだという感じです

284 :NAME IS NULL:2011/12/04(日) 23:52:59.23 ID:???
つか特定のDBMSの実装の問題はそのDBMSのスレで聞け

285 :NAME IS NULL:2011/12/06(火) 15:28:00.30 ID:???
MySQL5.1を使っていて、パーティショニングについて疑問があるので質問させてください。
10億レコードのデータをパーティショニングしたテーブルを作成したいと思い、下記のSQL文を実行しました。

create table tbl1(
shopname varchar(255) not null,
itemname varchar(255) not null,
id int,
primary key(shopname, id)
)
ENGINE=InnoDB
partition by hash (id)
partitions 100;

これを実行したところ、特にこれといったエラーもなく作成されました。
現在はこのテーブルにload data local infileを用いてデータの書き込みを行っています。

実際にテーブルを利用する際は
select id from tbl1 where shopname='...';
といった具合に、shopnameからidを検索する形になります。

パーティショニングのメリットは一定の式に基づいて分類保存することで、大規模なデータでも高速で参照できることだと伺いました。
確かに、パーティショニングを行った際に与えた数値を使うことが出来た場合には、そのように出来るかもしれませんが、
上記select文の様に、パーティショニングに使ったユニークIDを利用できない場合、どのパーティションにレコードが作成されているか分からない為、
パーティショニングを使わずに一つのテーブルで作成した場合とselect文実行にかかるコストは
変わらないのではないかと疑問に感じたのですが、やはりそうなるのでしょうか?

まだデータの取り込みが終わっていないので実行していませんが、
各パーティションはshopnameで別途インデックス付けする予定です。

よろしくおねがいします。

286 :NAME IS NULL:2011/12/06(火) 18:32:42.13 ID:???
selectの速度には影響がないかもしれない。
けど、インデックスの更新速度が速くなるのはメリットだと思うよ。
詳しくはMySQLスレで聞くといいかも

287 :NAME IS NULL:2011/12/07(水) 07:57:23.93 ID:???
not nullなカラムに空文字が入って欲しくないんですけど
これはcheckでやるしかないですか?

288 :NAME IS NULL:2011/12/07(水) 12:12:02.44 ID:???
>>287
ほとんどのDBMSではちゃんとNULLと空文字列を区別するからそう
ただ一部区別できないDBMSがある。メジャーなやつだがな

289 :NAME IS NULL:2011/12/07(水) 15:31:00.10 ID:???
MS?

290 :NAME IS NULL:2011/12/07(水) 15:35:47.56 ID:???
SQLite?

291 :NAME IS NULL:2011/12/07(水) 15:37:26.48 ID:???
オラクルさんじゃね

292 :NAME IS NULL:2011/12/07(水) 19:59:34.90 ID:???
>>286
ありがとうございます。

293 :NAME IS NULL:2011/12/07(水) 20:49:49.31 ID:???
oracleです。

・テーブルデータ
テーブルA
 ID |状態
 100|○
 100|○
 101|○
 102|○
 104|○
 105|×
テーブルB
 ID |状態
 100|○
 100|○
 100|○
 103|○
 105|○
 106|×

・欲しい結果

 ID |AのCOUNT(ID)|BのCOUNT(ID)
 100|2 |3
 101|1 |null
 102|1 |null
 104|1 |null
 105|null |1

・説明:
A,B各テーブルの状態が○であるものをID単位でカウントし、
 AとBのテーブルを結合したいのですが、SQL1本で可能でしょうか?
 結合する際、どちらかのテーブルのカウントが1以上であれば出力したいです。

294 :NAME IS NULL:2011/12/07(水) 20:54:49.47 ID:???
Aがある場合とない場合に場合分けして union all で繋げ

295 :NAME IS NULL:2011/12/07(水) 20:57:22.30 ID:???
select coalesce(A.ID, B.ID), A.cnt, B.cnt from
(( select ID, count(ID) cnt from テーブルA where 状態 = '○' ) A
full outer join
( select ID, count(ID) cnt from テーブルB where 状態 = '○' ) B)

とか?

296 :NAME IS NULL:2011/12/07(水) 20:58:00.64 ID:???
on A.ID = B.ID がぬけてた

297 :NAME IS NULL:2011/12/07(水) 21:02:23.07 ID:???
AとBからIDを抜いてUNION、それにAとBを外部結合とか

298 :NAME IS NULL:2011/12/07(水) 22:51:17.55 ID:???
>>294
>>295
>>297

ありがとうございます。
今確認する環境がないので、
明日試してみます。


299 :NAME IS NULL:2011/12/08(木) 07:07:10.07 ID:???
NULLな項目でUNIQUEを指定すると、NULLがかぶってるときも登録できなくなりますが、
NULLはかぶってもよくて、NULLでないときはUNIQUEである必要があるというのは、
どんな感じに書けばいいでしょうか?

300 :NAME IS NULL:2011/12/08(木) 08:11:06.11 ID:???
>>299
>NULLな項目でUNIQUEを指定すると、NULLがかぶってるときも登録できなくなりますが、

できるやつと出来ないやつがあるよ。

>NULLはかぶってもよくて、NULLでないときはUNIQUEである必要がある

だから最も簡単には、DBを「nullは皆ユニーク」と扱うやつに変えてしまう、かな。

301 :NAME IS NULL:2011/12/08(木) 14:33:06.00 ID:Q8sIgK2f
MySQLで質問させてください。
ある条件で絞ったレコードを日付でソートして
最新のn件以降を削除したい場合はどのようなSQLを書くのが良いでしょうか?


302 :NAME IS NULL:2011/12/08(木) 15:10:27.49 ID:???
DELETE FROM table
WHERE プライマリキー NOT IN (
 SELECT プライマリキー
 FROM table
 WHERE ある条件
 ORDER BY 日付 DESC
 LIMIT n
 )

なんてのが出来るかどうかは、試してないから知らない。


303 :NAME IS NULL:2011/12/08(木) 15:28:44.91 ID:???
ある条件に当てはまらないものまで消えてしまわないか?

304 :301:2011/12/08(木) 15:57:18.19 ID:Q8sIgK2f
>>302,303

なるほど。
not in使えばよかったんですね。
limitでn件目以降全てというのが見当たらなかったので困ってました。
ある条件をdelete分のwhereに追加して試してみたいと思います。
ご回答ありがとうございます。


305 :NAME IS NULL:2011/12/08(木) 18:31:39.98 ID:???
MySQL5です。

programテーブル
`program_id`,`program_name`

titleテーブル
`program_id`,`title_id`,`title`

dataテーブル
`program_id`,`title_id`,`data_id`,`open_flag`

という感じで3つのテーブルがあります。
ここから、data.`open_flag`が'1'の物を含む、
title.`title`を、program単位でランダムに5件抽出したいと思っていますが、

SELECT
ttl.`title`
,prg.`program_id`
,ttl.`title_id`
FROM `title` AS ttl
LEFT JOIN `program` AS prg ON prg.`program_id`=ttl.`program_id`
LEFT JOIN `data` AS dat ON dat.`program_id`=ttl.`program_id` AND dat.`title_id`=ttl.`title_id`
WHERE dat.`open_flag` = 1
ORDER BY RAND()
LIMIT 0,5

とやった場合、同じprogram_idが重複して抽出される場合が出てきてしまいます。。
この場合、重複せず必ずことなる`program_id`から抽出するにはどうしたら良いでしょうか?



306 :NAME IS NULL:2011/12/08(木) 20:55:28.43 ID:???
なんか難しい気がする

307 :NAME IS NULL:2011/12/08(木) 22:01:56.52 ID:???
UNIQUEだとnullが重複させられないDBもあるのか
と思って手持ちのDBで検証してみた

<UNIQUEカラムがnullのレコードを複数入れられるか>
Oracle:可
DB2:不可
SQL Server:不可
MySQL:可

308 :NAME IS NULL:2011/12/08(木) 22:41:20.47 ID:???
>>305
SLECT t.title,t.program_id,t.title_id
FROM program p
JOIN (SELECT * FROM data WHERE open_flag = 1 AND program_id=p.program_id ORDER BY RAND() LIMIT 0,1) d ON p.program_id=d.program_id
JOIN title t ON t.program_id=d.program_id AND t.title_id=d.title_id
ORDER BY RAND()
LIMIT 0,5
とかで行けないか


309 :NAME IS NULL:2011/12/09(金) 15:09:40.43 ID:???
2つの表を結合したあとに、nullなカラムにたいしてwhereでin演算子使ったら、
null項目が消えてしまいました
nullを残すにはどうしたらいいですか?

310 :NAME IS NULL:2011/12/09(金) 15:47:07.31 ID:???
where カラム in (xxx, yyy, zzz) ってやったってこと?

普通に where カラム in (xxx, yyy, zzz) or カラム is null でいいと思うんだが。

where カラム in (xxx, yyy, zzz, null) とできるかと思ったが、だめみたい@sqlite

311 :NAME IS NULL:2011/12/09(金) 16:07:01.35 ID:???
> 普通に where カラム in (xxx, yyy, zzz) or カラム is null でいいと思うんだが。
順番が逆

> where カラム in (xxx, yyy, zzz, null) とできるかと思ったが、だめみたい@sqlite
そらそうよ

312 :NAME IS NULL:2011/12/10(土) 19:36:11.17 ID:W27PbLIP
access2000で

NEN | TUKI
23 | 11
ってデータがあったら

平成23年12月31日のように常に次月末日を返したいのですが
どのようなクエリになりますか?

313 :NAME IS NULL:2011/12/10(土) 19:40:14.08 ID:???
翌月のマイナス一日。

314 :NAME IS NULL:2011/12/10(土) 19:53:05.54 ID:W27PbLIP
DateSerial((NEN),Month(TUKI)+2,0)
ってやったら
平成35年02月28日って返ってきてしまうのですが...

315 :NAME IS NULL:2011/12/10(土) 20:05:36.67 ID:???
西暦にすればいんじゃね?
NEN+1988

316 :NAME IS NULL:2011/12/10(土) 20:10:40.26 ID:W27PbLIP
>>315
テンキュー!

317 :NAME IS NULL:2011/12/11(日) 04:02:19.30 ID:NKNPQTbf
検索結果の集合の共通部分は求められますか。
たとえばid=1の結果が{a, b, c, d}でid=2の結果が{b, c, e}なら{b, c}を求めたいです。

318 :NAME IS NULL:2011/12/11(日) 04:08:53.97 ID:NKNPQTbf
自己解決しました。INTERSECTでした。

SQLで集合演算:CodeZine
http://codezine.jp/article/detail/1304

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

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

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