SQL質疑応答スレ 12問目

このエントリーをはてなブックマークに追加
1NAME IS NULL
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

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

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

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

前スレ:
SQL質疑応答スレ 11問目
http://hibari.2ch.net/test/read.cgi/db/1299305530/
2NAME IS NULL:2011/09/23(金) 18:26:10.78 ID:???
3NAME IS NULL:2011/09/23(金) 18:27:12.05 ID:???
4NAME 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
;
5NAME 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
;
6NAME 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によって文法がかなり違うので注意
7NAME 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
8NAME 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ならこれを適当に改変すれば動きますが
 どのみちお奨めしません。
9NAME IS NULL:2011/09/23(金) 18:33:51.81 ID:???
以上、テンプレ終わり
10NAME IS NULL:2011/09/23(金) 18:50:00.23 ID:???
終了
11NAME IS NULL:2011/09/23(金) 19:07:06.06 ID:???
おつ
12NAME IS NULL:2011/09/23(金) 19:23:15.50 ID:???
ちん
13NAME IS NULL:2011/09/24(土) 22:57:23.29 ID:???
ぽこの
14NAME IS NULL:2011/09/24(土) 23:21:55.10 ID:???
さき
15NAME IS NULL:2011/09/25(日) 02:56:19.86 ID:???
っちょ
16NAME IS NULL:2011/09/25(日) 05:12:27.01 ID:???
ペロ
17NAME IS NULL:2011/09/25(日) 13:14:59.87 ID:???
なめ
18NAME IS NULL:2011/09/25(日) 14:59:49.75 ID:???
たい
19NAME IS NULL:2011/09/25(日) 17:52:40.43 ID:???
いいよ
20NAME IS NULL:2011/09/25(日) 18:10:01.89 ID:???
SQLマジSQL
21NAME IS NULL:2011/09/26(月) 02:22:08.21 ID:???
SQLマゾSQL
22NAME IS NULL:2011/09/27(火) 19:27:40.41 ID:???
まん
23NAME IS NULL:2011/09/27(火) 20:26:27.50 ID:???
ぼっ!!
24NAME IS NULL:2011/09/28(水) 01:27:57.03 ID:???
なめ
25NAME IS NULL:2011/09/28(水) 02:17:41.30 ID:???
よかった、SQLで悩んでる人はいなかったんだ
26NAME IS NULL:2011/09/28(水) 03:58:12.31 ID:???
いく
27NAME IS NULL:2011/09/28(水) 04:39:07.10 ID:???
でる
28NAME IS NULL:2011/09/28(水) 16:16:40.94 ID:???
のんで
29NAME 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を書けばいいでしょうか。
よろしくお願いします。
30NAME IS NULL:2011/09/28(水) 18:56:10.19 ID:???
select * from user where name = 'bbb';
31NAME 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)
こうかな
32NAME 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)
;
33NAME IS NULL:2011/09/29(木) 02:06:55.87 ID:???
>>32
MySQLって無茶苦茶なSQL通すから、間違いじゃないのかもしれん
が、それを堂々と回答されてもなぁ
34NAME IS NULL:2011/09/29(木) 02:20:05.86 ID:???
>>32って無茶苦茶なSQLなの?
35NAME IS NULL:2011/09/29(木) 02:28:43.31 ID:???
>>34
>>32じゃなくて>>31
36NAME IS NULL:2011/09/29(木) 03:47:43.88 ID:???
>>35
>>33じゃなくて>>32
37NAME 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個をフラグ建てたい)
するにはどうしたらいいでしょうか?

38NAME IS NULL:2011/09/29(木) 10:14:28.26 ID:???
update文にORDER BYって
39NAME IS NULL:2011/09/29(木) 10:33:32.84 ID:???
またMySQLか
40NAME 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じゃないだろうし
41NAME 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

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


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

自らが子会社の場合は親会社に合算するので、子会社としては表示しません。
お願いします。
43NAME IS NULL:2011/09/29(木) 12:15:39.26 ID:???
>>41
ID=1,2,3がabc商事なら、結果の1行目は200+300+400+100で1000じゃないのか?
売上テーブルに7,400の行が無いのは抜けてるだけか?
子会社の子会社はあり得るのか?
44NAME IS NULL:2011/09/29(木) 12:47:17.27 ID:???
>>41

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


45NAME 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
とかでどうだ
4629:2011/09/29(木) 13:54:27.91 ID:???
>>31-32
教えていただいたSQLでほしい情報を取得できました。
ありがとうございました。
47NAME IS NULL:2011/09/29(木) 13:58:13.47 ID:???
>>45
ありがとうございます。
ちょっとテーブル構成がより複雑なので修正してやってみます。

副問い合わせがよくわからなかったものでして。
48NAME IS NULL:2011/09/29(木) 17:34:55.87 ID:???
お安い御用です。
49NAME 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のせいで同じ結果がたくさん出てきてしまいます。
ビュー同士の結合とかはダメなんでしょうか?
うまく親会社ごとに合計したいです。お願いします。
50NAME IS NULL:2011/09/30(金) 19:34:57.48 ID:???
dbo.売伝 CROSS JOIN
dbo.売伝明細
の部分が要らないと思う
51NAME IS NULL:2011/09/30(金) 19:51:55.39 ID:???
>>49
A商事 本店,5100
どういう計算だ?
52NAME 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にしても、テーブルが紐付く条件よく考えてみることだ
53NAME 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

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

54NAME IS NULL:2011/10/03(月) 17:45:31.04 ID:???
なぜそんなビューを作るのか理解できん
すなおに個々のテーブル定義と欲しい結果書け
55NAME IS NULL:2011/10/03(月) 17:55:28.61 ID:???
>>54
すみません。
ここのテーブルは多すぎて。
ただ1つのテーブルに親得意先コードと親得意先コードがあるため
集計のときとかとてもやっかいです。

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

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

あとでテーブルまとめます。
56NAME IS NULL:2011/10/03(月) 20:46:46.84 ID:???
これだけ見ると、Group Byでよさげ。
57NAME IS NULL:2011/10/03(月) 21:46:16.60 ID:???
なんで出てくるたびに例のデータが変わってんだよw
今までにあげられたSQLではどうダメだったのか書かないと釣りかと思うぜ
5857:2011/10/03(月) 21:48:09.14 ID:???
考え方は、親でgroup化して、合算値を出して、得意先と結合して出力する、だよ。
それを求めるための方法がいくつかあるけれど、みんなそういうSQL書いてくれてるはず。
59 忍法帖【Lv=7,xxxP】 :2011/10/03(月) 23:57:09.71 ID:???
60NAME 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
61NAME 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を取得するにはどうしたら良いでしょうか?
62NAME IS NULL:2011/10/08(土) 02:51:44.33 ID:???
>>61
>>6は見たかな?
63NAME 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')
64NAME 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' )
とかじゃいかんのか?
6561: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'

パフォーマンステストをして方法を検討したいと思います
皆さんありがとうございました!
66NAME IS NULL:2011/10/08(土) 20:31:16.03 ID:???
post_tagsを2回もJOINする必要あるの?
67NAME IS NULL:2011/10/08(土) 20:41:15.24 ID:???
ない。
68NAME 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です。
69NAME IS NULL:2011/10/09(日) 06:58:37.42 ID:???
再帰的な検索しないなら、同じテーブルでも別名つけてJOINすれば良いだけ

再帰的に、レスのレスのレス...も欲しいとなると
・再帰SQLをつかう
・ストアドプロシジャで処理する
辺りが通常の手段だが、MySQLでサポートされてるかどうかはしらね
どっちもダメならホストアプリでやるかデータ形式工夫するかしないとダメだね
70NAME IS NULL:2011/10/10(月) 00:48:14.10 ID:???
SQLサーバーで、FROM 句のテーブル名をカンマ区切りで列記した場合は
INNER JOIN になる、であってるでしょうか??
71NAME IS NULL:2011/10/10(月) 01:20:51.35 ID:???
CROSS JOINだろ
72NAME IS NULL:2011/10/10(月) 01:28:27.16 ID:???
WHEREで結合条件指定しないならCROSS JOINじゃないか

と言っておいて考えると、CROSS JOINしてからWHEREで絞っても同じだから
結合条件があろうとなかろうとCROSS JOINと等価なのか
73NAME IS NULL:2011/10/12(水) 23:55:32.82 ID:qJQCBXRw
mysql5.1

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

74NAME IS NULL:2011/10/13(木) 01:15:33.52 ID:???
知るかよ。それぐらい自分で試せばいいだろ。いちいち人に聞くな
75NAME IS NULL:2011/10/13(木) 01:28:17.44 ID:???
テーブル次第。
76NAME IS NULL:2011/10/13(木) 03:47:19.96 ID:???
> REPLACEは、もしテーブル内の古い行が PRIMARY KEY か
> UNIQUEインデックスの新しい行と同じ値を持っていれば、
> 古い行は新しい行が挿入される前に削除されるという事以外、
> INSERTと全く同じように機能します。

ふぅん
77NAME IS NULL:2011/10/13(木) 08:13:23.36 ID:???
>>73
俺ならいきなりINSERTする。
ON DUPLICATE KEY UPDATE 〜 付きで。
78NAME IS NULL:2011/10/13(木) 13:49:24.76 ID:???
>>77
なんでREPLACEじゃないの?
79NAME IS NULL:2011/10/14(金) 13:57:07.71 ID:efaJhCig
一つのデータに複数のキーワードを関連付ける物を作成しているのですが、
指定したすべてのキーワードが関連づけられているデータを探し出すSQL文はどのように書けばいいでしょうか?
データ構造はdata, keyの二つで、
data=1に20と30のkeyが関連づけられていたら、
(1,20),(1,30)
のようなデータが入っています。
80NAME IS NULL:2011/10/14(金) 14:48:17.47 ID:???
81NAME 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

よろしくお願いします
82NAME 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)
;
83NAME IS NULL:2011/10/15(土) 12:49:36.09 ID:5cbPt9KL
ありがとうございます。deleteできました
84NAME 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 /* データベースが間違っています、または存在していません */
このエラーが出ます、文字列のエスケープシーケンスのやり方が間違っていると思うのですが、分かりません
教えて頂けないでしょうか。
85NAME IS NULL:2011/10/15(土) 14:29:24.35 ID:???
スレ違い
86NAME IS NULL:2011/10/15(土) 14:30:23.00 ID:???
>>84です
どこで聞いたらいいでしょうか?
87NAME IS NULL:2011/10/15(土) 14:52:37.32 ID:???
言語のスレ
88NAME IS NULL:2011/10/15(土) 14:54:18.39 ID:???
「ymdhm」でCREATEして「yymmdd」でINSERTかよ?
VALUE句もTEXTならシングルクォートで囲えよ・・・まあSQLiteなら数値なら通るだろうけど。
89NAME IS NULL:2011/10/17(月) 15:00:20.57 ID:???
データベースを選べるように設計したいのですが、
そうなると独自実装みたいなSQLは排除する必要があります。
主要なフリーのRDBMS
MySQL PostgreSQL SQLiteあたりでどれでも動くような書き方をするのに、
参考になるサイトや文献があったら教えてもらえませんでしょうか?
90NAME IS NULL:2011/10/17(月) 15:16:59.16 ID:???
そういうライブラリを使う
or
標準SQLの範囲で記述するのはもちろん、各RDBMSが実装できていない部分を調べて、それらを使わないようにする。
これはマニュアルを見るのが楽。
91NAME 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日まで遡ってまでのレコードを取得したい場合どう書くのが適切でしょうか?
92NAME IS NULL:2011/10/17(月) 16:21:20.95 ID:???
日付関数あるなら簡単でしょう
where 日付レコード > 現在時刻-90日分の時刻
93NAME 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');
で大丈夫かな
94NAME IS NULL:2011/10/17(月) 17:46:07.93 ID:???
その調子で全部確認していく気かい
95NAME IS NULL:2011/10/17(月) 18:15:30.41 ID:???
91,93どっちもdatetime()→date()だった
>>94
SQL初めて触ったけど純粋に datetime > 'yyyy-MM-DD' の比較が成り立つのが不思議でして
96NAME IS NULL:2011/10/17(月) 18:35:17.32 ID:???
unixタイムに変換すればいいじゃない
97NAME IS NULL:2011/10/17(月) 20:44:54.63 ID:???
>>95
型毎に演算子をオーバーロードしているようなものです
98NAME IS NULL:2011/10/17(月) 23:43:56.84 ID:???
この場合は暗黙の型変換だろ
99NAME IS NULL:2011/10/18(火) 15:28:21.23 ID:???
お安い御用です。
100NAME 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だと最も早い時刻でグループ化されてしまいます。
よろしくお願いします。
101NAME 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
で良いような気がする
102NAME IS NULL:2011/10/19(水) 05:10:43.03 ID:???
どう考えても>>4
103NAME IS NULL:2011/10/19(水) 05:11:26.40 ID:???
とおもったら日付でグループだった無念
104NAME IS NULL:2011/10/19(水) 10:32:30.80 ID:???
Androidでアプリを作ってんのか。すげぇな。
105100:2011/10/19(水) 13:32:07.01 ID:???
>>100
先ほど自己解決しました。
106NAME IS NULL:2011/10/19(水) 16:11:59.74 ID:???
>>105
解決したなら解決策を示しなよ。
>>101を始め、何人かがあんたのために考えてやったんだからさ。
107NAME 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ぐらいだとどうなんでしょう
108NAME 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

とかしといた方が、ステージ数がいくつになっても対応できるんじゃないの?
109NAME 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の値によってカラム数を変えるのは無理
110NAME IS NULL:2011/10/19(水) 19:33:11.44 ID:???
お安い御用です。
111NAME IS NULL:2011/10/22(土) 13:59:45.63 ID:???
>>107に近い質問だと思いますが、
レコードが0件の時に、全部のカラムをnullにしたのをinsertしたいのですが、
どういうinsert文を書けばいいでしょうか?
MySQLとSQLiteで使用可能な文だとありがたいです。
112NAME IS NULL:2011/10/22(土) 14:02:02.43 ID:???
when 0 then null
113NAME 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は複数あります。
114NAME IS NULL:2011/10/22(土) 18:55:02.86 ID:???
その例でいうとCARDID 1 のHOWMANYLEVELは 2 なのか 4 なのか
115113:2011/10/22(土) 18:57:13.72 ID:???
4です!
116NAME 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
;
117113:2011/10/22(土) 19:06:31.59 ID:???
>>116
ありがとうございます、sum文でも出来るんですね
非常に感謝してます
118111:2011/10/23(日) 01:24:51.45 ID:???
どなたか>>111お願いします。
119NAME IS NULL:2011/10/23(日) 01:47:39.01 ID:???
お安い御用です。
120NAME IS NULL:2011/10/23(日) 16:14:17.70 ID:???
>>118
レコードがあるときどうするのか書いてないけど、共通のロジックにしたいのならアプリでやる。
121NAME IS NULL:2011/10/23(日) 16:17:00.47 ID:???
そもそも num > 10 and num < 100.123 という条件だったらの間に何レコードあると教えるのさ
122NAME 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でも良いけど
123111: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で早速試してみます。
124NAME IS NULL:2011/10/23(日) 21:42:18.16 ID:???
>>122
なにこのトンデモ回答?

>>123
MySQL/SQLite専用ならcreate table if not existsとか
replace文とか使えるけど、汎用を目指すならそんな変な構文は使わず、
アプリ側で条件分岐すべき
125NAME IS NULL:2011/10/23(日) 22:00:33.49 ID:???
>>124
どこかどうトンデモ回答なのかkwsk
126124:2011/10/23(日) 22:34:45.65 ID:???
>>125
一点目はnullがリテラルとして使えるかという点
二点目はgroup byなしでhavingが使えるかという点

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

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

そこまで解ってるならトンデモ回答とか言わずにちゃんとそう指摘しろよ
128NAME IS NULL:2011/10/24(月) 01:17:47.83 ID:???
NULLがリテラルとして使えない実装だとどうするの?カラム指定をしないってことかな
129NAME IS NULL:2011/10/24(月) 03:40:19.16 ID:???
>>128
CASTのソース(NULLをCASTする)や、CASEでのNULLはOKらしいから、それでやるんじゃね

まあ、実際はテーブルには主キーがあるべきで、主キーがあれば、
列リストに主キーだけ指定したinsert文ながせば
主キー以外はデフォルト値入るからそうするべきじゃないかと
130NAME IS NULL:2011/10/24(月) 03:45:26.47 ID:???
>>128
念のために言っておくが、insertで指定されなかったカラムに入るのは
あくまでもそのカラムのデフォルト値な

明示的にNULL以外をデフォルト値にしてる場合はその値になるし、
デフォルト値が指定されていない場合は多分NULLがデフォルト値になってると思うが
これが既定の動作かどうかはしらん
131NAME IS NULL:2011/10/24(月) 05:47:45.09 ID:???
そういやPostgreSQLのダンプファイルとか見ると\nって書いてるな。
132NAME IS NULL:2011/10/25(火) 07:17:45.15 ID:???
お安い御用です。
133NAME 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で複数回読み込むのは避けたいです。

アドバイスよろしくお願いいたします。
134NAME 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(+);
135NAME IS NULL:2011/10/26(水) 04:28:43.15 ID:???
DAT_AのID2がnullのとき、mb.VALUEはどうしたいんだ?
(+)でもouter joinでもいいけど、普通にDAT_Aに外部結合するだけでいいとおもうんだが?
136NAME 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




よろしくお願いいたします。
137NAME IS NULL:2011/10/26(水) 21:48:41.42 ID:???
DATE=200103とDATE=200104でそれぞれ抽出、
ID1とID2でfull outer joinすればいい。
138NAME 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
;
139NAME 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
)

的なことをしたいです。
140NAME IS NULL:2011/10/27(木) 06:12:30.27 ID:???
つ trigger
141NAME IS NULL:2011/10/27(木) 06:15:31.69 ID:???
なるほど!
こういうときにtrigger使うんですね。
言葉だけは聞いたことはあったのですが、
難しそうなのでスルーしてました。
調べてみます。どうもありがとうございます。
142NAME IS NULL:2011/10/27(木) 19:45:31.79 ID:HJWr1HNd
あるカラムのMAXから+1した値をとりたいのですが
SELECT (SELECT MAX(column) FROM t) + 1
で問題ないでしょうか?
143NAME IS NULL:2011/10/27(木) 19:57:17.87 ID:???
SELECT MAX(column) + 1 FROM t
でいいだろ
144NAME IS NULL:2011/10/27(木) 19:59:10.53 ID:???
>>143
ありがとう!
145NAME IS NULL:2011/10/27(木) 21:53:43.97 ID:???
お安い御用です。
146NAME IS NULL:2011/10/27(木) 22:26:46.39 ID:???
そして、ありがとう!
147NAME 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ありませんか?
148NAME IS NULL:2011/10/28(金) 20:24:26.88 ID:???
まず日本語でちゃんと説明できるようになってくれ
149NAME 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できるよ。
151NAME 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使えばいいんじゃね
152NAME IS NULL:2011/10/29(土) 18:47:35.28 ID:???
すまん。よくよまずこたえてしまった
153NAME 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で表現したいのですが可能でしょうか?
154NAME IS NULL:2011/10/31(月) 00:46:24.09 ID:???
なにがしたいのか、さっぱりわからん
155NAME IS NULL:2011/10/31(月) 01:19:52.99 ID:aQyfoOov
SQL命令で表(TABLE)を作る
1、本(コード・題名・著者名・出版社名・価格・在庫冊数)

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

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

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

このまんまの問題がでたんだけど意味が全く分からない
156NAME IS NULL:2011/10/31(月) 02:02:09.11 ID:???
>>153
レコードがあればアップデートってことだと思うんだけど、
それなら
update t set foo=bar where id=1
だけでよくって。
157NAME IS NULL:2011/10/31(月) 02:03:02.99 ID:???
>>155
create table を4つ書けってこと。それでもまったくわからないのなら、基礎を勉強してくること。
158NAME IS NULL:2011/10/31(月) 04:36:12.47 ID:aQyfoOov
>>157
例えば1の場合だと
CREATE TABLE 商品表
みたいに書けばいいのか?
159NAME IS NULL:2011/10/31(月) 04:39:16.08 ID:???
>>158
え?商品表って言葉どっからでてきたん?
160NAME IS NULL:2011/10/31(月) 04:46:55.70 ID:aQyfoOov
>>159
カオスになってきたのでヒントか答えくださいまし
161153:2011/10/31(月) 05:07:19.45 ID:???
>>156
ありがとうございます。
確かにそれで問題はないのですが、
id=1がなかったらエラーが返ってきて、
それをログに書き込むようにしてるため、
それを無くす前に、update前にid=1があるかを確かめたい感じです。
selectとupdateを分ければ可能ですが、
1度に書くことはできないかな?と思って質問しました。
162NAME IS NULL:2011/10/31(月) 05:08:05.53 ID:???
>それを無くす前に
それを無くす為にです。
日本語おかしくてすみません。
163NAME IS NULL:2011/10/31(月) 05:45:22.57 ID:???
>>162
問題がないと言いつつエラーが返るという表現はおかしくないのかな
まずそのあやふやなエラーが何なのか聞く方が先だと思う
164NAME IS NULL:2011/10/31(月) 05:53:51.35 ID:???
>>160
カオスも何も。
create table 本 〜
日本語が気に入らないなら create table books 〜 とかにすればいい。

>>161
なかった場合は、正常に0件更新されるはずだよ。
165NAME IS NULL:2011/10/31(月) 05:55:08.19 ID:???
>>163
動作上は内部でエラーが出ても、
それを出力して動作を停止させるわけではないので問題がないといったのです。
Apacheでfavicon.icoがなかったらエラーログが書きこまれまくりますが、
イメージとしてはあれみたいな感じです。
166NAME IS NULL:2011/10/31(月) 05:56:52.78 ID:???
>>165
エラーを貼る。
エラーが実は出力されていなかったら>>155に君が回答してあげると良い。
167NAME 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になります。

よろしくお願いします
168NAME IS NULL:2011/10/31(月) 13:14:17.19 ID:???
desc テーブル名
じゃだめかな
169NAME IS NULL:2011/10/31(月) 16:06:33.76 ID:???
テーブル名を大文字で書いてないとか
170NAME IS NULL:2011/11/01(火) 03:53:41.32 ID:???
>>161
普通updateがゼロ件更新してもエラーは返さんと思うが
誰がどんなエラー返してるのか書け

>>167
そういうDBMS固有の問題はそのDBMSのスレで聞け
標準的なSQLにテーブル定義を表示する文はない
171NAME IS NULL:2011/11/01(火) 06:07:04.75 ID:???
> 標準的なSQLにテーブル定義を表示する文はない

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

select cname from col where tname='テーブル名';
173NAME IS NULL:2011/11/01(火) 06:32:32.54 ID:???
INFORMATION_SCHEMA 使えよ・・・ せっかくANSIにあるんだからさ。
174NAME IS NULL:2011/11/01(火) 09:00:04.34 ID:???
>>170
RDBの根本から覆しちゃったよw
175NAME IS NULL:2011/11/01(火) 16:22:23.83 ID:???
>>174
えっ
176NAME IS NULL:2011/11/01(火) 17:58:07.27 ID:???
>>172
そういう独自実装をまとめるためにsql2003で定義された。
sql標準への準拠なんてまちまちだから、自分が使ってるRDBMSが対応してるかどうか調べてからじゃないと使えないけどな。

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

testはnull可能な項目で、

select test from t where test <> null
ではだめでした。
178NAME IS NULL:2011/11/01(火) 21:55:01.35 ID:???
is not null
179NAME 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,タグ名
180NAME IS NULL:2011/11/04(金) 21:55:42.44 ID:???
>>179
十分だといってるそのテーブルレイアウトで、あるタグが指定されているメールを抽出するのはどうするつもり。
DBを信じるんだ。そんで、数十億件とかになるなら考えよっか。
181NAME IS NULL:2011/11/04(金) 22:05:04.02 ID:???
>>179
学問上、「正規化」と呼ばれる観点から言えば前者が正しい。

学問上正しい設計が実用に耐えうるかというのはまた別の話。
182NAME IS NULL:2011/11/04(金) 22:06:27.62 ID:???
設計スレ行った方がいいな。

DB設計を語るスレ 4
http://hibari.2ch.net/test/read.cgi/db/1309828440/
183179:2011/11/04(金) 23:19:30.78 ID:???
>>180-182
ありがとう。
なんか馬鹿な設計をしてるんじゃないかと心配になってた。
184NAME IS NULL:2011/11/05(土) 01:47:23.07 ID:???
ついでに質問。>>179 のような例で、
テーブルA:メールID,SendTo,本文,...,タグ名
テーブルB:メールID,タグID,タグ名
テーブルC:タグID,タグ名
上のように(たとえばタグ名で)データベースを重複させるのは御法度?それとも良くある話?
データ密度的に無駄でバグ要因でもあるけど、場合によっては効率は上がりそう。
185NAME IS NULL:2011/11/05(土) 02:25:09.03 ID:???
スレ違いだって言ってる相手にお礼をいってる人間のなすこととは思えんな。
186NAME IS NULL:2011/11/05(土) 08:29:34.52 ID:???
>>184
御法度。「場合によっては」なんて要件もクエリもろくに決まっていない
時点で無駄に効率云々に気を取られている時点で御法度。
教科書通り正規化しておけばよし。そして大抵はそれが一番無難に速い。
187NAME IS NULL:2011/11/05(土) 09:35:41.90 ID:???
必ずしも正規化が良い結果を生むとは言い切れない.
高度に抽象化するとあとで他の人の理解を妨げることもある.
どんくさくてもデータ量が少ないなら視認性の高いほうがいい.
188NAME IS NULL:2011/11/05(土) 09:46:54.64 ID:???
スレ違いだっつーの。
189NAME IS NULL:2011/11/05(土) 10:04:16.04 ID:???
すまん.
190NAME 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]で得られる結果は同一ではないかと思うのですが違うのでしょうか。

因みに、自分の環境での検証では同じ結果が得られていると思います。
191NAME 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;

この結果を比較して、全件出ていない気がする人に見せる
192NAME IS NULL:2011/11/07(月) 11:39:46.73 ID:???
今後、全件でてない気がするといわれるたびに同じことを繰り返し、
めんどくさくなったらSQLの勉強してくださいという。
193NAME IS NULL:2011/11/07(月) 14:01:29.29 ID:???
知人の例にある(+)はOracle方言の外部結合演算子。
例1の場合テーブル1にはあっても解法テーブルや手順テーブルに対応する行が
無い場合は出力されない。

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

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

あといつも外部結合を使う様な知人の言うこともイマイチ信用できないので要注意。
194NAME IS NULL:2011/11/07(月) 15:22:10.46 ID:???
left join と left outer join が等価でないソース希望
195NAME IS NULL:2011/11/07(月) 17:41:20.61 ID:???
例1でテーブル1が全件出力されていないなら、ORACLEにバグがあるとしか思えん
ORACLEってouter join周りはバグが多いと聞いたことがあるぞ
その知人はそれ嫌って(+)で外部結合してるのかもしれん(昔の人でそれしか知らんのかもしれんが)
とりあえずテーブル1の件数と出力件数比べてみればすぐわかるだろ

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

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

MySQLかsqlite3ってトリガ使えたっけ?
198196:2011/11/07(月) 18:54:58.85 ID:???
レスどうもありがとうございます。
順番とかないんですね・・・あまりに無知すぎて恥ずかしい。
ということは行の追加は普通に挿入すればいいんですよね。
で古い新しいの目印は、連番数字だとどんどん大きくなりすぎるから行を削除するたびにすべての行の連番数字をインクリメントしないといけないっぽいから
ミリ秒かマイクロ秒の時間にして、
行数の取得は
SELECT COUNT(*) FROM table
で、最大数よりもはみ出ているかどうかはPHP側でチェックして、
はみ出ていたら時間がもっとも小さいものを削除してまた行数を取得して最大数よりも大きいかチェックして・・・の繰り返しですか?
最小の行の削除は
DELETE MIN(time) FROM table
でいいですか?
199NAME IS NULL:2011/11/07(月) 20:10:55.40 ID:???
RDBMSによっては、循環型の連番を作ることができる。
けれど、数字が大きくなりすぎたからといって何の問題もないので連番でいいよ。
もし最大値まで使い切るような快挙を成し遂げた場合には、ここで報告してくれるとうれしい。
200196:2011/11/07(月) 20:43:44.60 ID:???
よくよく考えればミリ秒やマイクロ秒も数字がどんどん大きくなっていきますね・・・桁数に気をとられていました

行の総数が指定した数よりも大きいかとかの比較もSQLだけでできますか?
行数を取得(SQL)→指定した数と比較(PHP)→行数のほうが大きければ連番フィールドが最小の数字の行を削除(SQL)→
行数を取得(SQL)→指定した数と比較(PHP)→・・・の流れは無駄ですよね
今のところ行の追加は一行ずつなのでこの流れも一周だけで済みますが
それでもすべてまとめてSQLでできるならSQL→PHP→SQLとするよりもいいですよね
201NAME IS NULL:2011/11/07(月) 22:46:30.23 ID:HMXQlM9n
こんなsqlをmysqlで書いたんだけど、sql文が正しくないって出てくる
何が間違ってるのか教えてください
SELECT * FROM mycloud WHERE F_NAME = test.txt
202NAME IS NULL:2011/11/07(月) 22:49:03.10 ID:???
スレ立てるまでもない質問はここで 114匹目
http://hibari.2ch.net/test/read.cgi/tech/1318162690/453
203NAME IS NULL:2011/11/07(月) 22:53:19.02 ID:???
SELECT * FROM mycloud WHERE F_NAME = 'test.txt'
204NAME IS NULL:2011/11/07(月) 22:53:43.81 ID:???
>>200
どうしてもDB側でやりたければトリガーを使うしかない
アプリでやるのとそう変わらん

>>201
エスパーするとtest.txtが識別子じゃないんだろう
文字列リテラルならシングルクォートで括る
205NAME 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'])をシングルコーテーションでくくるとエラーになってしまいます・・・
206NAME IS NULL:2011/11/07(月) 23:05:52.22 ID:???
スレ違いだよハゲ
207NAME IS NULL:2011/11/07(月) 23:13:16.00 ID:???
>>206
すいませんでした・・・
そして自己解決できました、お騒がせして申し訳なかったです
208NAME 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で割ったあまり。
209NAME IS NULL:2011/11/08(火) 00:23:58.10 ID:???
行数が決まってるなら、更新日時♪が最小の行をupdateすればよくね?

アプリ起動(orインストール)時にダミーデータいれとく必要あるけど
210NAME IS NULL:2011/11/08(火) 00:25:05.86 ID:???
なんだこの音符は
211NAME IS NULL:2011/11/08(火) 02:23:18.00 ID:???
select * from test order by hoge desc
ってのは構文としてよくないんですか?
where 1とかちゃんといれたほうがいいんでしょうか?
212NAME IS NULL:2011/11/08(火) 02:31:00.68 ID:???
Where は別にいらん
むしろ*がだめ
213NAME IS NULL:2011/11/08(火) 03:20:00.93 ID:???
>>212
ありがとう
*使わないように気をつけます
214NAME 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するのは無駄が多いから
なるべく*使うなっていう考え方はある
215NAME IS NULL:2011/11/08(火) 05:08:25.95 ID:???
count(*)っていけないのかなとふとおもった
count(id)とかしてる例題あんまみないよね
216NAME IS NULL:2011/11/08(火) 05:20:49.04 ID:???
count(id)よりcount(1)よりcount(*)がいい
217NAME IS NULL:2011/11/08(火) 05:54:13.60 ID:???
>>215
count(id)とcount(*)では意味が違う

続きはwebで
218NAME IS NULL:2011/11/08(火) 06:06:10.43 ID:???
結果は同じでしょう
219196:2011/11/08(火) 20:06:55.87 ID:???
>>204,208-214
レスどうもありがとうございます
調べたり試したりしてみます
220NAME IS NULL:2011/11/08(火) 20:26:04.30 ID:???
>>217 
なぜ引っ張る?つか続きも何も本文もwebだぞ、ここw
>>218
項目の数を数えるのと行の数を数えるという意味的な違いはさておくとしても
idがnot nullなら同じ数字になるが、必ずしも同じになる保証はないのだよ

昔はcount(*)よりcount(1)ってした方が早い処理系が存在したらしいが
今ではおそらくバッドノウハウだと思われ
221NAME 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のレコードになります。
222NAME 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

とかでいけるんじゃね
223NAME 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);
224NAME IS NULL:2011/11/09(水) 20:51:56.87 ID:ViYEpCpP
行数の増減はほとんどなくても(たとえば1000行前後で推移してても)INSERTとDELETEを繰り返していると
断片化か何かで処理速度が落ちてきますか?
あとこういう行数はほぼ一定だけど行の挿入削除が激しい場合はindexはあまり意味ないですか?
いずれもデータベースによりますか?
225NAME IS NULL:2011/11/09(水) 21:22:11.72 ID:???
RDBMSによるんだけど、大抵それに対する解決方法がある
インデックスはそれが有効かどうかは行数に依存しない
226NAME IS NULL:2011/11/09(水) 21:33:59.91 ID:ViYEpCpP
レスありがとうございます
解決策というのはVACUUMやOPTIMIZEをしろということですか?それとも
断片化しにくいorしても速度が落ちにくい方法があるってことですか?
227NAME IS NULL:2011/11/09(水) 21:39:05.03 ID:???
スレ違いだからさっさとひっこめ
RDBMSによるっていってんのにRDBMSも指定しないとか脳みそ足りてんのか
228NAME IS NULL:2011/11/09(水) 21:40:53.45 ID:???
行の入れ替わりが激しい場合はどうなのかわからないけど
行数が少ないとインデックスの有効性はあまりなくない?
229NAME IS NULL:2011/11/09(水) 21:41:18.49 ID:???
スレ違い。
230NAME 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レコード取得する方法が思いつきません。
宜しくお願いします。
231NAME IS NULL:2011/11/11(金) 00:45:22.35 ID:???
select * from user
where name in (select name from user where id = @id)
232230:2011/11/12(土) 09:36:24.85 ID:???
>>231
行けましたありがとうございます!
233NAME 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
234NAME IS NULL:2011/11/12(土) 14:01:37.48 ID:???
動的SQLでセレクトした結果をカーソルに入れて返したいんですが、可能でしょうか?
235NAME IS NULL:2011/11/12(土) 16:22:24.54 ID:???
>>233
無理だな
どうしても書き換えるならUNIONだろうが、そっちのほうが速いとは限らない

>>234
普通はできるがプロシージャはDBMSによって全然違うので断言できない
236NAME IS NULL:2011/11/12(土) 16:26:31.59 ID:???
>>233
そのサイトもそろそろ時代遅れになってるな
237NAME IS NULL:2011/11/13(日) 01:02:02.53 ID:???
>>233
どうしてもORを使いたい場合ってのは、どうしてもORを使わざるを得ない場合を指してるんだよ。

>>236
たしかにね。すこし残念な気持ちに
238NAME IS NULL:2011/11/13(日) 14:57:33.43 ID:???
>>235
oracle11gです
239NAME IS NULL:2011/11/13(日) 14:59:10.20 ID:???
Oracleスレ行け。
240NAME 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独自らしいので、一般的なテーブルの有無の確認方法があれば
教えてください。

テーブルが無いかもしれないのは、テーブルを削除しない限り初回の一回だけなのに、
毎回テーブルの有無を確認するのは変な気もするので、もし
やりたいことを実現できる別のアプローチがあればその書き方を教えてください。
データベース自体をあらかじめ作っておくことは出来ません。
241NAME IS NULL:2011/11/13(日) 19:20:38.47 ID:???
常にCreateを投げてエラーを無視すればいい。
242NAME IS NULL:2011/11/13(日) 19:22:58.68 ID:???
>>241
レスどうもありがとうございます
エラーが出ないようにしないといけないものだと思っていましたが
そういうやりかたでいいんですね
243NAME IS NULL:2011/11/14(月) 06:21:49.08 ID:???
SQLiteならcreate table if not existsなんていう構文もあるが
244NAME 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
というので出来たのですが、「両方にある」という条件になったら書き方がわかりません。

よろしくお願いします。
245NAME IS NULL:2011/11/14(月) 13:58:55.11 ID:???
>>244

>>6 じゃなかろか。
246244:2011/11/14(月) 16:21:41.99 ID:+RxR3+y0
>>245
その1でできそうです。
ありがとうございます。
247240:2011/11/14(月) 18:49:33.36 ID:???
>>243
どうもありがとうございます
その方法でやってみます
248233:2011/11/14(月) 21:58:39.21 ID:???
ありがとうございました。
249NAME 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位あります。
250NAME IS NULL:2011/11/15(火) 03:32:37.58 ID:???
方言での実装になるのでMySQLスレにいくといいかも
251NAME IS NULL:2011/11/15(火) 03:41:30.27 ID:???
GROUP_CONCATで1列にしてしまうとか簡単だぞ
252NAME IS NULL:2011/11/15(火) 19:54:33.52 ID:???
カウント数が97とか、データが4000とか、97列とか4000列とかのデータが欲しいってか?
要件と設計みなおした方がいいんじゃねえか
253NAME IS NULL:2011/11/15(火) 20:19:56.54 ID:???
まず>>7
254249:2011/11/15(火) 23:53:31.31 ID:???
ありがとうございました。諦めます。
255249:2011/11/16(水) 00:00:59.45 ID:???
あ、>>251 さんの group_concat でイケそうです。
重ねて、ありがとうございました。
256249:2011/11/16(水) 00:16:50.67 ID:???
group_concat で欲しい結果を得る事ができました。(>>249の件 終了)

皆さん、本当にありがとうございました。諦めずに続けていきます。
257NAME IS NULL:2011/11/18(金) 11:37:31.67 ID:???
初心者です。よろしくお願いします。
使用DBはMS-ACCESSですが専用スレがないのでここで質問してみます。

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

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

このような事象をグループ化して抽出するうまい方法はありますでしょうか?
よろしくお願いいたします。
258NAME IS NULL:2011/11/18(金) 11:46:13.96 ID:???
申し訳ありません。
自己解決しました。
とりあえずターゲットの犬がいてその犬の兄弟だけ抽出ということだそうなので
ターゲットの犬の誕生日前後数日で検索すればよいことになりました。
259NAME 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分以内に探索を終了させたい)させるとしたら、どのような方法が考えられますでしょうか?
文字列を全て一度に送って、全件探索を一度で済ませるようなことは出来るのでしょうか?
ご教示願います。
260NAME 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, を追加
です。宜しくお願いします。
261NAME IS NULL:2011/11/26(土) 21:04:33.72 ID:???
orとunionで結べば1文にはなると思うけど
262NAME IS NULL:2011/11/26(土) 21:23:11.04 ID:???
とりあえず、index使って全件検索しないようにしてみたら?
263NAME IS NULL:2011/11/27(日) 17:43:51.99 ID:???
elem1にA-BとかA-B-Cとかいう文字列が格納されてるのか?
とりあえずループまわしてるSQL書いてみ
264NAME IS NULL:2011/11/27(日) 21:21:45.46 ID:???
>>259

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

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

265NAME IS NULL:2011/11/28(月) 01:34:43.46 ID:???
Aが出現しなければA-Bも出現しないので、そういうところで減らせたりしないのだろうか
266NAME IS NULL:2011/11/28(月) 02:03:37.30 ID:???
今のSQLも実行計画もださないで今より早くって言われてもな
>SQL文をループで回していて、unigramでは5回
まさかとおもうが、elem1='A'を検索するSQLを発行して、elem1='B'を検索するSQLを発行して...じゃないだろうな
267NAME IS NULL:2011/11/28(月) 02:34:26.35 ID:???
関数つきのインデックス(だったかな?)、 なんて言ったかなあ、あらかじめ関数の結果をインデックス化しておくやつ
それやっとけば速くなるかもね。
268NAME IS NULL:2011/11/28(月) 22:22:37.66 ID:???
それって結局関数の結果をDBに収めてるのと同じだろ
関数の意味ねぇな
269NAME IS NULL:2011/11/28(月) 23:00:49.79 ID:???
>>267
まんま、ファンクションインデックス

>>268
インデックスだからデータが更新されれば当然インデックスも更新されるわけで
マテリアライズドビューみたいな原則非同期更新のものとは違うという意味はあると思うけど
270NAME IS NULL:2011/11/28(月) 23:13:49.78 ID:???
使ったことないけど気にはなっていたマテリアライズドビューが非同期ということに驚いた
ありがとう
271NAME IS NULL:2011/11/29(火) 00:59:00.02 ID:???
マテリアライズドビューが原則非同期ってのが気になって調べてみたら
これって昔はレプリケーション用のスナップショットと呼ばれてた、らしい
なるほど
インデックス付きのビューとは用途が違ってるわけか
272NAME 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かでないとだめということです。

そういうことはできますでしょうか?
273NAME 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)
    )
)
274272:2011/12/03(土) 20:35:39.61 ID:???
>>273
ありがとうございます。

アプリケーション側ではできるのですが、DB側でも二重にしたかったので助かりました。
275NAME 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;
276NAME IS NULL:2011/12/03(土) 21:11:03.67 ID:???
>>275
ちょっとその日本語が何言ってるのかよくわからんが
その普通と今回とで実行計画とってみれば?
同じ実行計画なら同じ重さ

つかその二つで違う実行計画出すDBMSあったらびっくりだが
277NAME IS NULL:2011/12/03(土) 22:34:05.26 ID:???
>>276
サイキック回答ありがとうございます。
「実行計画」と言うのが初耳でした調べて見ます。
278NAME IS NULL:2011/12/04(日) 03:01:37.13 ID:???
>>275
その二つは別名の有無の差しかないけれど、上の日本語の内容を見ると、実際は実行計画の異なるクエリになるはずだな。
279NAME 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 ... は、検索が直面するすべてのレコード上に排他ネクストキーロックを設定します。」
と書かれています。
先行のトランザクションでは行に排他的ロックがかかってるはずですが、何故後発のトランザクションが読み取りに成功しているのでしょうか
280NAME IS NULL:2011/12/04(日) 22:11:51.12 ID:???
InnoDBってバージョニングでしょ?
更新前のデータを読むんだろ
281NAME IS NULL:2011/12/04(日) 22:39:54.81 ID:???
>>279
技術的興味で質問しているんだとしたら残念ながら回答にはならないけど、
もしこのことで何か困っているんだとすれば、ロックされるかされないかに
依存するようなプログラミングはしないこと。
頼っていいのはトランザクション分離レベルだけ。
282NAME IS NULL:2011/12/04(日) 22:40:06.74 ID:???
>>280
ありがとうございます
283NAME IS NULL:2011/12/04(日) 22:56:42.67 ID:???
>>281
更新の激しいテーブルをFOR UPDATEで確実に処理したいと思い、詳しく調べてみたら先述のような疑問が浮かんだという感じです
284NAME IS NULL:2011/12/04(日) 23:52:59.23 ID:???
つか特定のDBMSの実装の問題はそのDBMSのスレで聞け
285NAME 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で別途インデックス付けする予定です。

よろしくおねがいします。
286NAME IS NULL:2011/12/06(火) 18:32:42.13 ID:???
selectの速度には影響がないかもしれない。
けど、インデックスの更新速度が速くなるのはメリットだと思うよ。
詳しくはMySQLスレで聞くといいかも
287NAME IS NULL:2011/12/07(水) 07:57:23.93 ID:???
not nullなカラムに空文字が入って欲しくないんですけど
これはcheckでやるしかないですか?
288NAME IS NULL:2011/12/07(水) 12:12:02.44 ID:???
>>287
ほとんどのDBMSではちゃんとNULLと空文字列を区別するからそう
ただ一部区別できないDBMSがある。メジャーなやつだがな
289NAME IS NULL:2011/12/07(水) 15:31:00.10 ID:???
MS?
290NAME IS NULL:2011/12/07(水) 15:35:47.56 ID:???
SQLite?
291NAME IS NULL:2011/12/07(水) 15:37:26.48 ID:???
オラクルさんじゃね
292NAME IS NULL:2011/12/07(水) 19:59:34.90 ID:???
>>286
ありがとうございます。
293NAME 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以上であれば出力したいです。
294NAME IS NULL:2011/12/07(水) 20:54:49.47 ID:???
Aがある場合とない場合に場合分けして union all で繋げ
295NAME 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)

とか?
296NAME IS NULL:2011/12/07(水) 20:58:00.64 ID:???
on A.ID = B.ID がぬけてた
297NAME IS NULL:2011/12/07(水) 21:02:23.07 ID:???
AとBからIDを抜いてUNION、それにAとBを外部結合とか
298NAME IS NULL:2011/12/07(水) 22:51:17.55 ID:???
>>294
>>295
>>297

ありがとうございます。
今確認する環境がないので、
明日試してみます。
299NAME IS NULL:2011/12/08(木) 07:07:10.07 ID:???
NULLな項目でUNIQUEを指定すると、NULLがかぶってるときも登録できなくなりますが、
NULLはかぶってもよくて、NULLでないときはUNIQUEである必要があるというのは、
どんな感じに書けばいいでしょうか?
300NAME IS NULL:2011/12/08(木) 08:11:06.11 ID:???
>>299
>NULLな項目でUNIQUEを指定すると、NULLがかぶってるときも登録できなくなりますが、

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

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

だから最も簡単には、DBを「nullは皆ユニーク」と扱うやつに変えてしまう、かな。
301NAME IS NULL:2011/12/08(木) 14:33:06.00 ID:Q8sIgK2f
MySQLで質問させてください。
ある条件で絞ったレコードを日付でソートして
最新のn件以降を削除したい場合はどのようなSQLを書くのが良いでしょうか?
302NAME 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
 )

なんてのが出来るかどうかは、試してないから知らない。
303NAME IS NULL:2011/12/08(木) 15:28:44.91 ID:???
ある条件に当てはまらないものまで消えてしまわないか?
304301:2011/12/08(木) 15:57:18.19 ID:Q8sIgK2f
>>302,303

なるほど。
not in使えばよかったんですね。
limitでn件目以降全てというのが見当たらなかったので困ってました。
ある条件をdelete分のwhereに追加して試してみたいと思います。
ご回答ありがとうございます。
305NAME 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`から抽出するにはどうしたら良いでしょうか?

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

<UNIQUEカラムがnullのレコードを複数入れられるか>
Oracle:可
DB2:不可
SQL Server:不可
MySQL:可
308NAME 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
とかで行けないか
309NAME IS NULL:2011/12/09(金) 15:09:40.43 ID:???
2つの表を結合したあとに、nullなカラムにたいしてwhereでin演算子使ったら、
null項目が消えてしまいました
nullを残すにはどうしたらいいですか?
310NAME 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
311NAME 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
そらそうよ
312NAME IS NULL:2011/12/10(土) 19:36:11.17 ID:W27PbLIP
access2000で

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

平成23年12月31日のように常に次月末日を返したいのですが
どのようなクエリになりますか?
313NAME IS NULL:2011/12/10(土) 19:40:14.08 ID:???
翌月のマイナス一日。
314NAME IS NULL:2011/12/10(土) 19:53:05.54 ID:W27PbLIP
DateSerial((NEN),Month(TUKI)+2,0)
ってやったら
平成35年02月28日って返ってきてしまうのですが...
315NAME IS NULL:2011/12/10(土) 20:05:36.67 ID:???
西暦にすればいんじゃね?
NEN+1988
316NAME IS NULL:2011/12/10(土) 20:10:40.26 ID:W27PbLIP
>>315
テンキュー!
317NAME IS NULL:2011/12/11(日) 04:02:19.30 ID:NKNPQTbf
検索結果の集合の共通部分は求められますか。
たとえばid=1の結果が{a, b, c, d}でid=2の結果が{b, c, e}なら{b, c}を求めたいです。
318NAME IS NULL:2011/12/11(日) 04:08:53.97 ID:NKNPQTbf
自己解決しました。INTERSECTでした。

SQLで集合演算:CodeZine
http://codezine.jp/article/detail/1304
319NAME IS NULL:2011/12/13(火) 10:03:28.67 ID:???
tbl_rosen (駅名と備考は1:1)
路線名  駅名  備考
----------------------
A線   i駅   備考1
A線   j駅   備考2
A線   k駅   備考3
B線   k駅   備考3
B線   l駅   備考4
B線   m駅   備考5
C線   n駅   備考6
D線   k駅   備考3
D線   o駅   備考7

tbl_shop
店名  最寄駅
---------------
X店   j駅
X店   m駅
X店   o駅
Y店   l駅
Z店   k駅

tbl_rosenは鉄道路線とその駅名のテーブル(1路線に対して1〜n駅ある)、
tbl_shopは、スーパーの名前と最寄駅(1店に対して0〜nの最寄駅がある)

<やりたいこと>
・その店に鉄道で行くことが出来る駅のリストを作成したい
・ある特定の路線は除外(上の例だと、D線は対象外)
・乗り換えは考慮しない。

→例えば、Z店はk駅が最寄りで、k駅はA線、B線、D線の乗り入れ。D線を除外すると、
i、j、k、l、m駅から電車(±徒歩)でZ店に行ける

<最終的に出力したいテーブル)
tbl_output
店名  最寄駅  備考
----------------------
X店   i駅   備考1
X店   j駅   備考2
X店   k駅   備考3
X店   l駅   備考4
X店   m駅   備考5
Y店   k駅   備考3
Y店   l駅   備考4
Y店   m駅   備考5
Z店   i駅   備考1
Z店   j駅   備考2
Z店   k駅   備考3
Z店   l駅   備考4
Z店   m駅   備考5


2段階に分ければ(駅で結合して店名、路線名でグループ化(D線除外)した
テンポラリテーブルをつくって、さらにtbl_rosenと結合する)普通にできるのですが、
出来れば一発のSQLで出力したいのですが、SQL自体にまだ馴染みが薄く、
どのように書いて良いのかわかりません

よろしくお願いします(PostgreSQL8.4です)
320NAME IS NULL:2011/12/13(火) 13:21:20.51 ID:???
> (駅で結合して店名、路線名でグループ化(D線除外)した
> テンポラリテーブルをつくって、さらにtbl_rosenと結合する)
これをサブクエリでやればいいと思う。
exists使えば少しすっきりするかもだけど。
321NAME IS NULL:2011/12/13(火) 14:04:33.47 ID:???
>>319

SELECT 店名, 駅名, 備考

FROM
(SELECT 店名, 路線名 FROM tbl_rosen, tbl_shop
WHERE tbl_shop.最寄り駅名=tbl_rosen.駅名
GROUP BY 店名, 路線名
HAVING not in ('D線')) AS tmp, tbl_rosen

WHERE tmp.路線名=tbl_rosen.路線名;

雑で冗長だけど、これでいけるかな…

あ、最寄駅にはnullがありうるから、ダメかもw
322NAME IS NULL:2011/12/13(火) 21:41:23.84 ID:???
select 店名,最寄駅,t2.路線名,t2.駅名,t2.備考
from tbl_shop
join tbl_rosen t1 on 最寄駅=t1.駅名
join tbl_rosen t2 on t1.路線名=t2.路線名
where t1.路線名 <> "D線"
とかでダメか?
323NAME IS NULL:2011/12/14(水) 11:30:03.03 ID:???
【質問テンプレ】
・DBMS名とバージョン MySQL 5.1
・テーブルデータ
・欲しい結果
・説明

テーブル「カート」
カラム 「セッションID」「商品種別」「カートに入れた時刻」

テーブル「カート詳細」
カラム 「セッションID」「商品コード」

テーブル「商品リスト」
カラム「商品コード」「商品種別」

というテーブルがあります。

最後にカートに入れた時刻から12時間以上経過したセッションIDを検索して、
そのセッションIDを持つレコードを「カート」「カート詳細」の両方から
全て削除したいのです。

同じセッションIDを持つレコードは、両方のテーブルに複数あります。
「注文」テーブルで「セッションID」「商品種別」の組合せはユニークで、
「注文詳細」テーブルでは「セッションID」「商品コード」の組合せにユニークです。

結合や副問い合わせを試してみましたが、うまいこと抽出できません。
SQLで書くやり方があれば教えてください。よろしくお願いします。
324NAME IS NULL:2011/12/14(水) 11:34:07.27 ID:???
>>323
正確には抽出だけならこの文でできました。

SELECT * FROM カート, カート詳細 WHERE カート.セッションID =
カート詳細.セッションID AND カート.セッションID IN (SELECT
セッションID FROM カート詳細 WHERE カートに入れた時刻 <
unix_timestamp()-12*60*60

削除がうまいこといきません。
325NAME IS NULL:2011/12/14(水) 11:39:01.26 ID:???
>>324
間違えていました。

SELECT * FROM カート, カート詳細 WHERE カート.セッションID =
カート詳細.セッションID AND カート.セッションID IN (SELECT
セッションID FROM カート WHERE カートに入れた時刻 <
unix_timestamp()-12*60*60

http://www.pistolfly.jp/weblog/2009/06/you-cant-specify-target-table.html
これと関係があるようですが、 AS の入れ方がよくわからないのです。
326NAME IS NULL:2011/12/14(水) 11:52:57.02 ID:???
>>325
これでたぶん希望通りに動作するようですが、あってますか?

DELETE カート, カート詳細
FROM カート, カート詳細
WHERE カート.セッションID = カート詳細.セッションID
AND カート.セッションID
IN (SELECT tmp.セッションID
FROM (SELECT セッションID FROM カート
WHERE カートに入れた時刻 < unix_timestamp() - 12 * 60 * 60)
AS tmp)
327NAME IS NULL:2011/12/14(水) 12:22:03.51 ID:???
カート.セッションID
IN (SELECT tmp.セッションID
FROM (SELECT セッションID FROM カート
WHERE カートに入れた時刻 < unix_timestamp() - 12 * 60 * 60)
AS tmp)

って

カート.セッションID
IN (SELECT セッションID FROM カート
WHERE カートに入れた時刻 < unix_timestamp() - 12 * 60 * 60)

でいいんじゃないの
328NAME IS NULL:2011/12/14(水) 17:42:25.31 ID:???
>>327
SELECT文ならそれでいいんですが、DELETE文でやると
>>325
You can't specify target table 'xxx' for update in FROM clause
というエラーが出るので、同じ内容の一時テーブルを作る必要があります。
329NAME IS NULL:2011/12/14(水) 19:04:58.06 ID:???
・DBMS名とバージョン MySQL 5.1
InnoDBのトランザクションを使ってオートインクリメントをすると
連番にならず、番号が飛ぶのですが、仕様ですか?

INSERTする行数だけ飛びます。
1,2,3,4,5の5行をINSERTすると、5個欠番で次のデータが11,12,13となり、
3個欠番で次は14からスタート。
飛んでも問題はないので気分の問題ですが。

書いてる文はこのような感じです。

BEGIN;
 REPLACE INTO カート詳細 VALUES ('default', いろいろ);
 INSERT INTO カート VALUES ('default', いろいろ)
  ON DUPLICATE KEY UPDATE いろいろ;
COMMIT;

'default'は連番の入っているカラムです。
上の文はINSERT INTO ... ON DUPLICATE KEY UPDATEも試しましたが同様です。
下の文はREPLACEでは都合が悪いです。

REPLACEだとDELETE権限が必要なので、できればINSERT ...
ON DUPLICATE KEY UPDATEの方が好ましいです。
330NAME IS NULL:2011/12/14(水) 23:03:53.41 ID:???
>>323-328
そもそも一つのDELETE文で複数テーブルから削除できるのって、標準的な動作なのか?
delete from カート詳細 where セッションID in (select セッションID from カート where 省略)
delete from カート where あと同じ
の二つのSQL流せば良いんじゃ(REPEATABLE READ以上の分離レベルで)

>>329
それはSQLの問題じゃなくてMySQLの仕様の問題なんで、MySQLのスレで聞け
331NAME IS NULL:2011/12/14(水) 23:15:31.15 ID:???
>>330
そうか、その順番で2つのSQLを流せば無事に全部消えてくれますね。
一つで一気にやろうとばかりしていました。
ありがとうございました。
332NAME IS NULL:2011/12/15(木) 20:56:31.68 ID:???
oracleです。

・テーブルデータ
テーブルA
 ID |日付
 100|10/1
 100|10/2
100|10/5
 101|11/1
 102|11/1
 102|11/2
 103|12/1


テーブルB
 ID |期間(自)|期間(至)
 100|10/1  |10/4
 101|10/1  |10/30
 102|11/1  |11/5
 103|12/1  |12/1
 

・欲しい結果

 ID |期間内のカウント
 100|2
 101|0
 102|2
 103|1
 

・説明:
IDをキーに、期間内のIDごとのカウントをとりたいです。
SQL1本で取得する方法はありますでしょうか?
列は増やしたくないです。

333NAME IS NULL:2011/12/15(木) 21:56:01.48 ID:???
select
t.ID,
(select count(*) from テーブルA where ID=t.ID and 日付>=t.期間(自) and 日付 <=t.期間(至) ) as 期間内のカウント
from
テーブルB t
334NAME IS NULL:2011/12/17(土) 03:04:07.64 ID:mcufmMSb
mysqlで質問です。

| col1 | col2 | col3 | col4 | col5 | col6 |

| 3 | 1 | 0 | 5 | 4 | 12 |

| 2 | 5 | 6 | 0 | 1 | 8 |

のようなテーブルで
複数の条件、例えばA,B,C,D,E,Fで
このうちの3つの条件がいずれかでもあえば
そのレコードを取得するというような
クエリは可能でしょうか。

イメージ的にはLOTO6で5等に該当するレコードは全て取得するといった
感じなのですが。
335NAME IS NULL:2011/12/17(土) 04:19:23.42 ID:???
A and (B or C or D or E or F) or B and (C or D or E or F) or C and (D or E or F) or D and (E or F) or E and F
336NAME IS NULL:2011/12/17(土) 15:09:53.77 ID:6xQtD/Up
下の処理をTRANSACTIONにした場合に、(f)のLinkTableの登録で、
以前はlast_insert_rowid()で取得していたarticleIDとcategoryIDの値が分からず困っています。どうしたら出来ますか?
こういう場合は、AUTOINCREMENTのlast_insert_rowid()をあてにせずに、自分でIDTable.idの値を管理するべきですかね?

insert into IDTable (type) VALUES (0); //(a)articleID登録
insert into ArticleTable (articleID,name,contents) VALUES (last_insert_rowid(),"..",".."); //(b)記事を追加

insert into IDTable (type) VALUES (1); //(c)categoryID登録
insert into CategoryTable (categoryID,name) VALUES (last_insert_rowid(),".."); //(d)カテゴリ追加

insert into IDTable (type) VALUES (2); //(e)LinkTable用のID登録
insert into LinkTable (id,articleID,categoryID) VALUES (last_insert_rowid(),articleID,categoryID); //(f)記事とカテゴリのリンクを追加
337NAME IS NULL:2011/12/17(土) 15:29:51.18 ID:???
case when col1 in (A, B, C, D, E, F) then 1 else 0 end +
case when col2 in (A, B, C, D, E, F) then 1 else 0 end +
case when col3 in (A, B, C, D, E, F) then 1 else 0 end +
case when col4 in (A, B, C, D, E, F) then 1 else 0 end +
case when col5 in (A, B, C, D, E, F) then 1 else 0 end +
case when col6 in (A, B, C, D, E, F) then 1 else 0 end
>= 3
338NAME IS NULL:2011/12/17(土) 15:36:26.77 ID:???
>>336
rowid変えない、変わらない自信があるならいいのかもしれないけど。
シーケンス使ったほうがいいと思うよ。
339NAME IS NULL:2011/12/17(土) 16:06:49.00 ID:???
特定のDBMSの実装にかかわる問題はそのスレで聞けよ
340NAME IS NULL:2011/12/17(土) 16:27:02.89 ID:???
実装に依存しないように書き換えればいいじゃん
341336:2011/12/18(日) 05:32:44.68 ID:???
>>338
参考になりました。ありがとうございます。

自己レスですが、とりあえず以下のようにTEMPORARY TABLE使って処理しました。

CREATE TEMPORARY TABLE IF NOT EXISTS categoryArticle(categoryID INTEGER, articleID INTEGER);
DELETE FROM categoryArticle;
INSERT INTO categoryArticle(categoryID,articleID) VALUES (-1,-1);

insert into IDTable (type) VALUES (0);
UPDATE categoryArticle set articleID=last_insert_rowid();
insert into ArticleTable (articleID,name,contents) VALUES (last_insert_rowid(),"..","..");

insert into IDTable (type) VALUES (1);
UPDATE categoryArticle set categoryID=last_insert_rowid();
insert into CategoryTable (categoryID,name) VALUES (last_insert_rowid(),"..");

insert into IDTable (type) VALUES (2);
insert into LinkTable (id,articleID,categoryID) VALUES (last_insert_rowid(),(select articleID from categoryArticle),(select categoryID from categoryArticle));
DROP TABLE categoryArticle;
342NAME IS NULL:2011/12/19(月) 10:05:41.21 ID:???
http://toro.2ch.net/test/read.cgi/db/1318935267/
ここの大阪弁のおっさん、誰か何とかしてください
343NAME IS NULL:2011/12/19(月) 10:23:12.88 ID:???
http://uni.2ch.net/test/read.cgi/lifeline/1323350614/
ここの大阪弁のおっさん、誰か何とかしてください
344NAME IS NULL:2011/12/19(月) 23:18:14.97 ID:bmyt5mT+
MySQL 5.1 使用しています。

出勤カレンダーを作って、工程表を作りたいのですが、出勤日テーブルに
出勤日テーブルは以下のようにして

T_出勤日

日にち, 出勤
----------------
1月5日  ○
1月6日  ○
1月7日  ×
1月8日  ×
1月9日  ○

「今日」が出勤日(○)として、「今日の前の出勤日からはじめて、
今後の出勤日」を抜き出すSQL文はどう書いたらよいのでしょう?
つまり、「今日」が2番目に来るような抜き出し方です。
一応、考えたのは

(SELECT 日にち FROM T_出勤日 WHERE 出勤='○' AND 日にち<DATE() LIMIT 1)
UNION
(SELECT 日にち FROM T_出勤日 WHERE 出勤='○' AND 日にち>=DATE()
ORDER BY 日にち ASC);

これより簡潔に書けるでしょうか?
345NAME IS NULL:2011/12/19(月) 23:41:12.18 ID:???
select 日にち from T_出勤日 where 出勤 = '○' and 日にち >= (select MAX(日にち) from T_出勤 where 出勤 = '○' and 日にち < date())
たいしてかわらんか。
346NAME IS NULL:2011/12/19(月) 23:59:04.63 ID:bmyt5mT+
なるほど…
LIMIT が使えないDBでもいけそうですね。
ありがとうございます。
347NAME IS NULL:2011/12/20(火) 02:42:15.85 ID:???
>>346
ああ、>>344はLIMITつかってるから、1個目のサブクエリにもORDER BYいるよ
348NAME IS NULL:2011/12/21(水) 22:08:24.22 ID:J0OL2EsB
(質問)
 チェックボックス値による検索を行いたいと思っています。

MYSQL5.1

T1 マスタテーブル
ID | DATE     | DATA
--+----------+-----
1 | 2007-11-11 | aaa
2 | 2007-11-11 | bbb
3 | 2007-11-10 | ccc

T2 チェックボックステーブル1
ID | cate1     |
--+--------- |
1 | 201      |
1 | 202      |
1 | 205      |
2 | 202      |
2 | 203      |
3 | 203      |
3 | 204      |

T3チェックボックステーブル2
ID | cate2     |
--+--------- |
1 | 401      |
1 | 403      |
1 | 404      |
3 | 403      |
3 | 404      |
3 | 405      |

このような3つのテーブルから、下記のように出したいがどうすれば

T2で 201、202、を含み
且つ
T3で 403 を含む 

結果 T1のIDレコード
1 | 2007-11-11 | aaa

試した事
select * from `T1`
join `T2` using(ID)
join `T3` using(ID)
where
cate1 in(201,202)
and cate2 in(403)
group by ID
having count(*)=??

絞るのにカウント数がT1、T2のチェックレコード数で
可変するので詰まっています。
そもそも、考え方がおかしいのかもしれません。
良い方法をご教示ください。
349NAME IS NULL:2011/12/21(水) 23:28:46.47 ID:???
そのまま
having count(*)=2
でいいんじゃないの?
350NAME IS NULL:2011/12/21(水) 23:36:03.12 ID:???
>>348
exists使えば楽
351NAME IS NULL:2011/12/22(木) 11:41:54.44 ID:UVOXMIfK
解決気味です。

上記を諦め、

T1 マスタテーブル
ID | DATE    | DATA |ckbox
--+----------+----- |------
1 | 2007-11-11 | aaa | 201,202,205,401,403,404
2 | 2007-11-11 | bbb | 202,203
3 | 2007-11-10 | ccc | 203,204,403,404,405

上記の形式にして
select ID,DATE,DATA from `T1`
where
CONCAT(',',chkbox,',') like '%,201,%'
and
CONCAT(',',chkbox,',') like '%,202,%'
and
CONCAT(',',chkbox,',') like '%,403,%'

こういった形で取得。

チェックボックスは計300個程ありそれぞれユニークを振っています。
チェックされている数は平均50個程。
レコード数は約1万程なのですがこの方法で大丈夫かどうか心配です。
352NAME IS NULL:2011/12/22(木) 12:06:22.77 ID:UVOXMIfK
>>349
3テーブル分の重複があり2ではありませんでした。
2テーブルであれば送ったINのカンマ割り分だけで
大丈夫だったのですが

>>350
この機会にexists勉強してみます。
見当が付かないですが;;
353NAME IS NULL:2011/12/22(木) 16:57:24.51 ID:???
MySQL 5.1
株価テーブル kabuka
stock_code ←銘柄コード
vol_date ←出来高年月日
sp
hp
lp
cp
vol

銘柄マスタ stock_info
stoc_code ←銘柄コード
shkbn ←商品区分(0,1,2,3,4)
stk_name ← 銘柄名
delete_flg 削除区分
〜その他いろいろな項目

銘柄マスタの商品区分0及び1は除外して銘柄名を付けて株価テーブルから銘柄ごとの最古登録日と最新登録日の一覧を出したい

select a.stock_code,stk_name,shkbn,min(vol_date),max(vol_date)
from kabuka a
inner join stock_info b
on a.stock_code = b.stock_code
where
a.stock_code in
(select b.stock_code from stock_info
where delete_flg=0 and shkbn not in(0,4))
group by a.stock_code
order by shkbn,a.stock_code;

で、上記のSQLを書いてみたんですが、shkbnが0及び4のもでてしまいます
出さないようにするにはどうすればいいのでしょうか?
354NAME IS NULL:2011/12/22(木) 17:39:44.68 ID:???
>>351
existsつかうとこんなん。
select * from T1 where
exists (select * from T2 where T2.ID = T1.ID and T2.cate1 = 201)
and exists (select * from T2 where T2.ID = T1.ID and T2.cate1 = 202)
and exists (select * from T3 where T3.ID = T1.ID and T3.cate1 = 403)
355NAME IS NULL:2011/12/22(木) 17:53:47.11 ID:???
>>353
> where
> a.stock_code in
> (select b.stock_code from stock_info
> where delete_flg=0 and shkbn not in(0,4))
これって
where
b.delete_flg=0 and b.shkbn not in(0,4)
じゃだめなん
356NAME IS NULL:2011/12/22(木) 18:06:30.45 ID:MkKdS3zo
>>355
ありがとうございます!
こういうのは、明示的にしておかないといけないってことなんですかね?
357NAME IS NULL:2011/12/22(木) 20:24:32.15 ID:???
>>356
銘柄テーブルのstock_codeがユニークならそうならない気もするけれど、レイアウトが不明なのでちょっとわからんです
358348:2011/12/22(木) 21:06:34.01 ID:UVOXMIfK
>>354
サブクエリの中で全部行う事が必要かと思っていました。
通常クエリでexistsサブクエリ群をANDで繋げるだけだったのですね!
今後はご教示頂いたSQLコードで作っていきます!。
何か道が開けたような気持ちです。有り難う御座います。
359NAME IS NULL:2011/12/22(木) 21:21:08.99 ID:???
聞いてみようと思ってきたら、答えがよくある質問1でワロタ
360354:2011/12/22(木) 22:36:51.23 ID:???
>>358
やったことないけど、これでも出来そう。

select * from T1 where ID in (
select ID from T2 where cate1 = 201
intersect
select ID from T2 where cate1 = 202
intersect
select ID from T3 where cate2 = 403
)

もしかすると intersect all の方がよいかも。
361NAME IS NULL:2011/12/25(日) 19:46:15.31 ID:???
( ´Д`)y━・~~
362NAME IS NULL:2011/12/25(日) 20:55:41.25 ID:???
>>361
SQLの勉強しにきたん?
363NAME IS NULL:2011/12/25(日) 23:08:49.38 ID:???
>>362
( ´Д`)y━・~~ ?
364NAME IS NULL:2011/12/26(月) 20:28:10.99 ID:???
365NAME IS NULL:2011/12/27(火) 19:24:21.52 ID:P41//Np9
・DB名:Firebird1.03
・テーブル
 ■メイン
  受注番号 受注日 注文社
  11    2011/12/20 A社
  12    2011/12/21 B社
 ■サブ
  連番 受注番号 商品コード 数
  50  11    A10    100
  51  11    C30    20
  52  12    A10    10
 ■商品
  商品コード 商品名 カテゴリ 納品番号(商品ごとで重複していません)
  A10     コート 洋服   100
  C30     帯   和服   504

メインの受注番号とサブの受注番号、サブの商品コードと商品の商品コードで
リンクしています。

欲しい結果
受注日の期間(いつからいつまで)と、商品のカテゴリと納品番号で、
受注の全内容(商品)が知りたいです。
受注日:2011/12/01から12/31まで
カテゴリ:洋服 納品番号:100で検索をして

受注番号 受注日 注文者 商品コード 商品名 数量
11    2011/12/20 A社 A10    コート 100
11    2011/12/20 A社 C30    帯   20----★
12    2011/12/21 B社 A10    コート 10
★受注の全内容が知りたいので、該当する受注番号のサブはすべて表示
したい。メインの内容は重複表示となります。

丸投げですみませんが、どなたかSQL文をお願いできませんでしょうか。
テーブルが3つになるとどうしてよいものかわからないです。
よろしくお願いします。
366NAME IS NULL:2011/12/27(火) 19:47:27.58 ID:???
2つだったらわかるのか?
367NAME IS NULL:2011/12/27(火) 20:00:06.28 ID:???
たしかに、3つになるとわからないって理由で教えちゃまずい気がする
368NAME IS NULL:2011/12/27(火) 22:17:51.63 ID:???
「sql select join 3つ以上」でぐぐると分かるよ。 >>365

例えば
ttp://www.pursue.ne.jp/jouhousyo/SQLDoc/select21.html
このページを落ち着いて全部読めばおk。
369NAME IS NULL:2011/12/27(火) 22:52:38.54 ID:???
括弧でくくったことないかもしれん
370365:2011/12/27(火) 23:43:48.20 ID:P41//Np9
変な言い回しをしてすみません。
2つの場合、サブの商品コードで検索するのであれば
SELECT * FROM メイン M
WHERE M.受注番号 =
(SELECT S.受注番号 FROM サブ S WHERE S.商品コード = ?);
とかで、いけそうに思うのですが・・・。
371NAME IS NULL:2011/12/27(火) 23:46:29.83 ID:???
>>370
2つのテーブルでうまくいってるという表現が誤解を与えたかもしれない。
サブの商品名出せないでしょ
とりあえずjoinを学ぶこと
372365:2011/12/27(火) 23:59:07.97 ID:P41//Np9
>>368
私が勘違いしてるのかもしれませんが、自分の解釈でそのページのやり方
をすると、カテゴリ・納品番号で検索だと、例えば、それぞれ洋服、100
だと、商品コードA10のデータしかでてこなくなります。
A10を含む、受注データを検索したいので、その方法がわかっていません。
>>370で書いたコードだと、速度的にも問題がありそうに思いもっと
スマートな方法があるようにも思っています。
ご指導よろしくお願いします。
373365:2011/12/28(水) 00:08:00.65 ID:NV8y9xjw
>>371
そうですね。サブのデータを引っ張ってないですね。
JOINだと、メインとサブと商品をくっつけても、>>372の例のように
受注番号 受注日 注文者 商品コード 商品名 数量
11    2011/12/20 A社 A10    コート 100
12    2011/12/21 B社 A10    コート 10
しか該当しないんじゃないでしょうか?私は誤解してますでしょうか?
該当する受注番号のデータすべてを抽出したいのですが・・・。
11    2011/12/20 A社 C30    帯   20
のデータも必要なんです。
374NAME IS NULL:2011/12/28(水) 00:22:38.74 ID:???
そんなあなたにはこのサイトがおすすめです
ttp://blogs.itmedia.co.jp/magic/2011/12/6886-2d5b.html
375NAME IS NULL:2011/12/28(水) 00:23:32.81 ID:???
JOINのしかたはわかってるんだ?
じゃあ、あとは>>370のサブをさらに商品.納品番号で絞ればいいんじゃね?
376NAME IS NULL:2011/12/28(水) 02:12:23.27 ID:???
>>373
まっすぐ考えるとこんな感じ。

select 受注番号, 受注日, 注文者, 商品コード, 商品名, 数 as 数量
from ほしい情報があるテーブル
where 受注日 between '2011/12/01' and '2011/12/31'
and 受注番号 in (対象となる受注番号)

ほしい情報があるテーブルを作る
main join sub using (受注番号) join 商品 using (商品コード)

対象となる受注番号は商品コードを元に得られる。
select 受注番号 from サブ where 商品コード in (対象となる商品コード)
 商品コードを得るためには、商品テーブルを見ればよい。
  select 商品コード from 商品 where カテゴリ = '洋服' and 納品番号 = 100
  (納品番号がユニークだということなので、カテゴリで絞り込む意味はないかもしれない)
 商品コードを得たので、組み合わせる。
  select 受注番号 from サブ where 受注番号 in
   (select 商品コード from 商品 where カテゴリ = '洋服' and 納品番号 = 100)

受注番号を得たので、全部組み合わせる。

select 受注番号, 受注日, 注文者, 商品コード, 商品名, 数 as 数量
from main join sub using (受注番号) join 商品 using (商品コード)
where 受注日 between '2011/12/01' and '2011/12/31'
 and 受注番号 in (
  select 受注番号 from サブ where 受注番号 in
   (select 商品コード from 商品 where カテゴリ = '洋服' and 納品番号 = 100)
 )

他にもいろいろ書き方はあるけれど、まずはこれから。
377NAME IS NULL:2011/12/28(水) 02:16:12.89 ID:???
それから、速度的に問題があると思うと書いているけれど、時期尚早。
378NAME IS NULL:2011/12/28(水) 06:40:37.09 ID:???
正解を教えてるフリをして嘘を教える
いやらしいな
379NAME IS NULL:2011/12/29(木) 01:00:28.56 ID:SVpsIQoX
CREATE TABLE `comment` (
`comment_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`entry_id` int(11) unsigned NOT NULL,
`user_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`comment_id`),
KEY `entry_id` (`entry_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

ブログのどの記事(entry_id)にどのユーザー(user_id)がどのコメント(comment_id)を投稿したかを記録するテーブルで、
同じユーザーが同じ記事に複数のコメントを投稿できます。
ここから「コメントを投稿した記事の数」が多い順にユーザーを取得したいのですが、どう書けばいいですか?

SELECT * FROM comment ORDER BY GROUP BY user_id ORDER BY COUNT(DISTINCT(entry_id)) desc

としてみたのですが上手くいっていないみたいで…

よろしくお願いします。
380NAME IS NULL:2011/12/29(木) 03:34:25.01 ID:???
>>378
誤字くらいじゃない?
381NAME IS NULL:2011/12/29(木) 04:09:31.71 ID:???
>>378
それが高専卒IT下請けドカタっちゅうもんやろ( ´Д`)y━・~~
382NAME IS NULL:2011/12/29(木) 20:34:53.79 ID:???
>>379
いらんとこにORDER BYがあるのは置いといて

GROUP BYするSELECTに*は使えないのが普通
グループしてる項目か集計関数つかえ。この場合はuser_idだな
383365:2011/12/29(木) 22:43:38.47 ID:MUHtF/FL
>>376
考え方はわかります。370の延長なので。
typo修正すれば動作します。378,381のような知ったかぶりは気にしないでください。
ありがとうございました。
速度は時期尚早とのコメントもいただきましたが
実際は、360万件の受注データで実行すると、数分かかります。
(5件くらいのデータなら即答します。)
WEBからの利用なのでタイムアウトの可能性がでてきます。
利用DBでは、usingは使えないのでonで書き換えましたけれど。
他の書き方はとはどんなものなのでしょうか。

私の質問の仕方が良くなかったせいか、JOINについてのアドバイスをいただいて
いますが、JOINの使い方程度はわかっています。(WHERE =だと複数が通らない
のを忘れていたのは凡ミスでした。反省。)
384NAME IS NULL:2011/12/29(木) 23:01:08.64 ID:???
>>383
まずは納品番号にインデックスをはる。
カテゴリを抽出条件に使う必要があるのなら、それも考慮する。
で、クエリプランを見る。
385365:2011/12/30(金) 09:43:06.53 ID:???
>>384
納品番号・カテゴリのあるアイテムテーブルは即答するのでどうなんでしょう。
恐らく、ネックになっているのは、
受注番号のサブクエリからの検索と、
どうも一番最後に日付の検索をしているところだと思うのですが
具体的にどうすればいいのか検討がつかないです。
386NAME IS NULL:2011/12/30(金) 13:40:59.25 ID:???
>>385
おそらくじゃなく、プランを見る
日付にインデックスをはる
387NAME IS NULL:2011/12/30(金) 13:42:19.75 ID:???
Firebirdでインデックスのマージが行われるかどうかは知らないので、その辺は適宜がんばれ
388365:2011/12/30(金) 15:53:48.84 ID:???
>>386
クエリプランを見るとは具体的にどうすることでしょうか?
各クエリ毎に分割して感覚として掴んでいるのですが・・・。
日付のインデックスは別のパフォーマンスが落ちるので残念ならが付けられません。
(トランザクションの日付データってインデックス張らないと思うんですが)
>>387
私も解りませんが、結合している項目はすべてインデックスがあるので
その辺りは余地があまりないかと。

WHERE XXX IN (subQuery)のパフォーマンスがこんなに悪いとは・・・。
バージョンが古いのもあるんでしょうね。
389NAME IS NULL:2011/12/30(金) 16:23:51.44 ID:???
>>388
inがおそいDBはexistsに置き換えたほうがはやい場合も。昔のPostgreSQLもそうだった。
でもプランを見ないことには話にならない。
統計情報が更新されていないのかもしれないし、オプティマイザに対してヒントを与えるべきかどうかも判断できない。

firebirdよくしらないけど、こういうのでてきたよ。
http://blog.kimuradb.com/?eid=877186

時期尚早だといったのは、目的のデータを抽出できない段階で速度云々言ってることに対して。

> 日付のインデックスは別のパフォーマンスが落ちるので残念ならが付けられません。
> (トランザクションの日付データってインデックス張らないと思うんですが)
やってみてから言おうよ。
390NAME IS NULL:2011/12/30(金) 16:25:40.19 ID:???
それから、DBMS固有の話に突っ込んでいくなら専用スレで。

Firebird関連スレ3
http://toro.2ch.net/test/read.cgi/db/1234314631/
391NAME IS NULL:2011/12/30(金) 16:33:21.35 ID:???
すんません、質問です。
高専卒IT下請けドカタの方いらっしゃいますぅ〜?( ´Д`)y━・~~
392NAME IS NULL:2011/12/30(金) 16:37:05.79 ID:???
おっさんは回答もしなければ質問もしない、何のためにスレにくるんだ
393NAME IS NULL:2011/12/30(金) 16:40:17.09 ID:???
>>392
いま質問しとるやんけ(爆笑)

ちなみにマジで疑問に思っとるんやけど、ホンマどうして高専卒とか専門卒のドカタどもはプライド高いん?

ホンマにこれには答えて欲しい
394NAME IS NULL:2011/12/30(金) 16:40:38.84 ID:???
そりゃスレ違い
395NAME IS NULL:2011/12/30(金) 19:11:15.06 ID:???
あんたら意地悪やなぁ。
365とか370みたいなんにわざわざサブクエリなんて要らん、単純なjoinだけでええ
ということを誰も言うてやらんやなんて。

>>365みたいな丸投げ希望に応じてやる気は無しで、
自分で学んで考えろ方針はええとして、それなら最低でもサブクエリみたいな
(今回の場合は)馬鹿げたとこ迷い込んでるのは指摘したらんと。

とりあえず>>370なんか

SELECT tm.受注番号, .... , ts.商品コード, ...
FROM
 メイン tm,
 サブ ts
WHERE
 ts.商品コード = 検索したいコード
 AND ts.受注番号 = tm.受注番号

これでええんちゃうの?
396NAME IS NULL:2011/12/30(金) 19:42:38.45 ID:???
その指摘は一周遅れてる
397NAME IS NULL:2011/12/30(金) 21:00:50.34 ID:???
正解を教えてるフリをして嘘を教える
いやらしいな
398365:2011/12/31(土) 10:13:27.83 ID:???
>>395
それだと、一つの商品しか検索できないんじゃ・・・。
あまりいいたくはないんですが、要件を理解されていますか。
私の質問が言葉足らずだったり、誤解が生じるものだとしても、
本質を理解いただけないのは、私の能力不足だけではないと思います。
399365:2011/12/31(土) 10:20:46.26 ID:???
>>389
firebirdについて調べてくれてありがとう。お手間を取らせました。
そっち方面は調べてみます。
ところで、existsってレコードが存在する、しないくらいしか使ったことが
ないのですが、inを置き換えるというのはどうするのでしょうか。
・・・日付の件は、受注データの登録・更新作業のプログラムで
速度が遅くなるという判断がなされたので不可なのです。
400NAME IS NULL:2011/12/31(土) 11:12:35.38 ID:???
365の要件だとどんな書き方をしても
 select * from main where 受注日 between '2011/12/01' and '2011/12/31'
というクエリ単体の速度を超えることはないだろう

このクエリの速度でなんとか我慢できるなら
そこを先にやれば全体としてもどうにか我慢できる速度にはなるかもしれない

select 受注番号, 受注日, 注文者, 商品コード, 商品名, 数 as 数量
from (select * from main where 受注日 between '2011/12/01' and '2011/12/31')
   join sub using (受注番号)
   join 商品 using (商品コード)
where 受注番号 in (
  select 受注番号 from サブ where 受注番号 in
   (select 商品コード from 商品 where カテゴリ = '洋服' and 納品番号 = 100)
 )
401NAME IS NULL:2011/12/31(土) 11:36:42.77 ID:???
いや、納品番号のカーディナリティがメインに対して比較的高ければ
メインのfull scanは必要ない可能性もあるよ。
Firebirdのプランナがどのくらい賢いかはわからんけど。
402NAME IS NULL:2011/12/31(土) 11:51:03.91 ID:???
特定の商品カテゴリが特定の期間にしか売れないとか、
商品カテゴリが大量にあるとかならそれもありえるかもしれんけど、
いずれの場合でも指定する商品カテゴリによって
処理速度がかなり左右されることになるだろうねえ
403NAME IS NULL:2011/12/31(土) 20:47:19.60 ID:1ddnDqlq
mysql Ver 14.14 Distrib 5.5.8, for Win32 (x86)
mysql> insert question_tb (question_id,purchase_date,purchase_price,star) values
(1,2011/11/10,1000,4);
と購入日2011/11/10と入力すると、購入日が 18.2818181となってしまいます。
phpでやると2011/11/22のように登録されます。/の記号がダメなのでしょうか?
404NAME IS NULL:2011/12/31(土) 21:22:08.38 ID:???
>>403
insert question_tb (question_id,purchase_date,purchase_price,star) values(1,'2011-11-10',1000,4);
405NAME IS NULL:2011/12/31(土) 21:24:02.10 ID:???
>>403
それだと、2011を11で割って、さらに10で割った答えを入れてしまってる。
'2011/11/10' みたいにシングルクオートで囲むべし。
406NAME IS NULL:2011/12/31(土) 21:31:34.01 ID:1ddnDqlq
>>404
>>405
ありがとうございました。/で割り算になってたんですね。
全く気づきませんでした。うまくいきました。
407NAME IS NULL:2011/12/31(土) 22:06:02.20 ID:1ddnDqlq
mysql Ver 14.14 Distrib 5.5.8, for Win32 (x86)
masql> create table question_tb
>(question_id int(4) primary key auto_increment,
中略,
);
において、question_id=1〜10を持つデータを登録した場合。
mysql> delete from question_tb where question_id=〜;
で1〜10のデータを消し、
mysql> insert question_tb (purchase_date,purchase_price,star) values('2011/11/10',2900,5);
question_id=1〜10がないにもかかわらず、question_id=11から登録します。
primary key auto_incrementで登録したid=1〜10という情報を消すことは
可能ですか?
登録したデータを全て消した場合
mysql> insert question_tb (purchase_date,purchase_price,star) values('2011/11/10',2900,5);
でquestion_id=1から登録することは可能ですか?






408NAME IS NULL:2011/12/31(土) 22:15:43.62 ID:???
>>407
そういうのは、

【MySQL】下らねぇ質問はID出して書き込みやがれ 2
http://toro.2ch.net/test/read.cgi/db/1322402682/

こっちじゃないかな。

とりあえずその状況設定のように、テーブルが空っぽであるなら、
auto_incrementをもう一度1から始めるのは可能。
ttp://www.programming-magic.com/20071126231401/
409NAME IS NULL:2012/01/01(日) 00:19:04.86 ID:+bqRnP5t
>>408
あいがとうございました。
410NAME IS NULL:2012/01/03(火) 02:29:18.91 ID:???
>>395
それでええとおもうのか…
411NAME IS NULL:2012/01/05(木) 05:14:08.00 ID:0uRuYpTO
質問です。DBはSQLite3です。
構成が同じなので>>244のテーブルを説明に使わせてもらいます

北海道なら、Bカンパニー・Cカンパニー
青森なら、無し
岩手なら、Bカンパニー
秋田なら、Aカンパニー・Cカンパニー
北海道・秋田なら、Cカンパニー

除外検索の要領で、対象の支社が無い会社を呼び出したい時はどうすればよいのでしょうか
412NAME IS NULL:2012/01/05(木) 11:57:29.38 ID:???
not exists
413NAME IS NULL:2012/01/05(木) 16:02:47.22 ID:???
NoSQL系のスレが見つからなかったのでここで質問させてもらいます
初心者的な質問なのですが、3台のサーバがあって、サーバAがサーバB又はサーバCのmemcachedに何かリストを書き加え、それをサーバBが利用するというような、機器間の連携は出来るのでしょうか?

もし出来るとした場合、ネットワークを通じることになるので、やや速度的には落ちるのでしょうか?
宜しくお願いします
414NAME IS NULL:2012/01/05(木) 16:51:19.20 ID:???
NoSQLがこのスレと何の関係があるの?
415NAME IS NULL:2012/01/05(木) 22:34:28.95 ID:???
もっとも関係ないスレに、思想の根底近辺にある内容を聞くとかどうかしてるわ
適当にぐぐれよ
416NAME IS NULL:2012/01/10(火) 14:40:12.23 ID:i/UShvc5
DB:SQL SERVER 7.0、クエリアナライザー

DBのレコードが膨大なのでTOPで範囲を区切ってレコードを削除したいのですが、
DELETEの時にエラーが出てしまいます。何かミスしてしまっているのでしょうか?

SELECT TOP (10) * FROM table_name WHERE field LIKE '2006%' → OK
DELETE TOP (10) FROM table_name WHERE field LIKE '2006%' → NG
417NAME IS NULL:2012/01/10(火) 19:15:52.91 ID:???
バージョンが古いからじゃね?

delete from table_name where key in (select top (10) key from table_name where field like '2006%')
だといけるのかね?
418NAME IS NULL:2012/01/10(火) 20:02:36.88 ID:???
>>417
とりあえずテスト環境作って
最新版のSQL Serverでdelete top出来るか確認してみます。

主キーが複数あるテーブルなので
inでのやり方がうまく書けない(汗
419NAME IS NULL:2012/01/10(火) 20:21:49.37 ID:???
7.0とか古すぎてわからんな
420NAME IS NULL:2012/01/10(火) 21:21:38.43 ID:???
>>418
じゃあexistsは?
421NAME IS NULL:2012/01/11(水) 19:17:24.72 ID:???
order by書かないTOPとか恐ろしくて使う気しないが
何順で消したいんだ

普通に項目で範囲指定すれば良いだけだと思うんだがな
'200601%'けして'200602%'けして....で行けるんじゃねえのか
そもそも何のエラーでてるんだよ?
422NAME IS NULL:2012/01/11(水) 20:24:54.86 ID:???
最終的には全部消したいけど、なんとなく不安だから小分けにしてるって感じ
423NAME IS NULL:2012/01/11(水) 23:12:52.10 ID:???
ヽ(・ω・)/ズコー
DBのりかえろよもう!
424422:2012/01/11(水) 23:23:37.88 ID:???
あああ、本人(>>416)じゃないよ!
なんとなくそんな気がしたっていうだけ。

ますますズコーってなりそうですまん
425NAME IS NULL:2012/01/12(木) 00:12:33.27 ID:???
truncateしろよ
426NAME IS NULL:2012/01/12(木) 00:26:14.60 ID:???
全部は消したくないんだろうよ
427NAME IS NULL:2012/01/12(木) 00:27:23.29 ID:???
like '2006%' に該当するのが500万件ぐらいあって、
一括で削除しようとすると時間がかかって不安だからちょっとずつ消してみよう!
というわけのわからないアレ。
428NAME IS NULL:2012/01/12(木) 00:28:14.41 ID:???
とおもったけど、ごくまれにそうせざるを得ない場面があるかもしれんなぁと思ったりした、が、きっと当てはまらないだろう
429NAME IS NULL:2012/01/12(木) 00:31:03.41 ID:???
条件が日付だけだったら
like '200601%'
みたいな感じでいいんでね
430NAME IS NULL:2012/01/12(木) 00:35:33.08 ID:???
DELETEに時間がかかってロック待ちが大量に発生するのを避けたい、
というのはあるかもしれない。
431NAME IS NULL:2012/01/12(木) 00:38:03.08 ID:???
ロックエスカレーションか
メンテ時間にやれば。
432NAME IS NULL:2012/01/16(月) 21:16:04.70 ID:???
条件が日付ではないものだとして,
ROWNUMで消したいデータ数をしていすればいいんじゃないかな
DELETE FROM table_name WHERE ROWNUM <= 10
もし条件が日付だけなら>>421>>429にすべきと思う
433NAME IS NULL:2012/01/17(火) 00:54:21.55 ID:???
それオラクルや
434NAME IS NULL:2012/01/17(火) 16:22:50.85 ID:???
ROWNUMってオラクル限定なの?
435NAME IS NULL:2012/01/17(火) 16:28:54.69 ID:???
>>434
うん
436NAME IS NULL:2012/01/18(水) 18:20:42.62 ID:???
mysql 5.1.44

table datatbl
inputdate
data1
data2
data3

で月単位でまとめるときは
GROUP BY DATE_FORMAT(日時, '%Y%m')
で出せますけど、週間単位の時はどうするんでしょうか?
437436:2012/01/18(水) 18:29:35.50 ID:???
日時→inpudate でした
438NAME IS NULL:2012/01/18(水) 18:40:26.28 ID:???
439NAME IS NULL:2012/01/18(水) 18:43:24.20 ID:???
WEEKOFYEARが気楽かも
440NAME IS NULL:2012/01/18(水) 19:16:42.00 ID:???
ありがとうございます '%Y%u'で出来ました。
441NAME IS NULL:2012/01/18(水) 21:03:50.93 ID:HEQZTiH1
データベース内の複数のテーブル(テーブルAAA,テーブルBBB)から
データを取得することはできますか。
AAAの中には1,2,3、BBBにはa,b,cというデータが入っていて
select * from AAA;、select * from BBB;とやれば両方のデータを表示
させることはできますが、それを一文で行いたいです。
442NAME IS NULL:2012/01/18(水) 21:16:52.14 ID:???
とりあえず、初心者向けのSQLの本を読め
443NAME IS NULL:2012/01/18(水) 21:19:42.70 ID:???
できなかったらリレーションしてないww
444NAME IS NULL:2012/01/18(水) 21:24:44.43 ID:HEQZTiH1
select * from AAA,BBBでいいんぢゃない?
445NAME IS NULL:2012/01/18(水) 22:25:15.07 ID:???
ああ、ちゃんとこっちに来たのか、と思ったら何この自演
446NAME IS NULL:2012/01/18(水) 23:31:30.27 ID:???
二行でいいぢゃん。
どうしても一行にしたいちゃんとした理由があるんならそれを説明しろ。
447NAME IS NULL:2012/01/19(木) 03:24:03.20 ID:???
つかunionしたいってことじゃ?
448NAME IS NULL:2012/01/21(土) 00:29:50.26 ID:???
よくselect文でDUALって見かけますがこれは何ですか?
449NAME IS NULL:2012/01/21(土) 01:11:08.67 ID:???
ORACLEの仮想表です。とくに意味はありません。
450NAME IS NULL:2012/01/21(土) 21:16:01.74 ID:???
データセット
date
2001-10-19
2001-10-19
2003-12-7
2004-9-7
....

といったidと日付の集まりがあります。日付は重複しています。
ここから,SELECT count(date) FROM table GROUP BY dateで日付ごとの集計がとれたのですが、さらにmaxを使って集計が最大の日の日付とカウント数を出したいのですがうまくいきません。
上の例では、2001-10-19,2というのを取りたいのですが、どうやったらいいんでしょうか?
451NAME IS NULL:2012/01/21(土) 22:02:36.65 ID:???
まあ王道で行けばこうだよなあ
select A.date, A.cnt
from (select date, count(date) cnt from table group by date) A
   inner join
   (select max(cnt) max_cnt from (select count(date) cnt from table group by date)) B
   on A.cnt = B.max_cnt
;

limitが使えるDBMSならこんなんでも
select date, count(*) cnt from table group by date order by cnt desc limit 1;

どっちにしてもcountが最大の日付が複数あるときどうするか考えとかないとね
452NAME IS NULL:2012/01/21(土) 22:49:43.82 ID:???
ありがとうございます!

まだ呪文が長すぎて理解しきれませんが、希望通り動きました

最大値が二件以上の場合も考えておく必要がありますね
前者はすべて抽出し後者はidの若いもの一件がでてくるのでしょうね
order by date desc limit 1 を全体につけときます
453NAME IS NULL:2012/01/22(日) 10:19:20.67 ID:???
>>452
>前者はすべて抽出し後者はidの若いもの一件がでてくるのでしょうね

>>450 の時から思っていたんだが、id ってなんのことだ?
454NAME IS NULL:2012/01/22(日) 15:52:33.87 ID:???
質問するときにDBMSを明記しないやつが多くてこまる
455NAME IS NULL:2012/01/23(月) 15:09:25.68 ID:???
>>453
ただの連番だと思うよ
456NAME IS NULL:2012/01/24(火) 15:54:49.71 ID:???
テーブル メニュー
メニュー番号, メニュー
1 ステーキ
2 ハンバーガー
3 ビーフシチュー

テーブル 注文
社員番号,名前,第1希望,第2希望,第3希望
1 鈴木 3 1 2
2 川本 1 2 3
3 山田 1 3 2

ここから
1 鈴木 ビーフシチュー ステーキ ハンバーガー
と出力するにはどうすればいいでしょうか。

第1希望だけなら where メニュー.メニュー番号=注文.第1希望
で出るのですが。
457456:2012/01/24(火) 15:55:40.46 ID:+XGx9Ps2
>>456
DBMSはMySQL 5.0です。よろしくお願いします。
458NAME IS NULL:2012/01/24(火) 16:28:05.44 ID:???
SELECT 社員番号,名前,menu1.メニュー,menu2.メニュー,menu3.メニュー
FROM 注文
JOIN メニュー AS menu1 ON (注文.第1希望=menu1.メニュー番号)
JOIN メニュー AS menu2 ON (注文.第2希望=menu2.メニュー番号)
JOIN メニュー AS menu3 ON (注文.第3希望=menu3.メニュー番号)

こんな感じ?
459456:2012/01/24(火) 16:36:36.54 ID:+XGx9Ps2
>>458
個別にJOINするんですね。
ありがとうございました。精進します。
460NAME IS NULL:2012/01/24(火) 16:37:08.57 ID:???
なるほど!
461NAME IS NULL:2012/01/24(火) 17:32:04.45 ID:???
>>458
ON (... OR ... OR ...) でよくね?
462NAME IS NULL:2012/01/24(火) 17:50:24.47 ID:???
>>461
じゃあそれで動くSQLをどうぞ。

ちなみに

SELECT 社員番号,名前
,(select メニュー from メニュー where メニュー番号 = 第1希望)
,(select メニュー from メニュー where メニュー番号 = 第2希望)
,(select メニュー from メニュー where メニュー番号 = 第3希望)
FROM 注文

でもできる
463456:2012/01/24(火) 18:40:36.90 ID:+XGx9Ps2
>>458
これでできました!
ASでmenu1, menu2, menu3に分けるところがミソなんですね。
ありがとうございます。
464NAME IS NULL:2012/01/25(水) 11:21:33.36 ID:???
DBMSはMySQL 5.0です。

テーブル 合否
社員番号,結果,エラーコード
1,合格,0
2,合格,0
1,合格,1
1,不合格,0
3,合格,0
2,合格,0
2,不合格,1

こういうテーブルがあります。
社員は一人で複数回受験できて、合格か不合格の結果を記録します。
但し、特定の条件だとエラーになって結果は出るけどエラーコードに1がつきます。

(1)エラーコードが0のものの、合格と不合格の件数が知りたいとき
SELECT 結果,COUNT(結果) FROM 合否 WHERE エラーコード=0 GROUP BY 結果

結果
合格,4
不合格,1

(2)エラーコードにかかわらず、合格と不合格の件数が知りたいとき
SELECT 結果,COUNT(結果) FROM 合否 GROUP BY 結果

結果
合格,5
不合格,2

そこで、
(1)と(2)を同じ表に出力したいときはどう書けばいいでしょうか。
このような表になればいいです。よろしくお願いします。
合格,4,5
不合格,1,2
465NAME IS NULL:2012/01/25(水) 13:03:50.88 ID:???
その二つをjoinすればいいかと
466NAME IS NULL:2012/01/25(水) 13:32:35.44 ID:???
union allでしょ
467NAME IS NULL:2012/01/25(水) 14:18:50.98 ID:???
>>466
union all だと縦につながりました。
合格,4
不合格,1
合格,5
不合格,2

>>465
どういう風にjoinを使えばいいでしょう?
468NAME IS NULL:2012/01/25(水) 14:55:13.96 ID:???
>>467
単に結果列で結合すればいいだけじゃないからそう聞いているのか、結合を知らないだけなのかがわからない
469NAME IS NULL:2012/01/25(水) 15:14:18.65 ID:???
>>468
一応結合は知ってるのでたまに使うんですが、
selectの結果同士の結合はやったことがありません。
470NAME IS NULL:2012/01/25(水) 15:51:05.05 ID:???
サブクエリの結果はテーブルと同じように扱えるよ
471NAME IS NULL:2012/01/26(木) 11:50:30.61 ID:???
>>470
ありがとうございます。
こんなのを書いてみましたが、思うような数字が出てきません。
SELECTを2つJOINするのはうまく出ませんでした。

SELECT a.結果,COUNT(a.結果),cb FROM 合否 AS a
JOIN (SELECT 結果,COUNT(結果) AS cb FROM 合否 GROUP BY 結果) AS b
WHERE a.結果 = b.結果 AND エラーコード=0 GROUP BY 結果

>>462 みたいなのはサブクエリの結果が複数行だと出ないみたいですね。
472NAME IS NULL:2012/01/26(木) 12:39:46.55 ID:???
>>471
二つをjoinすればいいっていうのはこういうこと。
select 〜 from
(select 〜 ) join (select 〜 )

>>462のはそう。複数行だったときに出力しようがないからね。
473NAME IS NULL:2012/01/26(木) 12:50:13.67 ID:49RPcyCy
DBはMysql5です

記事 entry user_id , blog_id , title ,body
ユーザー user status
友人 friend send_user_id , get_user_id(sendが自分で、getが他人)

があるとして
user.statusが管理者の時は無条件で記事を表示
それ以外は友人と、自分の記事のみ表示
という状況を考えてます

SELECT * from ( ( entry join user on entry.user_id = user.id ) join friend on user.id = friend.get_user_id )
where user.id = "自分のID" OR user.status = "管理者" OR friend.send_user_id = "自分のID"

これでいけるかと思ったのですが、同じ記事が20個も30個も表示されてしまいます
どのように書けばいいでしょうか?よろしくおねがいします……
474NAME IS NULL:2012/01/26(木) 13:34:59.97 ID:???
friendの数だけ出てるんじゃないのかな。
where existsにかえるとか。
あと、そのwhere句なんかあやしい
475NAME IS NULL:2012/01/26(木) 19:00:39.98 ID:???
>>473
user user_id status
の間違いではないのだろうか。
476NAME IS NULL:2012/01/26(木) 22:03:57.96 ID:???
>>475
user id status の間違いだと思うよ。
user.idってかいてるから。
477NAME IS NULL:2012/01/26(木) 22:25:07.14 ID:???
>>476
そうですね。
478NAME IS NULL:2012/01/27(金) 23:28:35.46 ID:???
mysql 5.5.?

株式の出来高テーブルがあります

code,vdate,startingprice,highprice,lowprice,closingprice,volume

一定の期間中の4本値(例えば月次、週次)を取得したい時、高値、安値は

select max(highprice) as takane, min(lowprice) from kabukatbl
where code= xxxx and vdate between 'yyyy-mm-dd' and 'xxxx-zz-bb';

で取得できますけど、一気にその期間の最初の日のstartingprice,
その期間の最後の日のclosingpriceを取得することは出来ないでしょうか?

(この際、出来高 volumeは無視で)
479NAME IS NULL:2012/01/28(土) 00:02:06.47 ID:???
max(case vdate when min(vdate) then startingprice else startingprice+1 end)
でできそうな気はする。
480NAME IS NULL:2012/01/28(土) 00:02:55.62 ID:???
max(case vdate when min(vdate) then startingprice else startingprice-1 end)
の間違い
481478:2012/01/28(土) 09:20:31.91 ID:???
>>479,480
ありがとうございます。ただ文法エラーになってしまいました。
そこで自分なりに書き換えてみたんですが、

select
case (vdate) when min(vdate) then startingprice
end as hajimene,
max(highprice) as takane,
min(lowprice) as yasune,
case (vdate) when max(vdate) then closingprice
end as owarine
from kabukatbl
where stock_code= 998407 and vol_date between '2011-12-26' and '2011-12-30';

owarineだけが何故かNULLになってしまいます。(上記の例は日経平均です)

+----------+---------+---------+---------+
| hajimene | takane | yasune | owarine |
+----------+---------+---------+---------+
| 8504.46 | 8516.53 | 8330.87 | NULL |
+----------+---------+---------+---------+

case (vdate) when max(vdate) then closingprice
end as owarine
ここの部分を単独でやってみてもNULLになってしまうのですが、hajimeneは出来て、なぜowarineではだめなんでしょうか?
482478:2012/01/28(土) 09:24:51.83 ID:???
vol_date は vdate、 stock_codeは codeに置き換えてください
すいません
483NAME IS NULL:2012/01/28(土) 23:31:10.44 ID:???
単純に1個1個取得していったらどう?試してないけどこんな具合に

select
 初日.startingprice as 始値,
 最終日.endingprice as 終値,
 通算.highprice as 高値,
 通算.lowprice as 低値
from
 (select max(highprice) as highprice, min(lowprice) as lowprice from kabukatbl where code= xxxx and vdate between 'yyyy-mm-dd' and 'xxxx-zz-bb')) as 通算,
 (select startingprice from kabukatbl where vdate = (select min(vdate) from kabukatbl where code= xxxx and vdate between 'yyyy-mm-dd' and 'xxxx-zz-bb')) as 初日,
 (select endingprice from kabukatbl where vdate = (select max(vdate) from kabukatbl where code= xxxx and vdate between 'yyyy-mm-dd' and 'xxxx-zz-bb')) as 最終日
484NAME IS NULL:2012/01/29(日) 01:27:05.60 ID:???
>>481
owarineが取れないと言うより、hajimeneが取れたのもたまたまだな。他のデータベースだとエラーになる。

SELECT
(SELECT startingprice FROM kabukatbl WHERE vdate=T1.startingdate) AS hajimene,
takane,
yasune,
(SELECT closingprice FROM kabukatbl WHERE vdate=T1.closingdate) AS owarine
FROM
(SELECT min(vdate) AS startingdate , max(highprice) AS takane , min(lowprice) AS yasune , max(vdate) AS closingdate FROM kabukatbl
WHERE code=998407 AND vdate between '2011-12-26' AND '2011-12-30') AS T1

やっていることは>>483さんとほぼ同じだけど、WHERE句が1箇所で済むってことで。
485NAME IS NULL:2012/01/29(日) 01:31:22.31 ID:???
間違えた
SELECT
(SELECT startingprice FROM kabukatbl WHERE code=T1.code AND vdate=T1.startingdate) AS hajimene,
takane,
yasune,
(SELECT closingprice FROM kabukatbl WHERE code=T1.code AND vdate=T1.closingdate) AS owarine
FROM
(SELECT min(code) AS code , min(vdate) AS startingdate , max(highprice) AS takane , min(lowprice) AS yasune , max(vdate) AS closingdate FROM kabukatbl
WHERE code=998407 AND vdate between '2011-12-26' AND '2011-12-30') AS T1

サブクエリのWHERE句にcodeが抜けてたが、それを引っ張るためのmin(code)は面白くない。
486478:2012/01/29(日) 06:51:59.61 ID:???
むっ難しいぃ w

>>483,484
たまたま取れたというだけだったんですか。
484氏のやり方で出来ました。

483氏の方法はエラーが出るんでまた少し勉強してみます

ご教授していただき本当にありがとうございました。
487NAME IS NULL:2012/01/29(日) 22:16:56.23 ID:???
質問です。
ORACLE 11gです。
SQL Plus上では、以下の文が実行できてしまいます。
UPDATE エーテーブル AT
SET (
AT.20計,
AT.30計
)
= (
SELECT SUM(DECODE(MT.集計用コード, '20' , BT.本数,0)),
SUM(DECODE(MT.集計用コード, '30' , BT.本数,0))
FROM ビーテストテーブル BT,
マスタ MT
WHERE BT.コード
= AT.コード
AND BT.番号
= AT.番号
AND BT.サイズコード
= MT.サイズコード
)
WHERE AT.コード
= 'LNL'
AND AT.番号
= '0101278' ;
良くわからないのが、サブクエリ内でなぜエーテーブルの別名AT
が使用できるのかという事です。
(というかFROMに書いていないエーテーブルが参照?出来るのかです)
どうしてなのでしょうか?
488NAME IS NULL:2012/01/29(日) 23:34:31.43 ID:???
相関サブクエリでぐぐれ

まあ本来なら(SQL標準としては)UPDATE対象テーブルに
相関名は指定できないはずなんだけど
489NAME IS NULL:2012/01/30(月) 22:17:41.63 ID:???
MySQLです

Year | Month
------------
2012 | 1
2012 | 2
2012 | 3
2012 | 4
 〜 略 〜
2012 | 10
2012 | 11
2012 | 12

の様なテーブルから「年度」を取得したいです。
この場合は2011と2012を取得するにはどんなSQLを書けばよいでしょう?
IF文とか書く必要があるのであればプロシージャ作るのもOKです。
490NAME IS NULL:2012/01/30(月) 22:24:14.55 ID:???
select distinct Year
from テーブル名;
491NAME IS NULL:2012/01/30(月) 22:34:40.41 ID:???
実機ないからテストできないが、これでイケるんじゃね?

SELECT year + (CASE WHEN month <=3 THEN -1 ELSE 0 END) AS nendo, year, month FROM table_name;
492NAME IS NULL:2012/01/30(月) 23:11:03.90 ID:???
ああ、年度ってそういうことね
493NAME IS NULL:2012/02/01(水) 13:20:56.00 ID:MbnB8W1W
SQLでの検索について教えてください
あるテーブルAに日付時刻といろいろなデータを格納します。
データを検索するときに日付時刻で検索しますが
テーブル構造をどのようにするのが普通ですか?
たとえば2012年1月12日13時5分〜2012年2月11日11時16分までのデータを検索するときに
テーブル構造が以下のようになってるとどういうSQL文になるんでしょうか?

<テーブル構造:Oracle>
Year Number(10), Month Number(10), Day Number(10), Hour Number(10), Minute Number(10),...

これだと検索できないですよね?

Select * from テーブルA Where _
Year >= 12 AND Year <= 12 AND _
Month >= 1 AND Month <= 2 AND _
Day >= 12 AND Day <= 11 AND _
Hour >= 13 AND Hour <= 11 AND _
Minute >= 5 AND Minute <= 16 ;
494NAME IS NULL:2012/02/01(水) 13:33:00.22 ID:???
date型にすればいい
495NAME IS NULL:2012/02/01(水) 15:50:48.50 ID:???
YYYYMMDDの文字列とHHMMSSの文字列
496493:2012/02/01(水) 15:57:00.10 ID:MbnB8W1W
色々情報ありがとう
なんとなくわかってきました
497NAME IS NULL:2012/02/05(日) 01:53:34.14 ID:79atCtq1
select文でデータ取得する場合はどちらが早いんですか?

(a)2つのテーブルをJoinして条件指定してデータを取得する
(b)1つずつテーブル取得してメモリ上でJoinの条件指定する
498NAME IS NULL:2012/02/05(日) 02:36:01.49 ID:???
メモリ上でJoinの条件指定するってのがよくわからんが
一般的にDBMSの速度はどういう指定をしたかではなく、
どういう風にデータを取得したかによる
指定した通りにデータを取得するとは限らない

実際にデータを取得する方法を実行計画っていうんだが
どっちが早いか比べるなら実行計画比べないとダメ
499NAME IS NULL:2012/02/05(日) 02:40:57.47 ID:???
>>498
>メモリ上でJoinの条件指定するってのがよくわからんが
アプリ側でフィルタとマージするって事だろう
同じ事をDBMSがメモリとCPUを浪費しないように苦労してるんだけどね〜
500NAME IS NULL:2012/02/05(日) 04:13:16.47 ID:???
一旦全部キャッシュに載せるっていみじゃね?
そらそっちが早いよ。
だが苦肉の策だからよくわからんならやっちゃダメ。
501NAME IS NULL:2012/02/05(日) 04:19:49.37 ID:???
とりあえずメモリ128MB載せる。
そのうち96MBぐらいをバッファプールに割りあてる。

これが大人のやり方だw
502NAME IS NULL:2012/02/05(日) 12:19:04.18 ID:???
大人っていうかジジイ。
503NAME IS NULL:2012/02/05(日) 12:33:02.77 ID:???
あんだと小便小僧が
まだアラフォーだぞ
もう爺かよ!
出てこい( ゜Д゜)オラ
504NAME IS NULL:2012/02/05(日) 12:33:38.75 ID:???
やっぱ
爺でいいや。
505NAME IS NULL:2012/02/05(日) 16:10:39.49 ID:???
>>503
アラフォーって孫がいる可能性も十分ありえる年齢
506NAME IS NULL:2012/02/05(日) 17:27:30.58 ID:???
ていうかいまどきメモリ128MBでDBサーバとか
507NAME IS NULL:2012/02/10(金) 01:41:14.58 ID:???
DELETE FROM seihin WHERE buhin1Id NOT IN (SELECT id FROM buhin)
DELETE FROM seihin WHERE buhin2Id NOT IN (SELECT id FROM buhin)

↓1行にまとめてみたら

DELETE FROM seihin WHERE (buhin1Id OR buhin2Id) NOT IN (SELECT id FROM buhin)

うごかん。なんで?
508NAME IS NULL:2012/02/10(金) 02:32:50.41 ID:???
SQLではどうかわからんけど普通のプログラム言語の感覚では
(buhin1Id OR buhin2Id) のOR演算が優先されると思う
であれば期待する結果にならないのは当然かと。
素直にというか単純に

DELETE FROM seihin WHERE (buhin1Id NOT IN (SELECT id FROM buhin))
OR (buhin2Id NOT IN (SELECT id FROM buhin))

ではだめなのかな
509NAME IS NULL:2012/02/10(金) 03:08:33.96 ID:???
だめなのかな、とか言われても・・・わかんないんです

DELETE FROM seihin WHERE buhin1Id NOT IN (SELECT id FROM buhin)
DELETE FROM seihin WHERE buhin2Id NOT IN (SELECT id FROM buhin)



DELETE FROM seihin WHERE (buhin1Id NOT IN (SELECT id FROM buhin))
OR (buhin2Id NOT IN (SELECT id FROM buhin))

どっちがイケてますでしょうか?
510NAME IS NULL:2012/02/10(金) 03:48:49.55 ID:???
わからないクエリを書くぐらいだったらわかる前者で済ませておけばいい
511NAME IS NULL:2012/02/10(金) 19:16:11.86 ID:???
ありがとうございます。最初の2行のやつでやってみます。

DELETE FROM seihin WHERE (buhin1Id OR buhin2Id) NOT IN (SELECT id FROM buhin)

これ書いたのは自分じゃなくてチームリーダーなんです。ちなみにチリ人です。
自分は部外者でタダでソフトをもらってるだけなので文句は言えないんです。
でも「動かん」ってバグ報告したらチームリーダーやらシニアデベロッパー(ちなみにスペイン人)やら
あと、ロシア人とハンガリー人がよってたかって「ちゃんと動く。動作テストした。エラー出ない」と言い張るんです。
こっちで試したらデータが全部吹っ飛んでしまって困ってるんです・・・
あ、内輪の話で申し訳ありません。
自分は工業高卒で英語が話せないのですが、なんとかがんばってヤツらを説得してみます。
512NAME IS NULL:2012/02/10(金) 19:28:11.05 ID:???
笑うしか無い
がんばってね w
513NAME IS NULL:2012/02/10(金) 20:38:28.49 ID:???
そんな構文が通るDBMSって何だ?
とか思って試してみたらMyなんちゃらでは通った。
514NAME IS NULL:2012/02/10(金) 20:39:56.38 ID:???
>>511
そういう時は、クエリのどこがどうおかしいかを伝えるのではなく、
このデータのときに結果がおかしいよ、というのを伝えるようにすれば、言葉の壁はなくなる
515NAME IS NULL:2012/02/10(金) 21:01:38.48 ID:???
513だけど通ったって言っても意図どおりに動作したって意味じゃなくて
構文エラーにならなかったって意味ね。

select buhin1Id, buhin2Id, (buhin1Id OR buhin2Id) from seihin
を実行してみると何が起きているか分かると思う。
516NAME IS NULL:2012/02/10(金) 22:15:56.25 ID:???
>>515
わかった〜!なんでデータが全部吹っ飛んだのか。
自分の操作ミスだと思ってたら、やっぱバグだった。

(buhin1Id OR buhin2Id) の値は常に 1 なんですよ。
たとえば、buhin1Id が 472536 で buhin2Id が 726666 だとすと
"SELECT 472536 OR 726666" を実行すると、1 が表示されるんです。
たったひとつの例外は、buhin1Id が 0 で buhin2Id も 0 のときだけ、0 になるんですけど
そんな部品は無いので、実質、ぜんぶ 1 になるんです。

ということは、
DELETE FROM seihin WHERE (buhin1Id OR buhin2Id) NOT IN (SELECT id FROM buhin)
これは
DELETE FROM seihin WHERE 1 NOT IN (SELECT id FROM buhin)
と等価なんです。
部品番号 1 以外は全て消去しなさい、って命令を実行してたんだ〜

チリ人のチームリーダーめ、呪ってやる!
517NAME IS NULL:2012/02/10(金) 22:23:45.63 ID:???
>>516
真偽値として解釈されるDBMSなら、そらそうよ。
0が偽、それ以外は真。DBMSは3値論理なので、NULLは除いて。

そんなことよりデータの復旧はできるのか?
518NAME IS NULL:2012/02/10(金) 22:44:13.93 ID:???
>>511
念のため確認するが、開発者がテストしたというDBMSと違うDBMSを使っているということはないよな?
519NAME IS NULL:2012/02/10(金) 22:55:32.56 ID:???
部品番号 1 以外は全て消去しなさい
じゃなくて
(SELECT id FROM buhin) の結果に1がなければ全削除、あれば1件も削除しない
になるな
520NAME IS NULL:2012/02/11(土) 23:39:14.88 ID:???
>>519
性格に言うと、そうですね。私が少し勘違いしてました。
でも結果は同じです。データが全部消えるんです。
消えたデータはテスト用(本番用のコピー)なので実害はありません。
(buhin1Id OR buhin2Id) という、あまり見慣れない式が出てきたんで
「なんじゃこりゃ?」と思い、テスト環境で動作チェックしてたところです。

チリ人のチームリーダー、まだ自信満々です。絶対に間違って無いと言い張ってます。
MySQL 5.5 です。もしかしたらMySQLのリビジョンによって OR の動作が異なるのかしらん。
もしかしたら俺の方が間違ってるのかな・・・だんだん自信がなくなってきた。
521NAME IS NULL:2012/02/11(土) 23:43:33.03 ID:???
>>520
サンプルSQLとサンプルテーブル使って
動作を見せてやりゃいいじゃん。
522NAME IS NULL:2012/02/12(日) 05:57:54.84 ID:???
多対多のテーブルがあって、それらを繋ぐためのテーブルって、なんて呼ばれてますか?
たとえば books と writers があって、この両者をつなげるためのテーブルです。
create table books_writers (
 book_id integer not null references books(id),
 author_id integer not null references authors(id)
)

あと、このようなテーブルの命名規則ってどうしてますか。
今は単純に2つのテーブル名をつなげただけなんですが、もっといい命名方法があれば教えて下さい。
523NAME IS NULL:2012/02/12(日) 09:49:50.23 ID:???
>>522
質問の意図がわからないんだけどなんか不都合があるの?
Railsとかは決まってるけど
524NAME IS NULL:2012/02/12(日) 10:34:51.81 ID:???
>>523
>>522 じゃないけど、質問の意図は
「(今の方法で困ってるわけじゃないけど) よりよい命名方あるか?」
でしょ。

俺には、思いつかないけど。
525NAME IS NULL:2012/02/12(日) 11:02:59.01 ID:???
まあスレ違いっぽいなぁ。

世間でどう言ってるかは知らないが、俺はブリッジと呼んでいる。
命名に関してはあなたと同じ。
例えば石橋表面に対してタイヤの滑り易さ係数収めたテーブルは、

bridge_stone_tyre

とか。
526NAME IS NULL:2012/02/12(日) 11:22:03.50 ID:???
>>525
ブリ○ストンの方ですか?
527NAME IS NULL:2012/02/12(日) 11:28:06.58 ID:???
完全に勝手命名だろうけどクロステーブルって呼んでる
他人と話すとクロス集計表と間違える人間がいるかも
528NAME IS NULL:2012/02/12(日) 13:29:46.71 ID:???
>>524-527
ありがとうございます。
結合するためのテーブルに、決まった呼び名はないのですか。驚きました。
命名規則も、もっといいのがあるといいのですが。
529NAME IS NULL:2012/02/12(日) 21:28:58.41 ID:???
じゃっかん乗り遅れたが、自分ルールではバインダー
テーブル名のプレフィックスは bind_[テーブルA]_[テーブルB]
そしてテーブルABの並びは ascii 順
530NAME IS NULL:2012/02/13(月) 12:05:42.95 ID:???
507 です。無事、解決しました。無事・・・ではないですけど。
seihinデータがまるごとぜんぶ消える現象をやっと認識してもらって、SQL文を元の正しいのに戻してもらいました。
チリ人のリーダーは、まだ理屈を理解してなさそうですけど。
でも、私のアカウントは停止されてしまいました。
英語の話せない日本人(私)が、dangerとかdatabase will brokeとか、さんざん騒いだせいです。
だって、緊急を要する最優先事項でうから。
アカウントくらい捨てメアドでいくらでも作れるので痛くもなんとも無いんですけど
2つめのアカウントも停止されてしまいました。いま3つ目をつくったところです。
日本のIPからのアクセスも禁止されてしまいました。いま海外からのプロキシでアクセスしてるところです。
この一部始終を皆さんに見せてあげたいところですが、いま掲示板を見たら、
データ消失事件のやりとりの一部始終がすべて削除されていました。
あの件は無かったことにされてしまいました。
ちゃんちゃん
531NAME IS NULL:2012/02/13(月) 13:33:57.33 ID:???
ちょ、チリ人連絡拒否とかひでえ
もうそこには仕事やらんでよろし
532NAME IS NULL:2012/02/13(月) 13:42:18.58 ID:???
>>530
dangerはまずいよ。
作った人を犯罪者扱いしてるようなもんだ。
そりゃ気を悪くするよ。
英語のわかる人に相談して、柔らかい物言いを
すりゃよかったのに。

でも、どういう体制の職場?
同じ会社の同僚じゃないの?
アカウント停止とかちょっと意味わかんない。
533NAME IS NULL:2012/02/13(月) 15:35:43.41 ID:???
会社じゃなくて、オープンソースかなんかの趣味(と言っちゃ悪いか?)プロジェクトだったん?
534NAME IS NULL:2012/02/13(月) 23:43:45.00 ID:???
なんか英語がわからなくて勘違いしちゃったんじゃないの?
オープンソースの開発者達がそんなレベル低いとは思えん。
535NAME IS NULL:2012/02/14(火) 00:10:18.20 ID:???
言葉が判らずとも再現手順があれば間違えようがないよな
536NAME IS NULL:2012/02/14(火) 22:58:14.10 ID:???
>>534
オープンソースも色々だし、コアの部分はともかく、端っこの部分は結構いい加減だったりするよ。
537NAME IS NULL:2012/02/14(火) 23:05:35.45 ID:???
しかし、出禁くらってんのに何度も入り直すのはよくないわ
オプソなら自己責任でやれよ
538NAME IS NULL:2012/02/15(水) 01:30:24.74 ID:???
またアカウント凍結されたんでこんどは
buhin1IdORbuhin2Id
というアカウント名を作ってみたら
翌日にはアカウント凍結されてた。
掲示板を閲覧だけして、まだ何も書き込んでないのに。
理由は、不正なアカウント名です、だって。
539NAME IS NULL:2012/02/15(水) 01:32:36.00 ID:???
スレ違い
540NAME IS NULL:2012/02/15(水) 02:46:46.47 ID:???
これは性格悪そう
541NAME IS NULL:2012/02/15(水) 03:53:44.79 ID:???
>>538
もうスレ違いなんで。
542NAME IS NULL:2012/03/01(木) 19:30:33.34 ID:???

・DBMS名とバージョン
Oracle 11gR2
・テーブルデータ
テーブル名:受注テーブル
列名:受注ID,受注数, 日付

・欲しい結果
前日から1週間前までさかのぼり、
日毎の受注数を取得する。
受注数が0の日も検索結果として表示したいです。
イメージは↓です。

○元となるデータ
受注ID, 受注数, 日付
1, 10, 2012/2/26 9:00
2, 20, 2012/2/27 9:00
3, 25, 2012/2/27 9:30
4, 30, 2012/2/29 9:00


○抽出結果
日付, 受注数
2012/2/23, 0
2012/2/24, 0
2012/2/25, 0
2012/2/26, 10
2012/2/27, 45
2012/2/28, 0
2012/2/29, 30

・説明
次のSQLで受注がない日については、
望んだデータが抽出できました。
受注がない日の扱いを教えてください。

select 日付, sum(受注数)
from 受注テーブル
where trunc(日付) between trunc(sysdate - 7) and trunc(sysdate - 1)
group by trunc(日付);

よろしくお願いします。
543NAME IS NULL:2012/03/01(木) 20:30:03.81 ID:???
存在しないデータを"select"することはできませんよ。 >>8
544NAME IS NULL:2012/03/02(金) 20:46:18.48 ID:???
間違ってたらごめんだけど、model句使えばできない?
545NAME IS NULL:2012/03/03(土) 02:47:10.89 ID:???
これみるとつかえそうね。
http://codezine.jp/article/detail/5154

PostgreSQLのgenerate_seriesと同じくらいの扱いにはできるかもしれない(きびしいか?)ので、>>8は変えてもいいかもね
546NAME IS NULL:2012/03/03(土) 02:48:56.62 ID:???
あ、と。Oracle使いではないので、そんなことはなく、>>8の方法のほうがよいとかあるならご指摘を。
547NAME IS NULL:2012/03/03(土) 05:35:25.99 ID:???
mode句が標準SQL(もしくは事実上標準)ならばそれでテンプレにすれば良いけど
特定のDBMS実装にかかわるものをテンプレに入れるのは反対
548NAME IS NULL:2012/03/05(月) 09:49:05.83 ID:???
Master Table
id | type id
------------
01 | 1
02 | 2
03 | 2
04 | 1
05 | 1
06 | 2

・DBMS名とバージョン
mysql 5.1.44

・テーブルデータ
Table A
id | name a
------------
01 | aaa
04 | bbb
05 | ccc

Table B
id | name b
------------
02 | ddd
03 | eee
06 | fff

・欲しい結果
Master Tableのtype idが1だとTable Aと、2だとTable BとJOINしたいんですけど、どう書けば良いんでしょうか?
549NAME IS NULL:2012/03/05(月) 11:33:00.79 ID:???
>>548
MySQLで動くかどうか試してないけど、

SELECT MasterTable.*,
CASE WHEN type_id=1 THEN Table_A.name_a WHEN type_id=2 THEN Table_B.name_b END AS name
FROM MasterTable
LEFT JOIN Table_A USING (id)
LEFT JOIN Table_B USING (id);
550NAME IS NULL:2012/03/07(水) 06:05:26.24 ID:SbjMyYjx
掲示板をつくっています。
・親投稿
 └ 子投稿
 └ 子投稿
のように1つだけコメントができる仕様で、
親・子投稿は以下のテーブルに格納されます。
post
- id(PK)
- parent_id(postのIDでこれが0なら親、その他INTなら子)
- その他、投稿に関する情報(タイトル、本文など)
上記のようなテーブルから、
親投稿にぶらさがる子投稿をまとめて取得するのはSQLではどう書けばいいでしょうか?

ちなみに現在は、WHERE parent_id = 0 で親を取得して、
その後取得した各レコードのidがparent_idに入っている投稿をループして取得しています。
なので、20個の投稿とコメント取得する場合、21個のSQLを発行してしまっています。
これを1回で取ってきたいです。
551NAME IS NULL:2012/03/07(水) 06:17:02.03 ID:???
>>550
木構造の情報を1回のSQLの発行で全部取り出す?
552NAME IS NULL:2012/03/07(水) 06:22:59.08 ID:???
親子だけで孫を許さないようになっているならこれだけでいいような

select *
from  post T1
    left outer join
    post T2
    on T1.id = T2.parent_id
;

孫以下、多階層を許すなら再帰問合せを使わなきゃなんない
553NAME IS NULL:2012/03/07(水) 06:28:09.94 ID:???
>>550
ttp://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html

おまいの使ってるエンジンが再帰(WITH RECURSIVE)に対応してればいいが・・・。
554NAME IS NULL:2012/03/07(水) 07:18:36.84 ID:???
親投稿をひとつのファイルにして、子を追記していく、でいいな。
555NAME IS NULL:2012/03/07(水) 08:11:17.34 ID:???
>>550
「一つだけコメントができる仕様」の意味が不明だったが、
Amazonの書評のような構造かな。
556550:2012/03/07(水) 09:20:25.90 ID:SbjMyYjx
いや、孫はいりません
>>552の方法でいけそうですけど、
親レコード+子レコードのレコードが1行になるので
アプリケーション側で工夫が必要ですね

ありがとうございます。
557NAME IS NULL:2012/03/07(水) 13:01:45.93 ID:???
>>556
order byにcase使えるDBMSなら
1.親IDが0ならID、そうじゃないなら親ID
2.ID
の順で並び変えるだけで良いんじゃないのか?
558NAME IS NULL:2012/03/07(水) 13:05:54.11 ID:???
設計スレで設計してもらい、SQLスレでクエリを教えてもらう、と。
アプリケーション側の工夫が必要だとわかったってことは、次はどこのスレだろ。
559NAME IS NULL:2012/03/07(水) 13:10:31.28 ID:???
うちの会社ブラックなんだがスレ
560NAME IS NULL:2012/03/07(水) 13:39:39.11 ID:???
アプリケーション側の工夫が必要らしいのですが、これに対応しているアプリケーションはありますか?
or
アプリケーションとはどうやれば作れますか?
561NAME IS NULL:2012/03/07(水) 15:01:29.71 ID:sPFfC/0l
初歩的な事ですいません
名前の後ろにさんや様を付けたい場合はどうすればいいのでしょうか?

先ほどupdate"社員表" set "氏名" = 'さん';
とした場合みんなの名前が全員さんになってしまいました・・・
562NAME IS NULL:2012/03/07(水) 15:22:04.44 ID:???
初歩的なことだと思うなら初歩的なサイトを見ればいいと思うのに。
文字列の連結の仕方知ってる?
563NAME IS NULL:2012/03/07(水) 15:22:12.63 ID:???
>>561
update"社員表" set "氏名" = "氏名"+'さん'
とか
+の所は文字列を結合する演算子なんだが、DBMSによって違うので自分で調べてくれ
564NAME IS NULL:2012/03/07(水) 18:05:27.73 ID:???
まあ普通は ||
565NAME IS NULL:2012/03/07(水) 18:06:24.12 ID:???
でもさんをつけるのはSELECT時にしてデータに入れなくていいような
566NAME IS NULL:2012/03/07(水) 18:48:02.23 ID:???
データにいちいち敬称なんかつけるなよ w
567566:2012/03/07(水) 18:50:32.28 ID:???
登録(更新)する時にということね

更新とか登録とかの時に敬称なんかつけてたらそれを取り除く作業が発生してしまうw
568NAME IS NULL:2012/03/07(水) 20:49:04.00 ID:???
敬称がデータとして必要な場面もあるけどな。まあその場合は敬称は別項目でもつべきだが
住所録ソフトの宛名とかそうなってるだろ
569NAME IS NULL:2012/03/14(水) 20:53:09.72 ID:???
code | val
------------
A | 11
A | 23
A | 34
A | 42
B | 321
B | 112
B | 23
B | 245
というようなテーブルがあり、ここから
同じcodeを持つ行が4行以上ある場合、val順で小さい方から3行残してのこりを削除
したいのですが、SQL一発でできますか?DBMSはMySQLです。

↓ほしい結果
code | val
------------
A | 11
A | 23
A | 34
B | 112
B | 23
B | 245
570NAME IS NULL:2012/03/14(水) 21:11:56.47 ID:???
limit句がdeleteやupdateでも使えたはず
571NAME IS NULL:2012/03/14(水) 21:13:16.63 ID:???
select T1.code,
    T1.val
from  TableName T1
    inner join
    TableName T2
    on T1.code = T2.code
    and T1.val >= T2.val
group by T1.code,
     T1.val
having count(*) <= 3
order by T1.code,
     T1.val
;
572NAME IS NULL:2012/03/14(水) 21:14:45.69 ID:???
ああ、deleteしたいのか
まあいいや
573NAME IS NULL:2012/03/15(木) 10:13:38.96 ID:???
ありがとうございます。これで削除ができました。

DELETE FROM t WHERE EXISTS (
  SELECT *
  FROM (
    SELECT t1.code,t1.val
    FROM t t1 INNER JOIN t t2 ON t1.code = t2.code AND t1.val >= t2.val
    GROUP BY t1.code,t1.val
    HAVING COUNT(*) > 3
  ) d
  WHERE
    d.code = t.code
    AND d.val = t.val
);
574NAME IS NULL:2012/03/16(金) 12:56:17.54 ID:???
MySQLかPostgreSQLかMongoDBかSQLiteのいずれかで以下のことを実現するSQLを伝授してください
やりたいこと: id10とid11の間に新しいカラムを挿入する

id 10のカラム みかん
id 11のカラム りんご

id 10のカラム みかん
id 12のカラム 新しく挿入した箇所
id 12のカラム りんご
575574:2012/03/16(金) 12:57:25.19 ID:???
訂正

id 10のカラム みかん
id 11のカラム りんご

id 10のカラム みかん
id 12のカラム 新しく挿入した箇所
id 13のカラム りんご ←ここ以降idをずらす
576NAME IS NULL:2012/03/16(金) 13:12:58.16 ID:???
なんかExcel等の表計算ソフトの発想っぽく見えるな、
カラム(じゃなくてロウだな)を挿入するってのが。

そもそもIDの付け替えってこと自体がなぁ…
ID体系の変更なんかで、全部えいやっと付け替える以外では
そうそうやるもんじゃないと思うんだが。
577574:2012/03/16(金) 13:17:00.08 ID:???
カラムの内容は重複しても構わないのでidがなくても構いません
この場合で考えていただいた場合でも難しいですか?
578NAME IS NULL:2012/03/16(金) 17:37:30.15 ID:???
>>577
問題になるのはそのidの方で、'10'と'11'の間に挿入しなさいと言われれば
'10' みかん
'11' 新しい挿入
'12' りんご
が普通。
新たに追加する場合に取得するidで追加しておいて、
そのあとにりんご以下をidを変更しながらコピーする
というのは相当にクレージー。
579NAME IS NULL:2012/03/16(金) 20:41:51.20 ID:???
>>574 はシステム開発の仕事をやめるべきだと思う。
580NAME IS NULL:2012/03/16(金) 22:45:59.58 ID:???
>>574
idが11以上のものに1足して、id11を挿入する。
updateして、insertする。
581574:2012/03/17(土) 00:40:03.84 ID:???
>>580

updateとinsertだと、

id 10のカラム みかん
id 13のカラム りんご ←ここ以降idをずらす
id 14
 :
id 12のカラム 新しく挿入

こんな風に順番が崩れてしまいませんか。
insertとは言っても、空いたところが無いでしょうから、
後ろに付け足されそうで…
582NAME IS NULL:2012/03/17(土) 00:54:40.79 ID:???
>>581
あー、それを気にしてるのか。
レコードの順番ってinsert順とは限らないよ。
だから、updateとinsertでいい。
583NAME IS NULL:2012/03/17(土) 00:56:31.65 ID:???
idの順番で取り出したいのならorder by idをつけないとだめ。常に。
584NAME IS NULL:2012/03/17(土) 09:59:54.59 ID:???
MySQL 5.5.19 . 長くなりますので
テーブルの定義・内容と欲しい結果はここに
http://codepad.org/oe1jhVrF

で、
select a.input_date,b.input_date,a.data1,a.data2,b.data2
from a_tbl a
right join b_tbl b
on a.input_date = b.input_date; とすると、結果が
+------------+------------+-------+-------+-------+
| input_date | input_date | data1 | data2 | data2 |
+------------+------------+-------+-------+-------+
| 2012-02-01 | 2012-02-01 | 10 | 12 | 13 |
| NULL | 2012-02-03 | NULL | NULL | 18 |
| 2012-02-04 | 2012-02-04 | 13 | 15 | 14 |
| NULL | 2012-02-05 | NULL | NULL | 95 |
| 2012-02-06 | 2012-02-06 | 13 | 10 | 10 |
+------------+------------+-------+-------+-------+
なんですが、実際にはいろんなコードが入っているので、コードも抽出条件に入れたら
select a.input_date,b.input_date,a.data1,a.data2,b.data2
from a_tbl a
right join b_tbl b
on a.input_date = b.input_date
where
a.code=1111 and b.code='ddd';
+------------+------------+-------+-------+-------+
| input_date | input_date | data1 | data2 | data2 |
+------------+------------+-------+-------+-------+
| 2012-02-01 | 2012-02-01 | 10 | 12 | 13 |
| 2012-02-04 | 2012-02-04 | 13 | 15 | 14 |
| 2012-02-06 | 2012-02-06 | 13 | 10 | 10 |
+------------+------------+-------+-------+-------+
になってしまいました。
コードを抽出条件に入れた状態で望ましい結果または上の方の結果になるようなSQLを教えて下さい。
585NAME IS NULL:2012/03/17(土) 10:04:45.20 ID:???
抽出してからjoin。
586NAME IS NULL:2012/03/17(土) 10:45:45.81 ID:???
ありがとうございます。

select a.input_date,b.input_date,a.data1,a.data2,b.data2
from
( select input_date,data1,data2 from a_tbl
where code=1111) a
right join
( select input_date,data2 from b_tbl
where code='ddd') b
on a.input_date = b.input_date;

で上の方の結果になることが出来ました。
587NAME IS NULL:2012/03/17(土) 16:46:35.79 ID:???
>>584 のを a.code=1111 or b.code='ddd'; にするだけでよくね?
588NAME IS NULL:2012/03/17(土) 16:54:20.97 ID:???
>>584
つ or a.code is null
589NAME IS NULL:2012/03/23(金) 19:05:50.71 ID:???
3行目と4行目のデータを入れ替えるというのはどのようにやるのでしょうか?
590NAME IS NULL:2012/03/23(金) 19:26:45.85 ID:???
>>589
リレーショナルデータベースでは表内の行に順序はありません
select文でorder by句を指定したとき初めて順序が生まれます

order by句を指定せずにselectしたときは
仮に実行するたびに順序が違っても文句は言えません

ここまで理解できたらもう一度質問してください
591NAME IS NULL:2012/03/28(水) 16:14:27.69 ID:MsrxUF32
・RDBMS
MySQL 5.1.6

・テーブルデータ
aji_table //調味料テーブル
rank int(3) //表示順位 NULL許可
name varchar(16) //調味料の品名
price int(5) //調味料の値段

・インサートされているデータ
NULL|さとう  |100
0   |しお   |200
3   |こしょう |300
NULL|みそ   |400
NULL|みりん  |500

・欲しい結果
0   |しお   |200
NULL|さとう  |100
NULL|みそ   |400
3   |こしょう |300
NULL|みりん  |500


・説明
お世話になります。
上記にある調味料値段データベースにおいて
表示順をソートする際に
・順位に数字が入っているものは、一覧表示を行う際にその数字に応じた順位に出す。
・それ以外は、値段昇順で出力する。

というSELECT文が組めないものかと思っております。

単純に値段順で表示したいんですけど、いくつかの商品は
表示結果におけるその順番の位置を固定したい!という内容でして
順位のフィールドをおいてなんとか解決しようとしているのですがうまく組めません。

対応策を是非、ご教授頂ければと思います。

なお、そんなテーブルの組み方はダメだ、そういうときはこう組め!等もありましたら
ご教授お願いいたします。


よろしくお願いいたします。
592NAME IS NULL:2012/03/28(水) 17:06:51.28 ID:???
質問です。
phpが絡むんですが、


$se = $_POST['search'];

$res = mysql_query('SELECT COUNT(*) FROM fx WHERE day LIKE "%{$se}%" AND
game LIKE "%勝ち%"');
$game_s = mysql_fetch_assoc($res);

$seの中には年月が入っています。
特定の月の勝ちの数を出したいんですがうまく行きません。

ちなみに$seの中身がちゃんと入っている事はprintで確認しています。

たぶん変数の入れ方に問題があると
思うのですが、

誰か指南を御願いします。
初歩的すぎてすぃません。。





593NAME IS NULL:2012/03/28(水) 17:25:40.96 ID:???
>>592
$seに受け取っている値は、定型なフォーマットの値で受け取っておりますでしょうか。
そこに受け取っている値例を出してください。
594NAME IS NULL:2012/03/28(水) 17:54:22.45 ID:???
>>593
自分のレベルが低すぎて
せっかくお答えいただいているのに
どう返していいかわかりません。(笑

情報が少なすぎると思いますので
流れを書きます。

input_s.htmlに以下の記述

<form method="post" action="input_s.php">
<select name="search">
<option value="2012/03/">2012年3月</option>
<option value="2012/04/">2012年4月</option>
<option value="2012/05/">2012年5月</option>
<option value="2012/06/">2012年6月</option>
<option value="2012/07/">2012年7月</option>
<option value="2012/08/">2012年8月</option>
<option value="2012/09/">2012年9月</option>
<option value="2012/010/">2012年10月</option>
<option value="2012/011/">2012年11月</option>
<option value="2012/012/">2012年12月</option>
</select>

<input type="submit" value="検索する" />

</form>
595NAME IS NULL:2012/03/28(水) 17:55:12.62 ID:???
>>593
input_s.phpに以下の記述

<?php
$url = "***";
$user = "***";
$pass = "***";
$db = "***";

// MySQLへ接続する
$link = mysql_connect($url,$user,$pass) or die("MySQLへの接続に失敗しま
した。");
// データベースを選択する
$sdb = mysql_select_db($db,$link) or die("データベースの選択に失敗しまし
た。");
mysql_query('SET NAMES UTF8');

$se = $_POST['search'];
$recordSet = mysql_query("SELECT * FROM fx WHERE day LIKE '%{$se}%'");




//勝ち絞込み検索結果
$res = mysql_query('SELECT COUNT(*) FROM fx WHERE day LIKE "%{$se}%" AND
game LIKE "%勝ち%"');
$game_s = mysql_fetch_assoc($res);


?>

<?php print "{$se}の集計"; ?>←ここは表示OK

<?php print $game_s['COUNT(*)']; ?>勝 ←ここの表示ができない
596NAME IS NULL:2012/03/28(水) 17:55:51.26 ID:???
>>593
mysqlの登録部分
フィールド/種別/照合順序/属性/ヌル(NULL)/デフォルト値/その他

day/text/utf8_general_ci/属性なし/いいえ/None/その他なし
game/text/utf8_general_ci/属性なし/いいえ/None/その他なし


こんな感じなのですが
どうでしょうか?

よろしくお願いします。
597593:2012/03/28(水) 18:09:37.07 ID:???
データ型だとか、$recordSetはどこ行っただとかいくつか突っ込むべき点が
あるのですが、そこらは割愛します。

大体やりたいことはわかりましたので
すでに入っているデータの中身の例を複数件、教えてください。

もし、可能でしたら、勝ち絞込み検索結果のSQL文を適当にechoして
phpmyadminか何かで直接MySQLに叩き込んでエラーを拾ってください。
598NAME IS NULL:2012/03/28(水) 18:42:46.24 ID:???
>>597
すいませんお世話になります。

$recordSetは繰り返し処理で処理しをしようと思っています。
今後です(笑

2件しかデータは入れていないですが、

idオートインクル

id/day/game

1 / 2012/03/26 / 勝ち
2 / 2012/04/26 / 負け


です。

ちなみに
SELECT COUNT(*) FROM fx WHERE day LIKE "%2012/03/%" AND game LIKE "%勝ち%"
で実行すると
COUNT 1 と出ます。

SELECT COUNT(*) FROM fx WHERE day LIKE "%2012/04/%" AND game LIKE "%勝ち%"
で実行すると
COUNT 0 と出ます。

これを踏まえて %ここ% この中身に変数を入れたらいいんだという
安易な考えなのですが、

<?php print "{$game_s}"; ?>
これを実行したら Arrayと出ました。

どうでしょうか?
599NAME IS NULL:2012/03/28(水) 18:56:30.64 ID:???
>>591
SELECT一発じゃ無理だな

select * from aji_table where rank is not null order by rank;
select * from aji_table where rank is null order by price;
を別々に取得してアプリ側でマージしたほうがいいかと
600NAME IS NULL:2012/03/28(水) 20:56:30.65 ID:???
>>591
mysqlは知らないけど、オラクルだとこんな感じでできないかな
動くかわかんないけど。

select
rank,name,price
from (
select
rank,name,price,
row_number() over(order by price) as num
from aji_table
)
order by nvl(rank,num), nvl2(rank,0,1)
601591:2012/03/28(水) 21:48:30.04 ID:SAJaqLDy
>>599
回答ありがとうございます。
やはりムリな背伸びはしないほうがいいですかねぇ…。
変数を与えながら行番号を与えて値段順にソートしたテーブルと
元のテーブルでrank is not nullかけたものをマージして
うまくrankと行番号つき合わせて処理できないかとか思っているのですが
SELECT文組む能力の足りなさを露呈して困っておりました。

>>600
ご回答ありがとうございます。
申し訳ございませんが不勉強なもので、
OVER()やORDER BYにNVLがあるとどうなるですとか
すぐには理解できなかったので
一晩かけて理解できるようまずそのSQL文から学んでみたいと思います。
そこからうまく期待のものが組めないかと思っております。

ありがとうございました。
602NAME IS NULL:2012/03/28(水) 21:51:12.12 ID:???
>>600
rankがnullでないものが途中に入ったら
それ以降のnumを繰り下げないといけないから
それじゃあ無理
603NAME IS NULL:2012/03/28(水) 22:24:52.54 ID:2iS1ICMl
MySQL

テーブルデータにNo int(255)があります。

現在Noには10000件のデータがあり追加や削除を繰り返しているので
既にNo連続した数字にはなっていません。

今回、取得したいのはNoが5000以上でNo小さい方から30件取得して
Noが大きい順に並べ替えて取得したいです。

この場合のSQLはどう書けばいいでしょうか?
604NAME IS NULL:2012/03/28(水) 22:36:30.70 ID:???
SELECT No FROM (SELECT No FROM tabName WHERE No >= 5000 ORDER BY No ASC LIMIT 30) AS otherTab ORDER BY No DESC

かな?
605NAME IS NULL:2012/03/28(水) 22:40:07.83 ID:???
>>604
なるほど参考になります。
試してみます。
606NAME IS NULL:2012/03/28(水) 22:44:58.06 ID:???
>>604
上手くいきました^^有難うございました
607NAME IS NULL:2012/03/28(水) 23:10:57.22 ID:???
>>598

それならば、mysql_result($res,0)で受け取ってみてください。
>>595が正解なはずなんだけど。
それでダメならば、mysql_error()してみたり、arrayと表示されたその変数をprint_r()してみて
中身をじっくりみて理解を進めてみるとよいと思われます。

なお、WHERE句は、適切に%を使う数を適切に制限したり、=でいいところは=にして明示的に絞り込んだりすることで
問題の切り分けもしやすくなるので、そこも含めて実行してみてください。
608NAME IS NULL:2012/03/29(木) 00:30:35.38 ID:???
>>607
resultでもうまくいかないっすね。
うーん、
もうちょっと調べてみます。
また結果報告いたします!
607さん付き合ってくれてありがとうです( ´ ▽ ` )ノ





609NAME IS NULL:2012/03/29(木) 00:54:07.22 ID:???
いいかげんホスト言語の問題はその言語のスレで聞いてくれ
610NAME IS NULL:2012/03/29(木) 01:29:20.12 ID:???
>>522
ORM界隈ではjoin tableって言ってる。
611NAME IS NULL:2012/03/29(木) 18:36:58.11 ID:???
>>601
これでどうかしら

select * from aji_table order by
 if (rank is null,
  (select count(*) from aji_table as t2 where t2.rank is null and t2.price < aji_table.price),
  rank - (select count(*) from aji_table as t2 where t2.rank is not null and t2.rank < aji_table.rank)
  ), rank is null, rank;
612601:2012/03/30(金) 10:42:12.28 ID:???
>>611
ばっちり動きました…。
ORACLEのNVLでまさかと思っておりましたが
ORDER BY でもIFかけられるんですね。
今後の参考にもさせて頂きます。
どうもありがとうございました!
613NAME IS NULL:2012/03/30(金) 13:15:40.82 ID:???
>>612
じゃあ、もののついでに、case文もかけるのを知っておくと何かの役に立つかも。
インデックス使えないとかの問題は出てくるけどね
614NAME IS NULL:2012/03/30(金) 14:37:22.08 ID:???
・DBMS名とバージョン
MySQL

・テーブルデータ
店舗(店舗ID 店舗名)

商品(商品ID 店舗ID 商品名)
(※同じ名前の商品が複数の店舗にあっても、別の商品として扱う)

売り上げ(売り上げID 商品ID 個数)

・欲しい結果
店舗名 商品名 売り上げ個数合計
(※店舗名、商品名でソート)

・説明
SELECT * FROM `店舗` ORDER BY `店舗名`;
この結果をプログラム側でループ
SELECT * FROM 商品 WHERE 店舗ID=? ORDER BY `商品名`;
さらにこの結果をループ
SELECT SUM(個数) FROM 売り上げ WHERE 商品ID=?

これだと時間がかかりすぎるので、これを1つ、または2つのSQLにまとめたいです。


SELECT *, SUM(`売り上げ`.個数`) AS `売り上げ個数合計`
FROM `商品`
LEFT JOIN `売り上げ` ON `商品`.`商品ID` = `売り上げ`.`商品ID`
WHERE `商品`.`店舗ID`=?

とりあえず下2つだけでもまとめようとしてみたのですが、合計が商品毎ではなく店舗毎の合計になってしまいます。
615NAME IS NULL:2012/03/30(金) 17:35:56.46 ID:???
group by 店舗ID, 商品ID

でも、商品はいずれかの店にしか配置されないわけだから、商品のgroupだけでいいかもね。
616NAME IS NULL:2012/03/31(土) 11:54:53.03 ID:???
>>592
game LIKE "%勝ち%" の部分だけど、本来は
game LIKE '%勝ち%' ですよね。

"%勝ち%" というフィールドを探しに行っているのではないの。
シングルクォーツの中にシングルクォーツを書くPHPの書き方を知らないから
どうすればいいとか言えないけど。
617NAME IS NULL:2012/03/31(土) 11:59:14.14 ID:???
なんで複数形なんだよw
618NAME IS NULL:2012/03/31(土) 12:21:33.50 ID:???
前と後で2つあるからとか?
619NAME IS NULL:2012/03/31(土) 16:51:00.95 ID:???
ん? シングルクォートか?www
620NAME IS NULL:2012/04/01(日) 03:33:26.55 ID:???
>>615
なるほど、そんな手が…。
ありがとうございます。
621NAME IS NULL:2012/04/01(日) 21:12:09.01 ID:Lb+ordGT
■DBMS名とバージョン
MySQL 5.0

■テーブルデータ
店舗テーブル
AreaID      int(1)←この2つでキーになってます
TenpoID     int(1)←この2つでキーになってます
uriage       int(16)

社員テーブル
SyainNo      int(255)
AreaID       int(1)
TenpoID      int(1)
SyainName    varchar(256)

■欲しい結果

uriageが5000以下の店舗に属してる社員を抜き出す
のと
その社員をいっぺんに消す

どのようにSQL文を書けばいいでしょうか?
622NAME IS NULL:2012/04/01(日) 21:25:51.49 ID:???
exists
623NAME IS NULL:2012/04/01(日) 21:30:32.83 ID:???
売り上げが一定額に達しなかったら全員リストラか
過激だな
624NAME IS NULL:2012/04/01(日) 21:51:10.09 ID:Lb+ordGT
>>623
あくまでサンプルですw
625NAME IS NULL:2012/04/01(日) 23:51:59.00 ID:p/jAjTZq
>>621ですがexistsを使って考えてるんですが上手くいきません

SELECT *
FROM 社員テーブル
WHERE EXISTS (
SELECT *
FROM 店舗テーブル
WHERE 社員テーブル.AreaID = 店舗テーブル.AreaID
AND 社員テーブル.TenpoID = 店舗テーブル.TenpoID
AND 店舗テーブル.uriage > 5000
)

ってやってみたんですけど 店舗テーブル.uriage > 5000 が効いてないみたいです
何が間違えでしょうか?
626NAME IS NULL:2012/04/02(月) 00:45:10.42 ID:???
>>625
>>621です。

あってたみたいです。
結果の確認の仕方が間違えていました。
627NAME IS NULL:2012/04/02(月) 06:06:37.01 ID:???
>>621
SELECT T2.* FROM (SELECT * FROM TenpoTable WHERE uriage<=5000) AS T1
JOIN SyainTable AS T2 ON T1.AriaID=T2.AriaID AND T1.TenpoID=T2.TenpoID;

DELETE FROM SyainTable AS T1
WHERE EXISTS (SELECT * FROM TanpoTable AS T2 WHERE uriage<=5000 AND T1.AreaID=T2.AreaID AND T1.TenpoID=T2.TenpoID);

MySQLで動くかしらないけどね。

ところでMySQLってUSINGはまだ使えないのでしたっけ?
使えるのならONのところはUSING(AreaID,TenpoID)となって楽。
628NAME IS NULL:2012/04/02(月) 23:09:42.67 ID:jqvkdUXL
Mysql5を使っています。以下のようなテーブルがある時、
・table_male(カラム:id/name/address)
・table_female(カラム:id/name/address)
・table_X(カラム:id/sex_id/sex/unique_key) ※sex_idはtable_male.idもしくはtable_female.id

クエリA
select `sex`, `sex_id` from table_X where unique_key = $key limit 1;
の結果(sexの値にmaleかfemaleが返る)に応じて
table_maleもしくはtable_femaleからaddressを引き出したいと思います
今まではクエリAのあとに以下のようにしていたんですが、両方をまとめてやることはできないでしょうか?
select `address` from table_male where `id`=$sex_id limit 1;

最初のクエリの取得結果に応じて、続けて実行するクエリの対象テーブルを変更させるということに
なると思うんですが…
よろしくお願いします
629NAME IS NULL:2012/04/02(月) 23:36:23.40 ID:???
select ifnull(table_male.address, table_female.address) from
table_X left join table_male on (table_X.sex_id = tablemale.id) left join table_female on (table_X.sex_id = table_female.id)
limit 1;

select address from
table_X join (select * from table_male union all select * from table_female) as table_malefemale on (table_X.sex_id = table_malefemale.id)
limit 1;

とか。
630628:2012/04/03(火) 04:04:56.20 ID:b2izkOxC
>>629
ありがとうございました、しらない方法で勉強になりました

すみませんがもう一つ質問させてください
SNSみたいなアプリを作ってて、ユーザーのマイページ(http://example.com/user/taro)に
「プロフィール、写真、イベント、日記、etc…」と複数のテーブルから引き出されるデータを表示する必要があるのですが、
それぞれのテーブルが以下のような構成になっています
t_profile id|accout(このユーザの値はtaro)|name|mailaddress
t_photo id|path_to_file|userId(t_profile.idです)
t_event id|event|day_event|userId
t_diary id|title|body_text|userId

この場合、どのようにデータを引き出すのが良いですか?
URLからt_profile.accountであるtaroを取得して、それをt_photoやt_tweet,t_diaryへのselect文のサブクエリに利用するのが良いのか
例:select t_photo.path_to_file where t_photo.userId = (select `t_profile`.id where `t_profile`.account = 'taro' limit 1)
  以降、t_event、t_diaryへも同様に処理
それとも、最初にaccountのtaroを利用してt_profileからt_profile.idを抜き出して、それをキーにselectした方が良いのか
例:select t_photo.path_to_file where t_photo.userId = $profileID

前者で発生するサブクエリ3回の負荷と、後者で発生するID抜き出しクエリ1回の負荷を単純に比較して
後者の方が良いと考えて良いんでしょうか
631NAME IS NULL:2012/04/03(火) 04:44:23.39 ID:???
実現できてから遅いところを直せばいい。
前者でやるにしても、そのlimitのクセはやめたほうがいい。
アカウント名がユニークじゃないならそれはそれで問題だし。
632NAME IS NULL:2012/04/03(火) 11:10:34.60 ID:???
phpmyadmin使うようになったら、お守りのようにLIMIT 1をつける癖がついた件
633NAME IS NULL:2012/04/03(火) 14:34:02.98 ID:???
MySQL 5.1です。

create table staff_list(
staff_id int(5) primary key //社員番号
staff_name varchar(8) //社員名
unit varchar(8) primary key //部署名
)

insert into staff_list (staff_id,staff_name,unit) values
(1,'範馬','総務'),
(2,'愚地','総務'),
(3,'花山','総務'),
(1,'高津','企画'),
(2,'池谷','企画'),
(3,'長嶋','企画'),
(1,'鳩山','営業'),
(2,'野田','営業'),
(3,'小沢','営業'),
(4,'枝野','営業')



このようなテーブルに対してSELECTをかける際、一度のクエリーで
部署別にソートしたうえで、総務だけstaff_id降順で他を昇順で出したいと思っています。

order by unit,IF(staff_name='総務',staff_id desc,staff_id asc)
などと試行してみているのですがうまくできません。

どなたかうまい方法をご存じないでしょうか。

よろしくお願いいたします。
634NAME IS NULL:2012/04/03(火) 16:08:25.12 ID:???
総務だけマイナスにしたら?
635NAME IS NULL:2012/04/03(火) 16:24:06.69 ID:???
IF(staff_name = '総務', staff_id * -1, staff_id)
とかどう?
636NAME IS NULL:2012/04/03(火) 17:14:01.14 ID:???
>>635
レスどうもです。

select * from staff_list order by if(staff_name = '総務', staff_id * -1, staff_id)
こちらを実行してみたところ

(1,'範馬','総務')の行だけ一番上にきて、あとはすべてstaff_id昇順になってしまいました。
むぅ。
637636:2012/04/03(火) 17:16:46.37 ID:???
すみません。
すごい凡ミスでして

order by unit ,if(staff_name = '総務', staff_id * -1, staff_id)
でうまくいきました。
どうも大変失礼いたしました。と同時にありがとうございました。
638NAME IS NULL:2012/04/04(水) 17:56:50.11 ID:???
mysql 5.5.10

table hogehoge
inputdate data1 data2 data3
2012-02-16 ssssss wwwww yyyyyy
2012-02-17 xxxxxx xxxxx xxxxx
2012-02-18 null aaaaa vvvvv
2012-02-19 null null null
2012-02-20 null null null
2012-02-21 null null null
2012-02-22 xxxxxx ccccc fffff

とある時に、指定日の前日のデータが欲しい
例でいうなら
data1について、
2012-02-17を指定することによって2012-02-16のssssssを、
2012-02-22の日付を指定して2012-02-17のxxxxxxが得られ
るようにしたいのですが。

よろしくお願いします
639NAME IS NULL:2012/04/04(水) 18:19:49.45 ID:???
mysqlの日付演算詳しくないけど、
where inputdate = DATE_SUB(指定日, INTERVAL 1 DAY)
とかでだめかな
640NAME IS NULL:2012/04/04(水) 18:21:11.76 ID:???
あれ、求めてるのがなんか違うね。

select * from hogehoge
where inputdate < 指定日 and data1 is not null
order by inputdate desc
limit 1

とか?
641NAME IS NULL:2012/04/04(水) 19:03:39.65 ID:???
>>640
ありがとうございました。 m(_ _)m
それで期待通りのデータが得られました。
642NAME IS NULL:2012/04/08(日) 14:31:49.62 ID:/RIv7L6k
MySQL 5.0.77

SELECT name, MIN( score ) AS score, time FROM ranking2
WHERE time > SUBTIME( NOW(), '1 0:0:0' )
GROUP BY name UNION
SELECT name, score, MAX( time ) FROM ranking2
WHERE time > SUBTIME( NOW(), '1 0:0:0' )
GROUP BY name ORDER BY score LIMIT 50

ゲームのランキングを作っています。
name、time、scoreというカラムがあり
スコアの値が小さいほど高得点です。
ランキングには各ユーザ毎に24時間以内の「最新のスコア」と「scoreが一番小さいスコア」を
表示させたいです。

自力で頑張って上記のコードまでたどり着いたのですが
どうやらUNION以降のコードが誤っているようで
ユーザの最新タイムのレコードを取得してるつもりなのですが
結果は、最新タイムのものが得られるのですが、スコアの値が誤っている状態になってしまします。

よろしくおねがいします。
643NAME IS NULL:2012/04/08(日) 14:39:42.76 ID:???
644NAME IS NULL:2012/04/08(日) 14:52:29.42 ID:???
GROUP BYを使う場合はGROUP BYに書いたカラムと集約関数しか
SELECT句には書けないのが普通なんだがMySQLでは書けるんだな・・・
645642:2012/04/08(日) 15:44:20.18 ID:???
SELECT name, MIN( score ) AS score, time
FROM ranking2 WHERE time > SUBTIME( NOW(), '1 0:0:0' )
GROUP BY name

UNION

SELECT a.name, a.score, b.time
FROM ranking2 AS a
INNER JOIN ( SELECT name, MAX(time) AS time
FROM ranking2 GROUP BY name ) AS b
ON a.name = b.name
AND a.time = b.time
WHERE a.time > SUBTIME( NOW(), '1 0:0:0' ) ORDER BY score

解決しましま!
ありがとうございました!
646NAME IS NULL:2012/04/08(日) 15:58:00.61 ID:???
UNIONの前も間違ってるな

それと、ORDER BYは普通UNION後にかかる
MySQLではどうか知らんが
647NAME IS NULL:2012/04/15(日) 08:46:02.00 ID:???
#インデントが崩れる場合は http://pastebin.com/26BkXDHs をみてください。

--
-- 商品テーブルと、
--
create table items (
id serial primary key,
name varchar(255) not null,
price integer not null -- 単価
);

--
-- 販売テーブルがあるとする。
--
create table sales (
id serial primary key,
item_id integer not null references items(id),
count integer not null default 1, -- 個数
total integer not null, -- 単価 * 個数
created_at timestamp not null default current_datetime
)

--
-- 日付を指定して、その日の商品別販売金額合計を大きい順に表示したい。
-- どういうSQLを書けばいいの?
-- こんなかんじで書けたらいいんだけど。
--
select items.id, items.name
from items,
(select item_id, sum(total) as sum_total
from sales
where date(created_at) = '2012-04-01'
group by item_id) as totals
where items.id = totals.item_id
order by totals.sum_total desc;

648NAME IS NULL:2012/04/15(日) 09:35:41.74 ID:???
そのSQLで問題ないように見えるけど、どこがダメなの?
強いて言えば最初のselect句にtotals.sum_totalを追加するぐらいか
649NAME IS NULL:2012/04/18(水) 13:51:03.58 ID:???
SQLというよりテーブル設計の質問なんですがいいでしょうか?

ユーザごとの日々変化するデータを1日1レコードずつ保存するために
以下のようなテーブル構造を考えました。

USERSテーブル
 user_no (ユーザ番号 PK)
 latest_gen_no (最新世代番号)
 氏名その他の属性

RECORDSテーブル
 user_no (ユーザ番号 PK*)
 gen_no (世代番号 PK*)
 日々変化する値
*user_no, gen_no のペアでPK

GENERATIONSテーブル
 gen_no (世代番号 PK)
 date (日時)

全ユーザの最新世代の値を取得するべく、
select ... from users u, records r
where u.user_no=r.user_no and u.latest_gen_no=r.gen_no;
というSQLを発行すると、ものすごく時間が掛かります。

PKやインデックスの設定の仕方に問題があるのでしょうか?
そもそもテーブルの構成がまずいでしょうか?
650NAME IS NULL:2012/04/18(水) 15:12:15.14 ID:???
遅くならなさそうに見えるよ。
651NAME IS NULL:2012/04/18(水) 18:50:12.28 ID:???
USERS に (user_no, latest_gen_no) のインデックスを張るぐらいじゃない?
「氏名その他の属性」が結構あるなら、そのテーブルを総ナメするよりは速くなるだろう

あとは、現在のアクセスパスを調べて、NESTED LOOPになっているようなら
どうにかして他のJOIN方法になるように努力するぐらいしか思いつかん
652649:2012/04/18(水) 20:24:15.04 ID:???
>>650-651
ありがとうございます。
ちなみに、>>649のSQLを走らすと、20分以上掛かります。
USERSが10万件、RECORDSが10万×500世代以上あるからでしょうか。

explain(MySQL) を掛けてみると、USERSは全件ですが
RECORDSはtype=eq_ref, key=PRIMARYとなっていて、何となくindexは使われているような感じです。
653NAME IS NULL:2012/04/18(水) 20:38:00.80 ID:???
select count(*) from records where gen_no = 100;
の速度を調べてみるとか
usersのカラム数がどれくらいあるのか知らんけど、多いならuser_no latest_gen_noのインデックスはるとか
スワップが発生してないか調べるとか
654649:2012/04/18(水) 22:41:12.40 ID:???
>>653
>select count(*) from records where gen_no = 100;
一時間半以上掛かりました。
gen_noだけのindexがないので全件になりますね。

USERSテーブルのインデックスについてちょっと考えてみます。
655NAME IS NULL:2012/04/19(木) 13:51:23.18 ID:???
>>652
同条件で試してみたけど10秒程度で帰ってくるから
チューニングとサーバーのスペックが問題じゃないかな
MySQLスレで聞いた方が良さげ
656NAME IS NULL:2012/04/19(木) 13:57:05.08 ID:???
それでも10秒ぐらいかかるんだなぁという感想
657NAME IS NULL:2012/04/19(木) 14:45:34.88 ID:???
>>655
同条件?データのばらつき具合も?
658NAME IS NULL:2012/04/19(木) 16:40:59.66 ID:???
>>657
同条件は語弊があったね
分かっているスキーマとレコード数だけしか考慮してないよ
659649:2012/04/19(木) 21:32:25.92 ID:???
>>655
10秒ですか。そのくらいで収まってくれるといいんですが。
チューニングの方向を試してみます。
ありがとうございました。
660NAME IS NULL:2012/04/19(木) 23:12:34.23 ID:???
どうにも不思議なんでPostgreSQL(8.2 ←古い)で試したら100msぐらいだったよ。
mysqlとそんな差が出るとは思えないけど、参考になれば。

スペックもたいしたことないはず。
CPU pentium dualcore E2180
メモリ 1G
HDD 普通のHDD

あと、これもやっぱりおそい?
select count(r.*) from users u join records r
on (u.user_no=r.user_no and u.latest_gen_no=r.gen_no);
661NAME IS NULL:2012/04/20(金) 15:18:41.24 ID:???
あれ、1万ユーザでためしてたゴメンゴ
662NAME IS NULL:2012/04/21(土) 00:00:05.61 ID:???
MySQL5

開始日、終了日を持ったテーブルを日付単位に表示したいです。
tbl_job は、以下の構造です。

id, name, start_date, end_date
---------------------------
1, JOB1, 2012-04-01, 2012-04-03
2, JOB2, 2012-04-02, 2012-04-04

上記テーブルから以下のように日付単位でJOBを表示するSQLを教えてほしいです。

date, id, name
--------------------
2012-04-01, 1, JOB1
2012-04-02, 1, JOB1
2012-04-02, 2, JOB2
2012-04-03, 1, JOB1
2012-04-03, 2, JOB2
2012-04-04, 2, JOB2
663NAME IS NULL:2012/04/21(土) 00:11:40.28 ID:???
664649:2012/04/21(土) 09:56:41.04 ID:???
あれから my.ini を編集してメモリをたくさん割り当てたり
DB アクセス時に HDD からカコンカコンと心臓に悪い音がしていたので
データファイルを他のドライブに移動したりしてみたら
>>649の SQL が20秒ぐらいで帰ってくるようになりました。

皆さん、どうもありがとうございました。
大変助かりました。
665NAME IS NULL:2012/04/21(土) 10:07:01.22 ID:???
>HDD からカコンカコンと心臓に悪い音がしていたので

www
666NAME IS NULL:2012/04/24(火) 04:19:16.07 ID:k32ZaufP
SQLite3を使っています。

カラムがなかったらinsert
あったらupdateしたいのですが、
どういうSQLをかけばいいのでしょうか?

insert into t1(c1, c2) values("hoge",10)
update t1 set c2=10 WHERE c1="hoge"
このときc1はuniqueです。

よろしくお願いします。
667NAME IS NULL:2012/04/24(火) 04:26:46.11 ID:???
insert or replace
668NAME IS NULL:2012/04/24(火) 04:32:45.50 ID:???
>>667
ありがとうございます!
669NAME IS NULL:2012/04/27(金) 21:20:22.88 ID:???
厳密にはSQLの質問じゃなんですが・・・
ER図を書くのにいいツールってないですか。
コードと連携する機能はなくていいですが、できればMacで動くのがいいです。
テーブルやカラムにコメントやメモが書けるとうれしい。
670NAME IS NULL:2012/04/27(金) 21:36:46.25 ID:???
ERwin、ER/Studio、Object Browser ER、、、
フリーならDBDesignerぐらいか?
Macは知らん
671NAME IS NULL:2012/04/28(土) 05:53:13.60 ID:???
ERMaster使ってるけど
EclipseプラグインだからMacでも動くんじゃね?
672NAME IS NULL:2012/04/28(土) 07:23:30.50 ID:???
>>671
>ERMaster
これよさそうですね。ありがとうございます。
673NAME IS NULL:2012/05/04(金) 20:10:55.70 ID:???
mysqlの記録した内容ってどこにあるのですか?
例えばxamppの場合は、xamppフォルダの中のmysqlフォルダの
中に入ってるのでしょうか?
このフォルダの中身をコピーすると別のパソコンでも
記憶したmysqlのデータを扱えるのでしょうか?
674NAME IS NULL:2012/05/04(金) 20:24:50.21 ID:???
スレ違い。
675NAME IS NULL:2012/05/04(金) 20:46:42.32 ID:???
>>673
データファイルの場所ということなら、my.ini の中にデータフォルダ名の指定がある
Windows として、xampp なら c:\xampp\mysql\bin\my.ini
単体インストールなら C:\Program Files\MySQL\MySQL Server x.x\my.ini
あたりを探して設定を確認すべし

MySQL 総合 Part22
http://toro.2ch.net/test/read.cgi/db/1325079058/
676NAME IS NULL:2012/05/10(木) 15:29:16.87 ID:???
開始日、終了日という項目があって
その両者の期間が重ならないような
制約をかけたいんだけど、
どう書けばいいの?
677NAME IS NULL:2012/05/10(木) 15:56:53.04 ID:???
>>676
>>1

スレ違いの匂いもかなりしますけどね。
678NAME IS NULL:2012/05/10(木) 20:39:42.19 ID:???
言語がSQLか否かにかかわらず、書けないんだろうw
679NAME IS NULL:2012/05/10(木) 22:48:22.42 ID:???
>>676
制約というのがCHECK制約のことを指しているなら、無理。
CHECK制約では自分の行のデータしか参照できない。
開始日が終了日より前であること、ぐらいなら書けるけど。

別の行のデータを参照して期間が重複していないか調べたいなら、
トリガーを使うしかないかな。
アプリ側でやってもいいと思うけど。
680NAME IS NULL:2012/05/11(金) 01:45:10.81 ID:???
同じレコードの中にある開始日と終了日の関係をチェックしたいと言うことじゃないの?
681NAME IS NULL:2012/05/11(金) 02:05:04.91 ID:???
>>679
>CHECK制約では自分の行のデータしか参照できない
そういうDBもあるかもしれんが、それが標準的な仕様ではないと思うぞ
まあトリガかホストアプリでやった方が良いというのは同意するが

とりあえずSQL Serverでやってみた

CREATE TABLE TEST(
開始日 DATETIME ,
終了日 DATETIME
)
go
CREATE FUNCTION 期間ダブり件数(@開始日 DATETIME,@終了日 DATETIME)
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = COUNT(*) FROM TEST
WHERE (開始日 <= @終了日 and 終了日 >= @開始日)
RETURN @retval
END;
go
ALTER TABLE TEST
ADD CONSTRAINT 期間チェック
CHECK (dbo.期間ダブり件数(開始日,終了日) <= 1 ); --自分自身があるので1行はOK
go

これで行けてる気がする
ちがうDB使ってるなら知らん
682NAME IS NULL:2012/05/11(金) 02:20:37.98 ID:???
>>681
スゲー!できるんだ。

でも条件はこれな気がした。

WHERE (開始日 <= @開始日 and 終了日 >= @開始日) or
(開始日 <= @終了日 and 終了日 >= @終了日)
683NAME IS NULL:2012/05/11(金) 13:00:35.02 ID:???
>>682
それだと、たとえば5-10というデータが存在するときに、1-15ってデータが挿入できるんじゃね
684NAME IS NULL:2012/05/11(金) 19:36:20.25 ID:???
いや、1-15は引っかかるけど逆に4-9は取りこぼすな。
どっちにしろ、>>681で正解。
685NAME IS NULL:2012/05/11(金) 21:40:11.75 ID:???
postgres9.2では範囲型が導入されるので
まさにやりたいことが出来るぞ


まだリリースされてないがな
686NAME IS NULL:2012/05/14(月) 11:36:13.64 ID:rmHVUy71
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
千歳科学技術大学 グローバルシステムデザイン学科 深町 賢一
687NAME IS NULL:2012/05/15(火) 19:25:05.05 ID:bfF6xyzj
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
それよりゴキブリ高専卒どもはワシにさっさと謝罪せんか!
688NAME IS NULL:2012/05/16(水) 04:26:17.61 ID:/ibgSKqe
私が千歳科学技術大学 グローバルシステムデザイン学科 専任講師・理学博士:深町 賢一だが何か?
用があるなら、http://www.chitose.ac.jp/course/teacher/glo/000057.html
689NAME IS NULL:2012/05/16(水) 13:38:43.36 ID:???
すみません。
高専機械科卒なんですがお願いいたします。

以下のようなテーブルにて、あかさたなでGROUP BYしてそれぞれの件数を出力できないかどうか悩んでおります。

CREATE TABLE `name_list` (
kanji varchar(64),
yomi varchar(64)
)

INSERT INTO name_list (kanji,yomi) VALUES
('安部','あべ'),
('井口','いぐち'),
('臼井','うすい'),
('江本','えもと'),
('小川','おがわ'),
('柿本','かきもと'),
('木島','きじま'),
('九条','くじょう'),
('毛森','けもり'),
('小島','こじま'),
('佐藤','さとう'),
('しみず','')・・・・・・

勿論、各頭文字で一件ずつじゃないのですが
これを

あ行 5件
か行 5件
さ行 8件

のように集計をかけたいと思っておりますが
よい方法が思いつかず…

出力結果は、例でして出力した左側のフィールドはなんでもOKです。
右側のあかさたな行のそれぞれのレコード数がチェックできればOKです。

なにとぞよろしくお願いいたします。
690NAME IS NULL:2012/05/16(水) 13:48:05.62 ID:???
substr(yomi,1,1) 使ってみそ
GROUP BY とSELECT両方に
691NAME IS NULL:2012/05/16(水) 13:50:06.01 ID:???
おっと、ここは汎用SQLのスレか。
環境によって変わるので、使ってるDBMS名とかも書いてね
692NAME IS NULL:2012/05/16(水) 13:52:14.39 ID:???
SUBSTRING(yomi FROM 1 FOR 1)
これならほとんどいける?
693689:2012/05/16(水) 14:14:09.84 ID:???
申し訳ないです。テーブル内容書くのに悩んでいてテンプレを忘れておりました。
mysql 5.1です。

>>690 >>692
両方試してみます。
夕方までに再度レスします。
694689:2012/05/16(水) 14:19:25.55 ID:???
さっそく試してみました。

>>690,>>692のどちらも共に期待通りの結果が得られました。
あとは、あかさたな行にアプリケーションで整形します。
どうもありがとうございました。
695NAME IS NULL:2012/05/16(水) 14:35:20.72 ID:???
まあ ||'行' とかで連結する手もあるな
696689:2012/05/16(水) 14:54:12.43 ID:???
あ、いえ、行単位とは
頭文字あ〜おの行、か〜この行という単位でほしかったのです。
説明が足りず申し訳ございません。
697NAME IS NULL:2012/05/16(水) 15:02:24.53 ID:???
濁点半濁点も入れるとSQLだけでは長文になりそう
698NAME IS NULL:2012/05/16(水) 15:29:10.19 ID:???
できないことも無いけど、プログラムで弄れるならそっちのがよさげだね
699NAME IS NULL:2012/05/16(水) 20:31:41.07 ID:???
まず50音表テーブルをつくるんだ!
700NAME IS NULL:2012/05/17(木) 06:04:57.32 ID:???
「い」でもグループ化されそうに見えるけど、それでもよかったぽいね
701NAME IS NULL:2012/05/21(月) 14:42:55.02 ID:???
児童ポルノよりエロ漫画のバナー広告規制しろ!
http://c.2ch.net/test/-/cm/1279363779/i
702NAME IS NULL:2012/05/22(火) 01:24:53.30 ID:???
アクセス権限の付与でききたいことがあります。

GRANT UPDATE ON TABLE TO NANASHI

これだとNANASHIにTABLE表の更新を権限を与えるのですが
TABLE表の特定の列だけ権限を与える場合は
GRANT UPDATE[列名] ON TABLE TO NANASHI

でよろしいのでしょうか?
703NAME IS NULL:2012/05/22(火) 06:06:59.19 ID:???
[ ] じゃなくて ( )
704NAME IS NULL:2012/05/22(火) 16:57:48.26 ID:???
>>703
ありがとうございます。カッコが違ってたのですね。
705NAME IS NULL:2012/05/22(火) 19:32:46.34 ID:???
かっこわるい
706NAME IS NULL:2012/05/29(火) 00:34:19.88 ID:???
Oracleです

テーブルA
列a,列b,列c

テーブルB
列m,列n

テーブルC
列s,列t

WHERE
列b=列s or (列c=列m and 列n=列s)

で全列出力したいんですけど列b=列sでマッチすると列Bが全レコード結合されてしまいます
前者でマッチした時は列mと列nは出力しないようにしたいです
AとCは基本的に全列出力されるので、Bだけを条件によって出力されなかったりするJOINって作れますか
707NAME IS NULL:2012/05/29(火) 02:40:16.17 ID:???
>>706
欲しい出力結果がよくわからん
>前者でマッチした時は列mと列nは出力しないようにしたいです
条件によって出力される列の数を変えたいのか?
708NAME IS NULL:2012/05/29(火) 05:07:07.51 ID:???
>>706
unionに変えちゃまずい?

select a, b, c, null, null, s, t from A, C where b=s
union all
select a, b, c, m, n, s, t from A, B, C where c=m and n=s
709NAME IS NULL:2012/05/29(火) 05:10:05.44 ID:???
あと、
select distinct a, b, c,
case when b=s then null else m end as m,
case when b=s then null else n end as n,
s, t
from A, B, C
where b=s or c=m and n=s

みたいなのでもいける気はする
試してないから構文エラーとかあったらごめん
710NAME IS NULL:2012/05/30(水) 17:18:38.29 ID:FSJSgAvr

質問です。。
・Postgresql 9
・テーブルデータはざっくりですが、以下のような感じです。

table_name

id | state | name | pride
------+-------+-----------+----------------
1 | 2 | hoge1 | 01
2 | 1 | hoge2 | 02
15 | 2 | hoge3 | 02,03
16 | 1 | hoge4 | 02,04,05
33 | 1 | hoge5 | 04
34 | 1 | hoge6 | 01,05
35 | 1 | hoge7 | 01,02,03
36 | 1 | hoge8 | 01,02,03,04

実際は、もっとレコード数が多いと思っておいてください。

・やりたい事
ランダムに10件、とかselectして表示させたいのですが、
state = 1
である事が絶対条件で、
なおかつ
pride
の、
「01」が含まれるものの中から10件、ランダムに抽出
「02」が含まれるものの中から10件、ランダムに抽出
・・・以下、実際のデータでは20位まで続きます。

・・・といった内容を、出来るだけ簡潔に書こうと思うと、どんな方法があるでしょうか?

ちなみに、最終的にはidとnameを表示させるだけ、
phpでWEBに表示させます。

SELECT id,name FROM table_name WHERE state = 1 AND pride LIKE '%01%' ORDER BY RANDOM() LIMIT 10

これで「01」が含まれるものの中から10件、ランダムに抽出・・・
はできるのですが、コレを20回って・・・と思いますし、
SELECT id,name FROM table_name WHERE state = 1
で全部出力して配列に突っ込んでからソートしなおす、
というのもあまりスマートでないような気がして。。。

良い方法ないでしょうか。
711NAME IS NULL:2012/05/30(水) 19:47:18.85 ID:???
>>710
たぶん無い。
WITH RECURSIVEを使えば見た目スマートに出来そうな気もするが、
結局はSQL側でループするか、ホスト言語(PHP)側でループするかの違いしか無い気がします。
712710:2012/05/30(水) 20:15:33.99 ID:9ULM8hGf
>>711
おぅ・・・そうですか。

WITH RECURSIVEも調べてみましたが…うーん。。。ですね。
地味にやるしかないかなぁ。
ありがとうございます。
713NAME IS NULL:2012/05/30(水) 22:56:06.15 ID:???
質問です

sql server

一つのSQLで複数のテーブルを更新したいです。
★INSERT ALL、UNIONは使わない
★IDは日付6桁に下5桁は連番にする

insert into table1
select
case when (max(substring(table1.ID,1,8))) is null then
CONVERT(VARCHAR,GETDATE(),112) + '00001'
else
CONVERT(VARCHAR,GETDATE(),112) +right('0000'+convert(varchar,convert(float,SUBSTRING(max(table1.ID),9,5)+1)),5)
end as table1.ID
, CONVERT(VARCHAR,GETDATE(),120) as table1.ID
, 1 as table1.KYAKU_ID
, CONVERT(VARCHAR,GETDATE(),120) as table1.ENT_DT
, CONVERT(VARCHAR,GETDATE(),120) as table1.UPDT_DT
, 0 as table1.DEL_FLG
from table1
begin INSERT into table2
select
case when (max(substring(table2.ID,1,8))) is null then
CONVERT(VARCHAR,GETDATE(),112) + '00001'
else
CONVERT(VARCHAR,GETDATE(),112) +right('0000'+ convert(varchar,convert(float,substring(max(table2.ID),9,5)+1)),5)
end as table2.ID,
1 as table2.SEQUENCE,
1 as table2.SYOUHIN_ID,
2 as table2.SYOUHIN_KAZU,
1 as table2.SYOUHIN_TANKA,
20 as table2.TOTAL_PRICE,
CONVERT(VARCHAR,GETDATE(),120) as table2.ENT_DT,
CONVERT(VARCHAR,GETDATE(),120) as table2.UPDT_DT,
0 as table2.DEL_FLG
from table2

insert into table1
select
case when (max(substring(table1.ID,1,8))) is null then
CONVERT(VARCHAR,GETDATE(),112) + '00001'
else
CONVERT(VARCHAR,GETDATE(),112) +right('0000'+convert(varchar,convert(float,SUBSTRING(max(table1.ID),9,5)+1)),5)
end as table1.ID
, CONVERT(VARCHAR,GETDATE(),120) as table1.ID
, 1 as tabke1.KYAKU_ID
のところでエラーが出ます(table2でも同じ部分でエラー有り)
いろいろ考えましたがどこが間違ってるかわかりません
訂正など教えて貰えれば助かります。お願いします。
714713:2012/05/31(木) 02:10:28.08 ID:???
すいません
訂正です
IDは13文字
日付は8桁は下5桁は連番でした
715NAME IS NULL:2012/05/31(木) 02:57:37.82 ID:???
>>710-711
select id, name, rank() over (partition by match_pride order by random()) as rank_in_pride
from table_name join (values('01'), ('02'), ('03')) as t(match_pride) on pride ~ '.*' || match_pride || '.*'
where rank_in_pride <= 10

window関数も正規表現も使ったことないけど、こういうのできないのかな
716NAME IS NULL:2012/05/31(木) 03:01:20.79 ID:???
>>713
as table1.ID ってかけるもんなの?

ともあれ、エラーが出なくなるまでどんどん削って特定するのが楽だと思うよ。
あとはエラーメッセージを読むとか。
717710:2012/05/31(木) 09:09:09.66 ID:WUyDFWiQ
>>715
IDコロコロ変わってますけど、移動してるからデス。

さてはて、レスありがとうございます。
試してみましたが、そのままではエラー返って来ました。

ON pride ~ '.〜

辺りで引っかかっているようです。
argument of JOIN/ON must be type boolean, not type text
ってエラー出たので・・・ナニコレ。prideはbooleanじゃなくてtextだよ、と言ってるのかな?

ともあれ、Window関数ってテもあるんですねー。
勉強になります。。
718NAME IS NULL:2012/05/31(木) 13:06:18.51 ID:???
|| は文字列の連結。論理和は or だよ。
719NAME IS NULL:2012/05/31(木) 15:01:29.94 ID:???
on pride ~ ('.*' || match_pride || '.*')
こうすればいいのかな。
on pride like ('%' || match_pride || '%')
でいけるのならそれでも
720719:2012/05/31(木) 15:07:16.46 ID:???
>>717
argument of JOIN/ON // onの引数は
must be type boolean, // (その評価結果が)booleanであるべき
not type text // textじゃなくてね。

>>718
うん。
721719:2012/05/31(木) 15:25:47.42 ID:???
そうか、postgresqlだから、
(values('01'), ('02'), ('03')) as t(match_pride)

(select to_char(i, '00') as match_pride from generate_series(1, 20) as t(i)) as t
こうかけるかも。
722NAME IS NULL:2012/05/31(木) 21:24:00.96 ID:???
>>710
実際の行数ってどれくらいなの?
723NAME IS NULL:2012/05/31(木) 21:28:25.86 ID:???
あと、state=1の割合も教えて
indexが利きそうなくらいのカーディナリティの低さはある?
724NAME IS NULL:2012/05/31(木) 21:34:43.22 ID:???
ごめん s/低さ/高さ/
725NAME IS NULL:2012/05/31(木) 23:47:56.99 ID:???
とりあえずsqlかいたら?
726710:2012/06/01(金) 07:14:56.50 ID:ESzAumhQ
>>719
うーん、上手く行かないですね。。。
すいません、あんま時間がなくて、ちゃっちゃとコピペして試しただけなので、
エラーの理由とかチェック出来てませんが;;

>> 722
>> 723
今のトコ2000ぐらいです。

state=1の割合は9割弱でしょうか。
実際には、0、1、2、3が使われています。
ユーザのステータスを表していて(にしちゃ、スペルがヘンなのは無視してくださいw)
0 仮登録
1 使用中
2 停止中(ユーザ任意の停止)
3 利用禁止(管理者任意の強制停止)
こんな感じです。
727NAME IS NULL:2012/06/03(日) 12:37:09.01 ID:???
>>226
すまん家族サービスでレス遅くなった、
2000レコードとか少ないうちはこんなんでそこそこいけるかな、
select
priderec --pride
,id
,name
from
(
select
id
,name
,priderec
,rank() over(partition by priderec order by random()) as cnt_per_pride
from
(
--分解しレコードに変換
select
id
,name
,unnest(string_to_array(pride,',')) as priderec
from
table_name
where
state = 1
) a
where
-- 20以下のprideのみ
priderec::int <= 20
) b
where
--pride当たりは10件に制限
cnt_per_pride <= 10
order by
priderec::int
;

一度全部レコードに展開してる。
強引といえば強引なのでコストは結構高いよ。
prideの中身とレコード数自体が10万以上とか増えてくるとだんだん破綻してくると思う。

その時は
・1〜20で繰り返してレコードを抽出して処理
に切り替えたほうが良さそうだね。これもSQLだけでいけるよ
ただ、抽出でシーケンシャルだとこれも辛いので、
数が増えそうなら、テーブル構成の変更をおすすめするぞ。

このままに近いテーブル構成取るにしても、
prideを配列型にして、ginインデックスを貼って、
pride_arrの要素検索でインデクスが効くようにするといいと思う。
728NAME IS NULL:2012/06/03(日) 12:39:42.62 ID:???
まちがえた、>>226あてじゃなくて>>726だった
729NAME IS NULL:2012/06/12(火) 22:10:11.19 ID:7l5jIcyB
DBはSQLiteを想定してますが、MySQLでもpostgreSQLでも全然かまいません


採取リスト
|番号|名称|コード|登録日|登録者|公開|

というテーブルがあります。
イメージとして、とある物体がありまして、登録者が各自で次々と登録していきます。
各物体には登録者の間で共有されていてぶれのないコード(A-0001とか)があるものの、
名称に関しては、ある程度の裁量があるため、登録者によって表記にぶれが起きます。

|番号|名称 |コード | 登録日  |登録者|公開|
|01  |クラゲ |A-001|2012/6/1 | 田中 | 1  |
|02  |くらげ |A-001 |2012/6/2 | 鈴木 | 0  |
|03  |海月 |A-001 |2012/6/3 | 佐藤 | 1  |
|04  |クラゲ |A-001|2012/6/4 | 高橋 | 0  |
|05  |ひとで |A-002|2012/6/5 | 小林 | 0  |

番号はオートナンバーで主キー。
登録日はそのままINSERTされた日。
告知フラグは0か1で、外部に公開されていたら1です。

んで、ここから公開されてない行を抜き出すビューを作りたいんです。
CREATE VIEW 未公開リスト (番号, 名称, コード)
AS SELECT 番号, 名称, コード FROM 採取リスト WHERE 公開 = 0
みたいなSQLを走らせると、

|番号|名称  |コード|
|02  |くらげ |A-001|
|04  |クラゲ |A-001|
|05  |ひとで |A-002|

という風になってしまいますが「くらげ」と「クラゲ」で実質的に重複してしまいます。
これを例えば「コードを基準にして重複がないように選んだ」上で、
名称には、特定の登録者の名称を用いてまとめることはできないのでしょうか?
単に、DISTINCTを使うだけでは無理なようですが・・・。
730NAME IS NULL:2012/06/12(火) 22:33:02.68 ID:???
「特定の登録者の名称を用いてまとめる」の意味が分かんない
たぶん>>4だと思うけど
731NAME IS NULL:2012/06/12(火) 22:36:02.56 ID:???
特定の登録者の名称を用いてまとめる
って何?具体的にどういうこと?
732729:2012/06/12(火) 22:45:31.35 ID:7l5jIcyB
説明不足ですいません。


要は「クラゲ」と「くらげ」は同じものを指しているのに、カタカナと平仮名の表記の違いから別物だと認識されてしまうので、
登録者の鈴木の用いてる名称(この場合は「くらげ」)に合わせて、それに統一させることはできないのか?ということです。


>>729の例だと、

|番号|名称 |コード | 登録日  |登録者|公開|
|01  |クラゲ |A-001|2012/6/1 | 田中 | 1  |
|02  |くらげ |A-001 |2012/6/2 | 鈴木 | 0  |
|03  |海月 |A-001 |2012/6/3 | 佐藤 | 1  |
|04  |クラゲ |A-001|2012/6/4 | 高橋 | 0  |
|05  |ひとで |A-002|2012/6/5 | 小林 | 0  |



ここからSELECT文に「WHERE 公開フラグ = 0」の条件を入れて検索したときに


|番号|名称  |コード|
|02  |くらげ |A-001|
|05  |ひとで |A-002|


こういう結果が欲しいんです。
733NAME IS NULL:2012/06/12(火) 23:04:25.98 ID:???
>>732
一意になる基準を決めれ。番号か名称か登録日で一番小さいものとか。
734729:2012/06/12(火) 23:08:17.40 ID:7l5jIcyB
特定の登録者(最も正しい表記をしてくれるであろうと期待される人間)の名称を用いる、という基準を一応持っています。
735NAME IS NULL:2012/06/12(火) 23:10:13.69 ID:???
ぱっと思いつくところだと、
postgresならwindow関数使って、
同じコードでの区間集計で、ひらがな、カタカナ、漢字ならの中で、order byでこの順に並べ替えることによって、
常に最初のもの、とか最後のもの、(或いはN番目のもの)を選択するって感じならできると思うが、
ひらがなに統一とか、鈴木の書いたケースに統一っていのはなかなか難しいと思う。
DBから見たら違うものでしかないし、判断できないから。
ひらがな、カタカナ、漢字の区別をつけて値を返す関数を作成すれば出来そうだけどね。
736NAME IS NULL:2012/06/12(火) 23:16:38.58 ID:???
>>734
その優先順位のデータがあるならばできなくはないが、標準SQLの範囲では
あまり効率はよくないだろうな。
737NAME IS NULL:2012/06/12(火) 23:22:14.75 ID:???
指定した人がいないコードとかではどうすんの?
仕様が曖昧すぎて出せない
738NAME IS NULL:2012/06/12(火) 23:28:25.39 ID:???
まあ、設計の話はスレ違いだが
普通の設計では、コードと正しい名称を持ったマスタテーブルを別にもつんだが
739729:2012/06/12(火) 23:35:24.67 ID:7l5jIcyB
なるほど・・・・特定の登録者を用いた名称、というのは難しいんですね・・・
ありがとうございました。

>>737
確かにそうですね・・・

>>738
詳しくお願いできますか?

その正しい名称というのは事前に入力しておかないといけないのでしょうか、やはり?
740NAME IS NULL:2012/06/13(水) 00:14:38.41 ID:???
>>739
特定の登録者って、どうやって特定するのか決めろって言ってるんだが
一定の条件で機械的に決まるなら出来るだろうって言ってる
人間が判断して決めないとダメなら、その判断した結果を入力しておかないと無理
741729:2012/06/13(水) 00:22:53.37 ID:emGltIb9
>>740
登録者の優先順位をつけたテーブルを事前に用意してそこを参照する・・・というのは少し複雑ですね。
742NAME IS NULL:2012/06/13(水) 03:59:39.24 ID:???
>>734
その鈴木さんのレコードがなかったら誰を頼りにするんだろ
743NAME IS NULL:2012/06/13(水) 04:00:12.89 ID:???
ごめんまるかぶりでした。
744NAME IS NULL:2012/06/13(水) 04:04:08.75 ID:???
ってだけだと申し訳ないので…

>>739
A-001は鈴木さんも田中さんも高橋さんも選ばないといけないのかな。
たとえばコードに対応する名前を入れられたら、それをマスタ登録して、
ほかの人は自動で入力されるようにしたら、統一できるし楽にならないかな。

あとは優秀な鈴木さんにマスタの名称を変更させる機能を提供するとかで。
745NAME IS NULL:2012/06/13(水) 06:56:58.46 ID:???
そもそも複数登録できるようになってるのがおかしいとは思うんだけど、そうなってる理由ってなんだろう?気になる。
登録の際にコードが被ったら弾くか、名称の変更を行なって登録するのが普通だとは思うが。
746NAME IS NULL:2012/06/13(水) 08:14:27.75 ID:???
>>734
登録者の優先順位をこんな具合に人間が決めていいのかな?

create table 採取リスト (番号 serial, 名称 varchar(100), コード varchar(100), 登録者 varchar(100), 公開 int);
create table 優先 (登録者 varchar(100), 優先度 int);

insert into 採取リスト (名称, コード, 登録者, 公開) values ('クラゲ', 'A-001', '田中', 1), ('くらげ', 'A-001', '鈴木', 0), ('海月', 'A-001', '佐藤', 1), ('クラゲ', 'A-001', '高橋', 0), ('ひとで', 'A-002', '小林', 0);
insert into 優先 values ('田中', 0), ('鈴木', 4), ('佐藤', 1), ('高橋', 2), ('小林', 3);

select 番号, コード,
  (select 名称 from 採取リスト join 優先 using (登録者) where 採取リスト.コード = 未公開.コード order by 優先度 desc limit 1) as 名称
from 採取リスト as 未公開 where 公開 = 0 group by コード;
747729:2012/06/13(水) 08:42:47.08 ID:N2kuDrG0
皆さん本当に丁寧にありがとうございます

SQLiteはusingとか使えないっぽいです

確かに最初にコードと名称が打ち込まれたら、以降は名称の入力を許さないというのもあると思います・・・。
最初に間違った名称が入力された場合、以降はそれに統一されかねないのがややネックですが
748NAME IS NULL:2012/06/13(水) 09:54:56.51 ID:???
USING使えなかったらON に置き替えりゃいい
749NAME IS NULL:2012/06/13(水) 17:36:35.61 ID:KVKN/UOS
2ch風スレッド掲示板を作成しているのですが
そこのトップページ作成時のSELECT文の書き方に迷ってしまったため、
お教えいただければと思っております。

・RDBMS
MySQL 5.1

・テーブル構造

//スレッドテーブル

CREATE TABLE IF NOT EXISTS `bbs_master` (
`threadId` int(11) unsigned zerofill NOT NULL auto_increment, //スレッドID
`status` tinyint(4) unsigned default '1', //スレッドのステータス(スレストとか)
`subject` text, //スレタイ
`res_count` int(11) NOT NULL default '0', //現在のレスの数
`createdDate` datetime default NULL, //スレッド作成日
`updatedDate` datetime default NULL, //最終更新日
PRIMARY KEY (`threadId`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


//レステーブル

CREATE TABLE IF NOT EXISTS `bbs_data` (
`replyId` bigint(20) unsigned NOT NULL auto_increment,
`status` tinyint(4) unsigned default '1', //レスの状態(あぼーんとか)
`threadId` int(11) unsigned zerofill default NULL, //紐付されるスレ
`username` varchar(32) default NULL, //ユーザ名
`body` text, //レス本文
`mailAddress` varchar(128) default NULL, //メールアドレス
`createdDate` datetime default NULL, //レスした日
PRIMARY KEY (`replyId`),
KEY `status` (`status`),
KEY `threadId` (`threadId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

//外部キー
ALTER TABLE `bbs_data`
ADD CONSTRAINT `bbs_data_ibfk_1` FOREIGN KEY (`threadId`) REFERENCES `bbs_master` (`threadId`) ON DELETE CASCADE ON UPDATE CASCADE;



スレッドテーブル側にてスレッド一覧を持ち
レステーブル側でレスをスレッドIDと紐付て>>1から持つように作成しております。


トップページにおきましては、2chの板トップページと同じく
最新の書き込みのあったスレッドを10件程度 それぞれ最新のレスを10件程度と共に載せようと思うのですが
そのSELECT文の書き方で行き詰ってしまいました。

10件ずつレスを呼び出す福問い合わせをスレッドの分だけ回せないかなどと考えているのですが
使う機能の名前や大まかな流れ等でもお教え頂ければと思います。

よろしくお願いいたします。
750NAME IS NULL:2012/06/13(水) 18:09:41.00 ID:???
泥臭く書けばどうにでもできるような。
まずは動くようにしてみたら?パフォーマンスに問題がなければアプリで制御してもいいんだよ
751749:2012/06/13(水) 20:11:07.42 ID:KVKN/UOS
>>750
返信ありがとうございます。

個人のサイトで仲間内とネトゲーの情報をやり取りする程度で使うつもりですので
パフォーマンスは全く問題ではなく、極端な話
一旦、
SELECT threadId,subject..... FROM bbs_master ORDER BY bbs_master.updated DESC LIMIT 10
でクエリー回してアプリで受け取り
その後、そのループ内でレスを拾うクエリーを都度投げるですとかならできるのですが

自分のレベルアップを狙って、一回のSQL文でスレッドごとにレスを10件ずつに制限しながら10スレッド分引くにはどうすれば?と考えたときに行き詰ってしまいました。

ヒントや大まかな流れ等だけでも結構ですのでなにとぞよろしくお願いいたします。
752NAME IS NULL:2012/06/13(水) 20:13:59.38 ID:???
この前の続きかな、
なんだ、そういうのを考えるのが楽しいんじゃんよ。

スレッドマスタなのにbbs_master?と思ったらカテゴリは無いのか。
ってのはいいとして、

・アプリで回す
bbs_masterから最新10スレッド取って来る->アプリでそのスレッドに付き最新10レス取得をループ

・1クエリで済ませる
bbs_masterから最新10スレッド取ってきて(サブクエリ)、
そのスレッドidにつき、bbs_dataテーブルとjoinして最新レス10件取ってきて、
スレッドid(+その他カラム)でgroup byして、
スレッドの更新時刻 降順->レスの更新時刻降順でorder by

な感じ?

クエリを組むときは、
目的の結果を得るためにどうしたらいいのか、
一歩一歩頭で組み立てながらクエリを組むと良いのでは。
753749:2012/06/13(水) 21:08:20.73 ID:KVKN/UOS
>>752
ご返信ありがとうございます。
テーブルの命名も些末なものだったようで大変恐縮です。
あと申し訳ないのですがこの件は、初診(?)となります。

自身のレベルアップも目的ですので
事例を探しながら組もうと頑張っていたのですが
複数件返される副問い合わせを元にしてクエリーを回すという部分で
どうも混乱してしまって、後頭部が痛くなってきたところで降参してしまいました。
努々、楽しめるよう肝に銘じたいです。

お教え頂いた流れ上で再度挑戦してみます。

どうもありがとうございます。
754NAME IS NULL:2012/06/13(水) 21:16:25.81 ID:???
あぁ、
スレ取ってきて、
それを元にselect句で相関サブクエリでもいいか、ていうか、こっちの方がシンプルか
まぁもがきながらでも自分で組んでみた方がいいよ
755NAME IS NULL:2012/06/13(水) 23:22:46.91 ID:???
よく考えたらselect句じやダメだな
756NAME IS NULL:2012/06/14(木) 15:01:32.69 ID:???
スレッドidごとに10件てところが面倒だろうと思ってたけど、そこはスルーされてるんだな。。
757749:2012/06/14(木) 15:54:05.36 ID:???
すみません、いまだに目標に到達できません。

>>755
うー、select句じゃダメなんですか。
仕事もあるので、これに注力しきれてないのですが
MySQLのリファレンスから機能を総洗いしてみて使えるのを拾っていこうかと考えています。

>>756
あれれ、スルーしましたか??
758NAME IS NULL:2012/06/14(木) 16:02:40.55 ID:???
select レス from bbs_data where スレ in (select スレ from bbs_master where 最新10スレ) and スレごとに最新10レス
759758:2012/06/14(木) 16:03:41.39 ID:???
>>757
ううん、アドバイスしてる人がそこをスルーしてるなっておもって。
760758:2012/06/14(木) 16:07:26.65 ID:???
select レス from bbs_data where スレ in (select スレ from bbs_master where 最新10スレ)
and exists (select * from bbs_data where スレ = スレ and レス > (select max(レス) from bbs_data where スレ = スレ) - 10)

っぽい感じになるのかな。
761758:2012/06/14(木) 16:12:11.84 ID:???
ん?
select レス from bbs_data join bbs_master using (スレ)
where スレ in (select スレ from bbs_master where 最新10スレ)
and レス > スレ.res_count - 10
これでいいのかも
762749:2012/06/14(木) 16:44:30.11 ID:???
>>758
ありがとうございます。

本職中なのでまだ試してないのですが
それで完璧なように見えます。
自分で作っておいてなんですが、res_count - 10で1スレあたりの数を制限できるのに全く気付いてませんでした。

どうもありがとうございました。
763NAME IS NULL:2012/06/20(水) 21:35:39.18 ID:???
A Table
a1 a2
-- --
1 A
3 B
5 C
6 D

B Table
b1 b2
-- --
2 E
4 F
6 G

を select で
a1 a2 b1 b2
-- -- -- --
1 A null null
3 B 2 E
5 C 5 F
6 D 6 G

にしたいけど、どうしたらいいでしょうか?
764NAME IS NULL:2012/06/20(水) 21:36:25.86 ID:???
すみません
a1 a2 b1 b2
-- -- -- --
1 A null null
3 B 2 E
5 C 4 F
6 D 6 G

でした
765NAME IS NULL:2012/06/20(水) 21:44:17.71 ID:???
基準がよくわからん
766NAME IS NULL:2012/06/20(水) 21:45:07.86 ID:???
意味がわからん
それぞれの列にどういう意味があって、どういう条件で同じ行にしたいの?

a1を超えない最大のb1?
767NAME IS NULL:2012/06/20(水) 21:46:49.97 ID:???
>>763-764
条件がよく分からんがこういうことか?
select
A.a1,A.a2,B.b1,B.b2
from
A
left outer join B on(
TO_NUMBER(A.a1)=TO_NUMBER(B.b1)+1 or
TO_NUMBER(A.a1)=TO_NUMBER(B.b1))
;
768NAME IS NULL:2012/06/20(水) 21:48:55.63 ID:???
たぶんもうちょっと変な要望があるとおもう
769NAME IS NULL:2012/06/20(水) 22:29:33.14 ID:???
これはかなりの難問。
条件は、A tableとt B tableの最後のデータを横一列ににするとか。
積み上げ棒グラフを作るようなイメージ。
770sage:2012/06/21(木) 12:06:59.60 ID:oEiJL9az
すまん、763です。具体的に言うと
株価Tab(時刻、株価)
為替Tab(時刻、$\為替レート)
を株価のテーブルをメインにして
SELECT時刻、株価、$|為替レート
にしたいんだけど株価と為替の時刻は当然一致していないけど、
株価の時刻からみて最新の為替レートを表示したいんです。
よろしくおねがいします。
771NAME IS NULL:2012/06/21(木) 12:14:37.93 ID:???
つまり、>>766で正解?
772NAME IS NULL:2012/06/21(木) 12:50:26.19 ID:???
ぽいね
773NAME IS NULL:2012/06/21(木) 18:04:51.54 ID:uEysGvXe
・DBMS名とバージョン: Access2003
・テーブルデータ: ID、作業開始日、作業完了日、作業区分
・欲しい結果
 一定期間の作業開始日及び作業完了日を日付別にカウントしたい。
・説明
例えば、2012/06/01から2012/06/07の期間を指定した場合、以下の様に取得したい。

日付     作業開始 作業完了
2012/06/01    10      10
2012/06/02     5      5
2012/06/03    20      15
2012/06/04    21      20
2012/06/05     7      10
2012/06/06    10      15
2012/06/07     4      10
774NAME IS NULL:2012/06/21(木) 18:13:03.94 ID:???
>>773
>>8が関連
775NAME IS NULL:2012/06/21(木) 18:26:51.32 ID:???
>>770
>すまん、763です。具体的に言うと

次回からは、初めから具体的に言ってくれ。
776NAME IS NULL:2012/06/21(木) 19:09:40.62 ID:???
>>773
作業開始、完了ってのはドコで見分けるの
作業区分?完了日がnullとか?
777NAME IS NULL:2012/06/21(木) 19:14:27.33 ID:???
>>770
こうかな?

select *
from  A T1
    left outer join
    B T2
    on T1.a1 >= T2.b1
where  not exists (
        select *
        from  B T3
        where  T1.a1 >= T3.b1
        and   T2.b1 < T3.b1
    )
order by a1
;
778NAME IS NULL:2012/06/21(木) 19:15:57.18 ID:???
>>773-774
>>5もじゃね?
779NAME IS NULL:2012/06/21(木) 19:19:58.50 ID:???
>>776
単に完了日だろ
780773:2012/06/21(木) 20:58:02.92 ID:???
>>776
日付が入っている=カウント(作業開始、作業完了として)するになります。

>>774,>>778
参考にします。
781NAME IS NULL:2012/06/21(木) 21:59:23.05 ID:???
ああ、しかしAccessか
再帰問合せもCASEもないっぽいねえ
782776:2012/06/21(木) 23:46:34.36 ID:???
>>780
単一クエリで処理する方法は分からないから UNION で

SELECT 作業開始日 AS 日付, Count(作業開始日) AS Count開始日, NULL AS Count完了日
FROM テーブル1
WHERE 作業開始日 IS NOT NULL
GROUP BY 作業開始日
UNION ALL
SELECT 作業完了日, NULL, Count(作業完了日) AS Count完了日
FROM テーブル1
WHERE 作業完了日 IS NOT NULL
GROUP BY 作業完了日
783NAME IS NULL:2012/06/22(金) 03:19:48.89 ID:???
>>782
それだと同じ日付が開始と完了で2回でるんじゃね
作業開始日、作業完了日でカウントしてFULL OUTER JOINで行けると思うけど
ACCESSってFULL OUTER JOIN使えないんだっけ?
ダメなら、作業開始日と作業完了日でUNIONして日付マスタっぽいのつくって、
相関サブクエリでそれぞれの件数とれば行けるかと
784NAME IS NULL:2012/06/22(金) 04:06:26.34 ID:???
UNIONした結果を日付でGROUP BYして、SUMすればいいとも思う
785NAME IS NULL:2012/06/22(金) 09:51:42.29 ID:???
無茶苦茶強引にやるなら
select A.日付,A.作業開始,B.作業完了
from
(select A1.日付,A2.作業開始
from
(select 作業開始日 as 日付 from テーブル
union select 作業完了日 as 日付 from テーブル
) as A1
left outer join
(select 作業開始日,count(*) as 作業開始 from テーブル) as A2 on (A1.日付=A2.作業開始日)
) as A
left outer join
(select 作業完了日,count(*) as 作業完了 from テーブル) as B on (A.日付=B.作業完了日)
;
でいけそうな気がする
786NAME IS NULL:2012/06/22(金) 12:03:08.14 ID:???
>>783
きっとレポートで集計するんでしょ
単純にクエリが欲しいなら 784 で良いし
787NAME IS NULL:2012/06/23(土) 10:02:37.81 ID:???
id5とid10という2つの情報しかないのですが
id5がもつc1とid10がもつc1を交換するとき
どういうクエリーをかけばよいでしょうか?

1.select c1 from t where id=5 or id=10 order by id
2.begin transaction
3.update t set c1=? where id=5 (?は1でとったid10のc1値)
4.update t set c1=? where id=10 (?は1でとったid5のc1値)
5.commit

自分の能力ではこんな手順が限界ですが
サブクエリーを駆使したらupdate1文でいけたりするのでしょうか?
もしできたらどんな感じの文になるか教えていただきたいです
788NAME IS NULL:2012/06/23(土) 10:18:22.80 ID:???
>>787
ちょっとはぐぐればいいと思うんだが…

http://blog.livedoor.jp/satoyansoft/archives/65408122.html
789NAME IS NULL:2012/06/23(土) 10:28:25.87 ID:???
>>788
ありがとうございます

開発環境がMySQLとSQLiteなのでちょっと厳しそうですが
SQLite以外では出来そうなことはわかったので
がんばってググってみます
790NAME IS NULL:2012/06/23(土) 11:39:50.65 ID:???
sqlite は、だめだな。

今、手近なマシンで試したら...

SQLite version 3.6.13
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema t
CREATE TABLE t (a, b);
sqlite> select * from t;
1|1
2|2
3|3
sqlite> update t set b = case a
sqlite> when 1 then (select b from t where a = 3)
sqlite> when 3 then (select b from t where a = 1) end where a in (1, 3);

おっ、エラーにならないじゃん。

sqlite> select * from t;
1|3
2|2
3|3

Orz…

まだ、エラーになる方がマシだよ。
791NAME IS NULL:2012/06/23(土) 17:21:24.60 ID:???
>>790
sqliteよくしらないが、それテーブルに相関名付けても同じなのか?
792NAME IS NULL:2012/06/23(土) 20:11:25.37 ID:???
・DBMS名とバージョン: SQLServer2008R2
・テーブルデータA: No.,テーブルB用id
・テーブルデータB: id,No.,nvarchar(MAX)
・欲しい結果
 テーブルデータAのNo.でクエリすると紐付いているテーブルBの文字列をBのNo.昇順に連結したデータを取得したい

A No id
  -- --
  1 a
  2 b

B id no text
  -- -- ----
  a 1 あ
  a 2 い
  a 3 う
  b 1 か
  b 2 き

結果
 a あいう
 b かき

・説明
 8000文字を超える文字列を扱いたいがSQLServerの設定はいじれない
 ストアドは使用可能
 アプリ側で対応も出来るが可能ならSQL側で完結させたい
793NAME IS NULL:2012/06/23(土) 20:17:14.44 ID:???
>>792
http://blog.livedoor.jp/oolv/archives/370268.html

すみません。。仕事中なので手抜き返答で許してください。
794NAME IS NULL:2012/06/23(土) 21:51:49.79 ID:???
>>791
いくつかやったけど、同じだった。

まあ、相関名つけたら挙動が変わるというのも、それはそれでどうかと思うし。
795NAME IS NULL:2012/06/23(土) 22:25:59.36 ID:???
>>792
with t as
(
select id,no,cast(text as nvarchar(max)) as text from B where no=1
union all
select B.id,B.no,t.text+B.text from t
join B on B.id=t.id and B.no=t.no+1
)
select t.id,t.text from t
join A on A.id=t.id
where
t.no=(select MAX(no) from B where id=A.id)
;
796795:2012/06/23(土) 22:32:32.40 ID:???
補足
noは1から連番で振ってある事が前提

再帰クエリでやってはみたが、どう考えてもストアド作る方がいいな、これ
ストアド扱うスレってあったっけ?
797792:2012/06/23(土) 22:44:44.09 ID:???
>>793
おお、XMLドキュメントとして扱うとは!
すごく盲点でした

>>795
こ、これは高度すぎて初心者の自分にはわけわかめ
精進します

お二方ありがとうございました
798NAME IS NULL:2012/06/24(日) 01:06:38.36 ID:xl2vNYYv
【質問テンプレ】
・DBMS名とバージョン sqlite3
・説明
今はUNIQUE制約をつけると支障が出るのでUNIQUEはつけず
準備ができ次第将来的にUNIQUEを追加する予定です
※今は使わない不要なカラムにDEFAULTを空文字で埋めていて
そのためUNIQUEがつけられません

あとでUNIQUE制約を追加する方法ですが
ALTER TABLE t ADD UNIQUE (c1, c2)では
UNIQUEのところでエラーが出てしまい働かなかったので
CREATE UNIQUE INDEX t_uni on t (c1, c2)にしたところ作成できたのですがこれでいいのでしょうか?
両者の違いがわかりませんがテーブルを変更するのはALTERだったと思うので
こんなんでいいのか困っています
問題があれば正しいSQLとアドバイスをお願いしたいです
799NAME IS NULL:2012/06/24(日) 21:06:00.04 ID:5hY+sk/g
DBMS名とバージョン PostgreSQL 8.4

仕事でどうしてもsql触らないといけなくなったので今朝から勉強してるんですが
一度構文エラーだとかを起こしてしまった後に他のSELECT文だとか打って
実行しようとして;を打った後Enterを押してもスルーされてしまうのですが
その解決方法教えていただけませんか?

800NAME IS NULL:2012/06/24(日) 21:28:26.43 ID:???
どこで打ってんだよ
トランザクション中であれば、
無視されて当然だしそれで正解。
801NAME IS NULL:2012/06/24(日) 21:43:07.20 ID:???
>>800
なるほど
何かヒントになりそうです
どうもありがとうございます。
802NAME IS NULL:2012/06/25(月) 21:41:39.03 ID:???
マスターとなるテーブル内で「*」を使うのってありなんですか?
目印の代わりにつけたみたいなんですが
検索とかで影響でないんでしょうか?
ちなみにSQL Server 2005 です。
803NAME IS NULL:2012/06/25(月) 22:46:55.57 ID:???
>>798
SQLiteはalter tableで制約の変更はできないみたいね
どっちにしろユニークインデックスで問題なし

>>802
質問の意味が分からん
SQLで「*」はワイルドカードではないよ
select句で使えば「全ての列」という意味にはなるけど
804NAME IS NULL:2012/06/26(火) 00:23:54.78 ID:???
>>802です
スレ違いでしたね

805NAME IS NULL:2012/06/26(火) 00:33:48.71 ID:???
スレ違いではあるけれど。

目印って書いてるから、カラム名に*をつけたいってことだよね。
id* みたいな。

それができるRDBMSがもし存在したとしても、するべきじゃないよ
806NAME IS NULL:2012/06/26(火) 02:24:20.83 ID:???
データとして'*'が入ってるってことか?
807NAME IS NULL:2012/06/27(水) 19:59:21.13 ID:???
Sqliteで列(カラム)の数を取得したいんですがどうすればいいですか?
808NAME IS NULL:2012/06/27(水) 20:56:41.56 ID:???
sqlの中でってこと?
それともただ単にわかればいいの?
809NAME IS NULL:2012/06/27(水) 21:26:38.95 ID:???
単にわかればいいです、androidソース側から
810NAME IS NULL:2012/06/28(木) 04:58:22.71 ID:???
であれば、
pragma table_info(テーブル名)
の結果行数を数えれば良い
811NAME IS NULL:2012/06/28(木) 09:07:39.22 ID:???
なるほぢど、やってみます
812NAME IS NULL:2012/06/28(木) 20:50:45.25 ID:CzuyUlLS
勤続年数をyy.mmの形で出したくて
datediff(year,入社月日,今日)と例えばしてるのですが、yearの部分の変更で対応できるのでしょうか?
813NAME IS NULL:2012/06/28(木) 21:33:37.70 ID:???
DATEDIFFでググったら出てきたぞ
814NAME IS NULL:2012/06/28(木) 23:11:08.14 ID:CzuyUlLS
>>813
教えてよ
815NAME IS NULL:2012/06/29(金) 09:01:46.27 ID:???
自分で試すだけやん…
816NAME IS NULL:2012/07/01(日) 11:30:47.51 ID:???
table1
id | name
-----------
0 | りんご
1 | みかん

table2
no | id
----------
0 | 0
1 | 0
2 | 1
3 | 1
4 | 1

この二つのテーブルから以下の結果を得るSQLの書き方を教えてください
id | name | num
-------------------
0 | りんご | 2
1 | みかん | 3

select id, name, (select count(code) from table2 as t2, table1 as t1 where t1.id=t2.code) as num from table1;
自分で考えた↑では2行ともnumが5になってしまいました
817NAME IS NULL:2012/07/01(日) 11:39:39.24 ID:???
SELECT id, COUNT(id)
FROM table2
GROUP BY id

の結果と table1 を結合
818NAME IS NULL:2012/07/01(日) 13:58:25.83 ID:???
>>817
select t1.id, t1.name, t2.id, count(t2.id) from table1 as t1, table2 as t2 where t1.id = t2.id group by t2.id
で目的の結果が得られましたが、table1にのみ(2,いちご)を追加しても
id | name | num
-------------------
0 | りんご | 2
1 | みかん | 3
2 | いちご | 0
とはなりらずに、追加前と同じ結果でした
片方のテーブルにない物も集計対象にするにはどうしたらよいのでしょう?
819NAME IS NULL:2012/07/01(日) 14:04:24.42 ID:???
from句以下を
table1 as t1 left outer join table2 as t2 on t1.id=t2.id group by t2.id;
にしろ
820NAME IS NULL:2012/07/01(日) 14:33:16.91 ID:???
>>818
少し頭を使えよ
821NAME IS NULL:2012/07/01(日) 23:33:46.27 ID:???
一方に無いものも欲しい
という場合は、とりあえず「外部結合」って奴を思い出してあげてください。
822816:2012/07/02(月) 23:37:11.47 ID:???
>>819, 821
819のやり方でうまくいったと思ったのですが、table1に(3,バナナ)を追加して
table2で未使用のレコードが2つになっても
id | name | num
-------------------
0 | りんご | 2
1 | みかん | 3
2 | いちご | 0
のままでした
そこで
select t1.id, t1.name, t2.id from table1 as t1 left join table2 as t2 on t1.id = t2.id;
なviewを作って
そのviewにたいして
select t1.id, t1.name, count(t2.code) from view1 group by id;
としたところ欲しかった
id | name | num
-------------------
0 | りんご | 2
1 | みかん | 3
2 | いちご | 0
3 | バナナ | 0
が得られました。
ありがとうございます。

823NAME IS NULL:2012/07/03(火) 00:02:49.22 ID:???
t2側でgroup byしてるからじゃないの?
select t1.id, t1.name, count(t2.id) from table1 as t1 left join table2 as t2 on t1.id = t2.id group by t1.id, t1.name
でいいような

しかしgroup byがそんな変な動きするのってMySQLだっけ?
824NAME IS NULL:2012/07/03(火) 22:09:12.59 ID:???
>>823
group byがっていうか
>select t1.id, t1.name, t2.id from table1 as t1 left join table2 as t2 on t1.id = t2.id;
>なview
セレクトリストでidがかぶってるのにエラーにならんのかと...
たぶんt1.idがidって名前で生きてるからうまくいってるんだと思うが

>select t1.id, t1.name, count(t2.code) from view1 group by id
これ通すのもMySQLぐらいか
825NAME IS NULL:2012/07/04(水) 23:03:36.18 ID:???
sqliteで select * from test where a = '1' or a = '2'

って感じで取得してるんですが、
上記のwhereで指定した条件の順番に結果がかえってこないんです。

理想としてはaが1のデータが配列の0番目の要素、2のデータが配列1番目の要素って感じに、
where句で指定した順に取得したいんです

そんなことは無理なんでしょうか?
ちなみにソートでは対応できない任意の順番なのでorder byでは無理です。

ちなみにunionでselect文で繋いでも、where句で指定した順番では帰ってきませんでした。
暫定対応としてselect文を一度ずつ実行して配列に入れています。
826NAME IS NULL:2012/07/04(水) 23:09:29.97 ID:???
無理。
827NAME IS NULL:2012/07/04(水) 23:12:50.93 ID:???
SQLって使えねーな
ありがとうございました
828NAME IS NULL:2012/07/04(水) 23:18:36.01 ID:???
自分の力量のなさをツールのせいにするなよ
829NAME IS NULL:2012/07/04(水) 23:23:29.28 ID:???
うるせー
PHP板からいちいちやってくんなカス
830NAME IS NULL:2012/07/04(水) 23:24:42.77 ID:???
>>825
> order byでは無理
この決めつけが視野を狭くしてるのではないかね
831NAME IS NULL:2012/07/04(水) 23:33:04.35 ID:???
>>830
その通りでした。
カラムをもう一つ増やせばできないこともないことに気づきました。
まあそのカラムにソートに必要な値を入れといて、
後でそいつをキーにソートするって方法ですけど。
でもそうするとこのキーの値もデータ更新時に毎回更新することになるから、
ちょっとなーって思ってたところです。
まあ400回ループするよりマシかもしれないのでちょっと考えてみます。
でも現状のカラムデータだけではソートは無理です。
ありがとうございました。
832NAME IS NULL:2012/07/05(木) 04:36:34.32 ID:???
出来ないやつって物のせいにするよね
833NAME IS NULL:2012/07/05(木) 05:38:44.50 ID:???
>>831
本気で取り出し順を工夫するときは、別に取り出し順テーブルを持たなくちゃ。
834NAME IS NULL:2012/07/05(木) 08:41:39.02 ID:???
>>832
あのな
自分の力量がないことなんかわかってんだよ
ただの捨て台詞だ
黙ってろボケ

>>833
なるほど。
それいいですね
参考になりました
ありがとうございます。
835NAME IS NULL:2012/07/05(木) 10:45:48.42 ID:???
ある整数型のカラムnumがあって、
その内容が、100以下の素数であるレコードだけ抜き出すために
SQLを簡潔に書く方法はありますでしょうか

where num=2 or num=3 or num=5 (略) num=89 or num=97
と書いてもいいんですが、
たとえば
where num={2,3,5,7,11,(略),83,89,97}
のようなまとめた書き方があったら教えてください
836NAME IS NULL:2012/07/05(木) 11:28:05.41 ID:???
in
837NAME IS NULL:2012/07/05(木) 14:27:43.64 ID:???
838NAME IS NULL:2012/07/05(木) 18:59:18.72 ID:???
select id, name, email from users;
というSQLがあって、idとemailはユニークだけど、nameは重複可能であるとします。
このとき、nameが重複したときは最初(または最後)に現れたレコードだけをselectすることはできますか。
DBはPostgreSQL 9です。
よろしくお願いします。
839NAME IS NULL:2012/07/05(木) 19:18:57.36 ID:???
Postgresならdistinct onでできるけど
標準SQLではない点はマニュアルにも書いてある通り
http://www.postgresql.jp/document/current/html/queries-select-lists.html
840NAME IS NULL:2012/07/05(木) 19:24:03.31 ID:???
環境ないからSQL書かんけど
nameでgroup byしてmin(id)とって、それと突き合わせてemail取るとかでいけそうな
841NAME IS NULL:2012/07/05(木) 20:38:42.24 ID:???
それなら
>>4
とだけ書けばいい
842NAME IS NULL:2012/07/05(木) 20:54:58.05 ID:???
>>839-841
ありがとうございます。
distinct onがいちばん簡単そうなので、これでできるかをまず検討し、
できなければ>>4の方法でいこうと思います。
843NAME IS NULL:2012/07/06(金) 00:26:01.09 ID:???
C# SQLite
特定の列にNallがあるかどうかの判定をして、あるかないかによって0または1を返したいのですが
へたれな頭で考え、ネットからコピーして、下記のように力業?で一応出来ております
もっと簡単にできるものでしょうか?

// 変数宣言
const string DATABASE_NAME = @"c:\test.db";
string gDataBaseFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), DATABASE_NAME);
string gDataSource = "Data Source=" + Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), DATABASE_NAME) + @";password=""testpass""";
int hantei = 0;

// 処理
private void HanteiShori() {
string sql;
SQLiteCommand command;

using (SQLiteConnection conn = new SQLiteConnection(gDataSource)) {
try {
conn.Open();
int allData = 0;
int noNall = 0;

// レコード数
sql = "SELECT COUNT(*) FROM testTable";
command = new SQLiteCommand(sql, conn);
SQLiteDataReader reader = command.ExecuteReader();

while (reader.Read()) {
string tmp = reader[0].ToString();
allData = int.Parse(tmp);
}

// Nall以外の数
sql = "SELECT COUNT(retuData) FROM testTable WHERE retuData is not NULL";
command = new SQLiteCommand(sql, conn);
reader = command.ExecuteReader();

while (reader.Read()) {
string tmp = reader[0].ToString();
noNall = int.Parse(tmp);
}

if (allData > noNall) {
hantei = 1;
}
else {
hantei = 0;
}
}
catch { }

finally {
conn.Close();
}
}
}
844NAME IS NULL:2012/07/06(金) 00:39:12.40 ID:???
NallってNullのことか?
普通にNullの行数数えるだけだろ
select count(*) from testTable where retuData is null
でダメなのか?
845843:2012/07/06(金) 00:59:36.16 ID:???
それでいけました
ありがとうございます

それにしてもへこむ、、、
結構がんばって検索して頭ひねったつもりでいたのにあっさりと答えて頂いた
自分で出来たときなんか「オレって天才じゃねw」とか思っていたりして

しかも長文が恥ずかしい
さらにNallって

精進いたします
846NAME IS NULL:2012/07/06(金) 01:02:50.02 ID:???
アフリカではよくあること
847NAME IS NULL:2012/07/06(金) 02:58:52.30 ID:???
格好つけて「なる」と発音してきたのはよく分かった。
848NAME IS NULL:2012/07/06(金) 10:54:20.12 ID:???
俺もナルって言ってるわ。
ドイツ語だとヌルらしいな。
ゼロもヌルだそうなので、ジェームス・ボンドはドイツ語だと「ヌルヌルズィーベン」だそうな。
849NAME IS NULL:2012/07/06(金) 13:04:15.89 ID:???
そしてポッカの「レモン100」は、
ツィトローネ フンダート!
になるんですよ。

スレ汚しごめん。
850NAME IS NULL:2012/07/06(金) 22:24:51.95 ID:???
>>835
なんだよ、SQLite スレとのマルチかよ。
851NAME IS NULL:2012/07/08(日) 13:04:32.99 ID:0KdAjTTB
DB初心者です。質問させてください。

特定多数の人が利用するFacebookの投稿情報を管理するデータベースを作るとした時に、
そのデータのテーブルの作り方は、

1案. UserIDカラムのある一つのテーブルに全部入れてしまうのか
2案. ユーザー毎にテーブルを作って管理するのか

では、一般的にはどちらのほうが良いとされるのでしょうか。

2案では、同じカラムのテーブルが作られるから、1案が妥当になるのでしょうか。
しかし一つのテーブルに特定多数の人のデータが入っているのはいかがなものかという気がしてます。

一ユーザーが保存する投稿データは10件くらいにする予定です。

よろしく御願いたします。
852NAME IS NULL:2012/07/08(日) 13:31:01.25 ID:???
普通に案1のほうだろ。
853NAME IS NULL:2012/07/08(日) 13:31:23.54 ID:???
ってスレチだな。設計スレに行け。
854NAME IS NULL:2012/07/08(日) 13:45:42.69 ID:???
ユーザごとにテーブルっていう発想が素晴らしい
将来大物になるかも
855NAME IS NULL:2012/07/08(日) 13:53:02.65 ID:???
DB初心者がいきなりでかい物を作ろうとするときのよくある勘違い発想じゃん
856851:2012/07/08(日) 13:55:23.74 ID:0KdAjTTB
普通は1案ですか。
スレチで且つお恥ずかしい質問でどうも申し訳ございませんでした。
ありがとうございました。
857NAME IS NULL:2012/07/08(日) 13:56:47.06 ID:???
2案でやってみりゃすぐ破綻するからやってみ。
858NAME IS NULL:2012/07/08(日) 14:11:34.51 ID:???
>>856
すこし集合を勉強すれば?
859NAME IS NULL:2012/07/08(日) 14:26:58.35 ID:???
>>856
結構意味深い質問なのではないかと思う。
オブジェクト指向で育った人なら2案を考えても不思議ではない。
2案の弱点は最終的には FROM テーブル名 のテーブル名のところに
変数を持って来なくてはならなくなる。それはSQLの設計思想から外れる。
860851:2012/07/08(日) 14:52:18.70 ID:0KdAjTTB
>>857
ユーザーが増えすぎると、一々ユーザー毎のテーブルを開くのに破綻するということでしょうか。
普通はトランザクション使って大量データを更新するんですね。

>>858
はい

>>859
すごいですね。仰せのとおり会社業務では、オブジェクト指向のソフト開発がほとんどです。
オブジェクト指向とは関係ないですが、よく配列データに操作するのにハッシュ的感覚で添字使って高速アクセスしたりするので、
そのような考え方をしてたと思います。


つまりは何回もテーブルは開いたり閉じたりするなということでしょうか。

因みにSQLiteです。
861NAME IS NULL:2012/07/08(日) 15:00:29.24 ID:???
>>859
> オブジェクト指向で育った人なら2案を考えても不思議ではない。

え?w
862NAME IS NULL:2012/07/08(日) 15:01:07.43 ID:???
あるユーザーの投稿一覧を取得しようとしたとき
どのテーブルを使うかはどうやって調べるんだよ
863851:2012/07/08(日) 15:12:04.26 ID:0KdAjTTB
>>862
ユーザー毎のテーブルなのだから、テーブル名がユーザーIDです。
864NAME IS NULL:2012/07/08(日) 15:20:23.06 ID:???
そのユーザーIDはどこから引いてくるの?
何らかの検索結果で出たIDをテーブル名にしてさらにSQL発行するのか
一つのテーブルなら一発でひけるのに
865NAME IS NULL:2012/07/08(日) 15:22:15.49 ID:???
>>863
ユーザマスタ(ID,名前)もユーザ毎にテーブルを作らないのか?w
866851:2012/07/08(日) 15:24:32.16 ID:0KdAjTTB
>>864-865
一つのテーブルでいいことはもうわかりましたのでそうします。
ありがとうございました。
867NAME IS NULL:2012/07/08(日) 15:55:21.33 ID:???
スレ違いだってのがわからないの? 馬鹿なの? 死ぬの?
868NAME IS NULL:2012/07/08(日) 16:00:10.99 ID:???
うまい回答が出来なかった時の免罪符ってか
869NAME IS NULL:2012/07/08(日) 16:13:29.99 ID:???
生まれて初めてプログラミング(PHP+MySQL)やったとき、
主キーもインデックスも知らなかったから、動作を軽くするためにやったわw>キーごとにテーブル作成
870NAME IS NULL:2012/07/08(日) 16:21:44.74 ID:???
生まれて初めてのプログラミングでデータベースまで使ったのか、
最近の子はすげーな。
871NAME IS NULL:2012/07/08(日) 16:41:16.69 ID:???
このスレの凄いところは
普段は人の気配がほとんどないと思わせておきながら何かあると急に湧き出してくるところ
872NAME IS NULL:2012/07/08(日) 16:42:25.56 ID:???
主キーって今まで設定してなかったんだけどあれなに?
873NAME IS NULL:2012/07/08(日) 16:44:31.93 ID:???
ぬしキーを知らぬとは、、、
874NAME IS NULL:2012/07/08(日) 16:45:26.97 ID:???
Facebookの管理にそんな必要があるかは疑問だが、個人ごとにテーブルで
管理することの面白さは、それぞれの個人を別の属性の集合、全積、関係として
管理できる点にある。設計という観点からすれば、それなりに筋が通っている。
ただ、RDBそれからRDBに起源を持つ、SQLとは折り合わない部分が多々ある
のでは、ということだ。
875NAME IS NULL:2012/07/08(日) 16:45:51.59 ID:???
ぬしって読むのかw
しゅきーかと思ってた
876NAME IS NULL:2012/07/08(日) 16:47:41.14 ID:???
>>872
そういう話をテーマにしたスレが確かあったはず。
877NAME IS NULL:2012/07/08(日) 16:55:33.51 ID:???
>>876
恐怖なんとやら、っていうスレなら随分前に1000まで行って終わった。
878874:2012/07/08(日) 17:50:53.36 ID:???
ごめん直積だった。最近こんな言葉使ったことなかったもんで・・すみません。
879NAME IS NULL:2012/07/08(日) 18:51:31.79 ID:???
>>874
そんな設計で筋が通っているなんて・・・恐ろしくてとても言えないわw
880NAME IS NULL:2012/07/08(日) 19:33:51.79 ID:???
そういや設計スレもだいぶ前に落ちたよな
とか言おうと思ったらまた立ってた

DB設計を語るスレ 6
http://toro.2ch.net/test/read.cgi/db/1341061787/
881Kinjyo Hirohito:2012/07/08(日) 22:28:06.75 ID:???
入庫、出庫、締め用のテーブルがあるとし、それぞれ、HEADER、DETAILがあり
HEADERには、入出庫、締め番号、日付、ACTIVE(該当月Y/N)など
DETAILには、アイテムと数量が入っているとします
そこでDAILY MOVEMENTを作成したいのですが、
1~31のように固定ではなく、トランザクションがあった日のみ、つまり
SELECT TRANS_DATE FROM
(SELECT TRANS_DATE FROM INCOMING WHERE ACTIVE='Y'
UNION ALL
SELECT TRANS_DATE FROM OUTGOING WHERE ACTIVE='Y') T_DATE
group by TRANS_DATE ORDER BY 1
でTRANS_DATE抽出しておきます
結果をREPORT WRITEとかWEBを用いずに
TRANS_DATEが横方向に1行目に表され、
2行目1カラムは、アイテム、2カラム目はOPENING数量で、
3カラム以降はIN又はOUTの数量を表記したいのですが
JUL/8はトランザクションがありませんので表記されていません
最後のカラムは、その月の現在までのSUMMARY

  JUL/7  JUL/9           JUL
IN OUT IN OUT IN OUT CLOSE
   3 5   3 3 8  15

みなさんなら、どうSQLを書きますか、教えてください
882NAME IS NULL:2012/07/08(日) 22:43:59.63 ID:???
>>7
883Kinjyo Hirohito:2012/07/08(日) 23:56:14.25 ID:???
Stored Procedureを用いてループさせるとした場合ならどうでしょうか
特にどのSQLかは、こだわりませんが、擬似SQLコードでは、どうでしょうか?

     JUL  JUL7 JUL9 JUL
     OPEN   IN OUT IN OUT IN OUT CLOSE
アイテム 15 3 5 3 3 8 10
884NAME IS NULL:2012/07/09(月) 00:22:30.19 ID:???
>>881
まともに意見が欲しいなら、もうちょっと他人に解るように説明した方が良いんじゃね
俺様用語が多すぎるわ

SQLに「表記」はないぞ
なぜそれをカラム可変でやる必要があるのか理解できん
素直に日付ごとに行を持てば(出力すれば)良いんじゃないのか
885Kinjyo Hirohito:2012/07/09(月) 23:45:13.84 ID:???
トランザクションが毎日あるなら別ですが、1週間に2,3回とかですと、
ブランクばかりになってしまいます、ですので可変で表記する必要があります
もちろんレコードが存在する日付のみを、カスケイドすれば可変になりますが
それでは、知恵がないかと思いまして、SQLに経験豊かな方々は、
どのようなコーディングをされるのかを、拝見したく思いまして
886NAME IS NULL:2012/07/10(火) 00:04:30.95 ID:???
>>885
>>884は、カラム数を可変にする必要性があるのかっていってるんだが?
トランザクションが二日あったら、2行で出力すれば良いんじゃないのか?
それを表示するときにホストアプリで縦横変換すれば良いだけで
データの表示形式を決めるのはSQLの範疇ではないって言ってるんだが

>レコードが存在する日付のみを、カスケイドすれば可変
意味がわからん
887NAME IS NULL:2012/07/10(火) 00:11:39.66 ID:???
日本語でおk
888NAME IS NULL:2012/07/10(火) 05:47:11.21 ID:???
そもそも、これは7月の入出庫だけが入っているテーブルなのかな。
7月だけActiveにしてあるなんて考え難いし。
889Kinjyo Hirohito:2012/07/10(火) 07:23:45.50 ID:???
Activeは、その月を取り出すためためだけの目的でして、
倉庫では、お客様の都合で2重帳簿を作ることがしばしばあります
つまりトランザクションDATEの年と月だけでデータ抽出すると
要望に答えれないからです。在庫があるのに、落としてある、
在庫がないのに、あるように見せるなど、各お客の要望に従って
幾つかのACTIVEのようなカラムを儲けています
890NAME IS NULL:2012/07/10(火) 09:10:09.76 ID:???
後から後からどんどん条件が出てくる w
891NAME IS NULL:2012/07/10(火) 10:09:57.34 ID:???
条件というか蛇足だな
本質は>>5のカラム数をデータに依存して決定したいという話なのに
892NAME IS NULL:2012/07/10(火) 10:29:42.27 ID:???
自分で調べる奴・・・問題の本質を理解する力がある
2chで聞いて済ませる奴・・・抽象化する力がないので質問内容もわけわかめ
893NAME IS NULL:2012/07/10(火) 22:07:06.14 ID:???
SQLじゃなくてRPGでも使うべきなんだろうな、ああいう人は。
894NAME IS NULL:2012/07/10(火) 22:29:11.76 ID:???
SQLの代わりにグレネードランチャー使うって凄いな
895NAME IS NULL:2012/07/10(火) 22:50:11.91 ID:???
oracle使っているのですが、
カンマ区切りの文字列を、カンマで分割した複数行としてSELECTできないでしょうか?

SELECT * FROM (select "1,2,3,4" from dual) 〜〜〜〜〜
とかで複数行として、カンマ分割した結果がほしいです!
896NAME IS NULL:2012/07/10(火) 22:57:58.51 ID:???
無理やりやるならテキストデータレベルでカンマを「 from dual union select 」で置換して
select * from (select '1' from dual union select '2' from dual union select '3' from dual union 〜)
みたいにする
897NAME IS NULL:2012/07/10(火) 22:58:18.39 ID:???
>>895
ストアド書けばいいんじゃね?
http://ichi-note.sblo.jp/article/34919609.html
898895:2012/07/10(火) 23:33:45.63 ID:???
ご教示ありがとうございます!
テキストベースにしたりファンクションにしたりしないとやはり厳しいんですね・・・。
ファンクション形式でやってみます!
899NAME IS NULL:2012/07/11(水) 04:31:57.39 ID:???
まず格納時にちゃんと複数行で格納するべき
それが無理なら、ホストアプリで分解する
SQLやストアドで何とかするのはとても勧められない
900NAME IS NULL:2012/07/11(水) 10:40:32.47 ID:???
テーブル名:PRODUCT

CODE, PRODUCT_NAME, M_Type
001,パソコン,01
002,パソコン NEC,01
003,パソコン FUJITSU,01
004,パソコン,01
005,パソコン,02
006,プリンター,03
・・・

とあるとき

@
PRODUCT_NAMEの重複するデータを抽出するにはどうしたらいいでしょうか?

001,パソコン,01
004,パソコン,01
005,パソコン,02

が出て欲しい

A
PRODUCT_NAMEかつM_Typeも一緒のデータを抽出するにはどうしたらいいでしょうか?

001,パソコン,01
004,パソコン,01

が出て欲しい

お願いします。

901NAME IS NULL:2012/07/11(水) 11:04:57.54 ID:???
GROUP BYしてHAVINGかな
902NAME IS NULL:2012/07/11(水) 11:35:56.43 ID:???
DBMS:SQLite3.7.12.1(System.Data.SQLite1.0.81.0)

[テーブルデータ]

CREATE TABLE tblA(
id INTEGER,
status001 INTEGER,
status002 INTEGER,
status003 INTEGER,
status004 INTEGER,
.
.
.
status300 INTEGER
);

id |status001|status002|.... . |status300|
----+--------+--------+ +--------|
1| 0 | 0 | | 0 |
2| 1 | 0 | | 0 |
3| 0 | 0 | | 1 |
4| 0 | 1 | | 1 |
5| 0 | 0 | | 0 |
6| 1 | 1 | | 0 |
7| 0 | 1 | | 0 |
8| 1 | 1 | | 1 |
9| 1 | 1 | | 0 |

想定レコード数 50,000〜2000,000

[欲しい結果]
-------------------------------------------
status001 | 4 //status001=1であるレコード数
status002 | 5 //status002=1であるレコード数
.
.
.
status300 | 3 //status300=1であるレコード数

正規化に問題があるように思えますが
これらを一度のSQLで取得出来ないでしょうか。
この結果を最も速く取得する方法を模索しています(__)
903NAME IS NULL:2012/07/11(水) 12:53:07.45 ID:???
UNIONを300書けばできる
904902:2012/07/11(水) 13:27:22.01 ID:???
>>903
一例ありがとうございます。既にそちらの方法は作成済みです。
905NAME IS NULL:2012/07/11(水) 16:03:08.87 ID:???
>>901

すみません知識不足のためよくわからないです。
サブクエリの部分がよくわからないです。
906NAME IS NULL:2012/07/11(水) 16:48:12.77 ID:???
ggrks
907NAME IS NULL:2012/07/11(水) 17:44:27.04 ID:???
>>900
select * from product group by product_name having count(*) > 1;
かな。試してないけど。
908NAME IS NULL:2012/07/11(水) 18:10:02.97 ID:???
>>900
@
select *
from  PRODUCT T1
where  exists (
        select *
        from  PRODUCT T2
        where  T1.CODE <> T2.CODE
        and   T1.PRODUCT_NAME = T2.PRODUCT_NAME
    )
;

A
select *
from  PRODUCT T1
where  exists (
        select *
        from  PRODUCT T2
        where  T1.CODE <> T2.CODE
        and   T1.PRODUCT_NAME = T2.PRODUCT_NAME
        and   T1.M_Type = T2.M_Type
    )
;
909NAME IS NULL:2012/07/11(水) 18:22:06.44 ID:???
>>902
>>903に一票

それか結果を
status001|status002|.... .|status300|
--------+--------+  +--------|
      4|     5|  |      3|
で得てからアプリ側で縦横入れ替えるか
910NAME IS NULL:2012/07/12(木) 11:02:21.60 ID:???
テーブル作りなおすべき
911NAME IS NULL:2012/07/12(木) 11:31:15.26 ID:???
【質問テンプレ】
・SQLite3
・テーブル
id,unixtime
100001,1341404056
100001,1341997094
100001,1341987930
100002,1341997860
100002,1341989037

・欲しい結果
100001,1341997094
100002,1341997860

・説明
上記テーブルでid毎にunixtimeが一番大きいデータを1つだけ取り出すには
どのようなクエリでできるでしょうか。1回では無理でしょうか。
912NAME IS NULL:2012/07/12(木) 11:40:58.03 ID:???
select id,max(unixtime) from hoge group by id order by id;
913911:2012/07/12(木) 11:53:58.76 ID:???
すみません、情報不足でした。テーブルにはテキスト情報もあり、
id,unixtime,value
"1" "1341404056" "内容1"
"1" "1341997094" "内容2"
"1" "1341987930" "内容3"
"2" "1341997860" "内容1"
"2" "1341989037" "内容2"

このような場合に
>>912さんに教えていただいた
select id,max(unixtime),value from t_test group by id order by id
とすると、
"1" "1341997094" "内容3"
"2" "1341997860" "内容2"
と内容がずれてしまうのですが、

こういった場合では、
"1" "1341997094" "内容2"
"2" "1341997860" "内容1"
と出すにはどうしたらよいでしょうか。
914NAME IS NULL:2012/07/12(木) 12:07:38.20 ID:???
>>913
それだと副問い合わせになるな
(id,unixtime) がユニークだとして

select t.id,t.unixtime,t.value from t_test t,
(select id,max(unixtime) as unixtime from t_test group by id) tmp
where t.id=tmp.id and t.unixtime=tmp.unixtime
order by t.id;
915911:2012/07/12(木) 12:25:38.43 ID:???
>>914
神様ありがとうございます!出来ました!
916902:2012/07/12(木) 13:38:28.50 ID:???
ご意見ありがとうございます!

>>909
検討してみます。

>>910
status群を子テーブルにするのが正しい姿のような気がします。
917NAME IS NULL:2012/07/12(木) 13:52:41.61 ID:???
代わりにエクセルとかでささっと編集するのが面倒になるけどね
918NAME IS NULL:2012/07/17(火) 22:22:45.76 ID:Di4GcY9V
・DBMS名とバージョン
MySQL5
・テーブルデータ
name (verchar)

abc040
abc100
abc90
abc20
abc1000

・欲しい結果
nameはユニーク
abcは固定、そのあとに数値文字列
ソートして、数値文字列の大きい順に抽出したい

abc1000
abc100
abc90
abc040
abc20

・説明
919NAME IS NULL:2012/07/17(火) 22:46:27.80 ID:???
4文字目以降をゼロ詰めしてソートすればいいな。
920NAME IS NULL:2012/07/17(火) 23:08:36.14 ID:???
4文字目以降の文字列を作る
左側を0でトリムする
その値で降順ソートする
921NAME IS NULL:2012/07/17(火) 23:16:02.84 ID:???
ご意見ありがとうございます!

ちょっと難しそうですね。
922NAME IS NULL:2012/07/18(水) 01:16:57.24 ID:???
ABCが固定であれば、
order by カラムdesc;
じゃ駄目なの?
923NAME IS NULL:2012/07/18(水) 03:57:57.20 ID:???
4ケタ目以降で、ゼロ埋めじゃなくて、数字変換する方が良いと思うんだが
つかまあテーブル定義やり直すべきだろう
カラムは最小単位で定義するのが鉄則
924NAME IS NULL:2012/07/18(水) 08:04:37.87 ID:???
>>922
それだと
abc90
abc20
abc1000
abc100
abc040
こうなるよ
925NAME IS NULL:2012/07/18(水) 16:16:22.74 ID:???
>>918
SELECT * FROM table ORDER BY CAST(TRIM(LEADING 'abc' FROM name) AS SIGNED INTEGER);
926NAME IS NULL:2012/07/18(水) 21:22:10.82 ID:???
>>925
完璧です。
ありがとうございます。
927NAME IS NULL:2012/07/19(木) 00:26:03.79 ID:???
・バージョン
MySQL5.5

・テーブルデータ
time (TIME), num1 (INT), num2 (INT)

00:00:00, 1, 0
00:00:10, 2, 0
00:00:20, 3, 2
00:00:30, 4, 3
00:00:40, 5, 3

・欲しい結果
00:00:20, 3, 2
00:00:30, 4, 3
00:00:40, 5, 3

・説明
time(時刻)が新しい(最近の)方から3行ぬきだし、
timeが昇順になるように並べます。
SELECT文でうまいことできないでしょうか。
よろしくお願いします。
928NAME IS NULL:2012/07/19(木) 06:57:42.24 ID:???
>>927

↓俺が使ってるもの(銘柄コード指定で最新データ10日分のを抜き出し
 日付の昇順で表示するもの

select * from
( select vdate,sp,hp,lp,cp ,vol
from daily_sp_tbl where sc=5401 order by vdate desc limit 10 ) t
order by vdate;

そちらの名称に合わせて書き換えてみたら
929NAME IS NULL:2012/07/19(木) 15:53:43.08 ID:???
ゴキ光線のお小言が始まるでぇ〜( ´Д`)y━・~~
930NAME IS NULL:2012/07/22(日) 23:57:04.02 ID:???
・DBMS名とバージョン
SQLite3
・テーブルデータ
tbl1 tid(auto), name(text)
tbl2 tid(int), sid(int)
tbl3 sid(auto), tag(text),type(int)

ざっとこんな感じでnameに対して複数のタグを持っている
といった感じのテーブルに対して、データを入れたいと思っています。
で、バックアップがCSVで「name,tag...」という形式で大量にあるのですが、
タグテーブルに無ければ追加、名前テーブルに追記、連結データを追加、
と手数が思ってた以上に多いので、
挿入の手数をもう少し減らせる手段とかありませんか?
931NAME IS NULL:2012/07/23(月) 06:43:06.22 ID:???
何言ってんのか分かんない
932SQL初心者:2012/07/23(月) 11:43:26.77 ID:???
SQLの質問がありまして、書きます。

Aテーブル
A B C
1 11
2 22
3 33


Bテーブル
A B C
4 44 1
5 55 2
6 66

欲しい結果
A B
1 44
2 55
3 33
6 66

BテーブルのCがAテーブルのAと一致したらBテーブル参照したいですが、A項目のみ値をAテーブルの値にしたいです。
何かアドバイスお願いします。。。。。
調べても、よくわからなかったので。。。
お願いします。。。
933NAME IS NULL:2012/07/23(月) 12:57:29.52 ID:???
>>932
欲しい結果の(3,33)と(6,66)を考えなければ
select A.A, B.B from A,B where A.A=B.C;
で簡単なんだが、下の二行はどういう条件で抽出されるべきなの?
934SQL初心者:2012/07/23(月) 13:03:33.77 ID:???
>>933
そうなんですね。。。
BテーブルのCに一致しないものを表示させたいです。。。。。。。
935NAME IS NULL:2012/07/23(月) 13:39:50.34 ID:???
AテーブルのAとBテーブルのBはかぶらないのか?
AとBをUNIONして、BをOUTER JOINしてCASEでNULL判定かな
936NAME IS NULL:2012/07/23(月) 18:36:14.05 ID:???
こういうことじゃないの?
select case when A.A is null B.A else A.A end as A,
    case when B.B is null A.B else B.B end as B,
from  A
    full outer join
    B
    on A.A = B.C
937SQL初心者:2012/07/23(月) 20:45:54.91 ID:???
大変ありがとうございました。
みなさんのおかげで、無事にできました。
938NAME IS NULL:2012/07/24(火) 00:21:52.45 ID:???
>>936
> case when A.A is null B.A else A.A end as A,

なんで、coalesce(A.A, B.A) 使わないの?
939NAME IS NULL:2012/07/24(火) 06:22:52.28 ID:Gfkf5V7p
初心者用が見つからなかったのでこちらで質問します

テーブル tbl
|-----INDEX----|--DATA--|
yyyy mm dd no item
2012 01 05 005 itemAA
2012 01 05 007 itemAC
2012 01 05 009 itemBB
2012 01 10 001 itemBA
2012 01 10 007 itemFG
2012 01 12 006 itemQW
      :
      :

結果
2012 01 10 001 itemBA
2012 01 10 007 itemFG

この場合
select * from tbl
where yyyy='2012'
 and mm='01'
 and dd='10'

このようにnoを指定しないと検索時にインデックスは有効とならないのでしょうか?
インデックスはその項目全てをSQLに明記しないと有効とはならないのでしょうか?

初歩的すぎる質問だと思いますがお願いします
940NAME IS NULL:2012/07/24(火) 06:24:12.46 ID:???
sage忘れました
申し訳ないです
941NAME IS NULL:2012/07/24(火) 06:52:25.93 ID:???
インデックスってこのスレで取り扱ってたっけ
942NAME IS NULL:2012/07/24(火) 06:53:23.18 ID:???
オプティマイザ次第。
943NAME IS NULL:2012/07/24(火) 18:40:45.30 ID:???
>>938
DBMS名書いてないから

>>939
普通のインデックス構造をもつ普通のDBMSなら普通は有効となる
ただしどんな状況でも必ずそうだとは言い切れないので
実機でアクセスパスを確かめること
(確かめる方法はDBMS固有なのでスレ違い)
944NAME IS NULL:2012/07/24(火) 18:58:10.33 ID:???
オプティマイザ以前に、そのDBMSでその手の検索にインデックスが有効かどうかが問題
今時のDBMSなら効くと思うけど、まずはDBMSのマニュアルで確認するべきだな
そのうえで実際の読み込みにインデックスが使われるかどうかはオプティマイザ次第

つか初心者ならまずちゃんとマニュアル読めよと
945NAME IS NULL:2012/07/24(火) 21:17:09.74 ID:???
・DBMS名とバージョン MySQL 5.1
・テーブルデータ
CSVファイル
"犬","シベリアンハスキー"
"猫","マンチカン"
"熊猫","レッサーパンダ"
・欲しい結果
インポートして、次のようにしたい、要するに連番をつけたい
ID 動物 種類
1 犬 シベリアンハスキー
2 猫 マンチカン
3 熊猫 レッサーパンダ
・説明
インポートするときにdefaultをつければいいのですが、SQL文で書けないでしょうか。
946NAME IS NULL:2012/07/24(火) 21:24:05.88 ID:???
MySQLならAUTO_INCREMENTあるだろ
947NAME IS NULL:2012/07/24(火) 21:26:27.73 ID:???
すると次はレコード消した時にIDが虫食い状態になるのでなんとかしたい…とかの質問が来るんだな w
948NAME IS NULL:2012/07/24(火) 21:38:32.92 ID:???
>>946
そうなんですが、csvのデータをいじらずにSQLのload data infile文で
なんとかならないかと思ったのですが
949NAME IS NULL:2012/07/24(火) 22:20:57.99 ID:???
誰がいじれなんつった?両方使えよ
950NAME IS NULL:2012/07/24(火) 22:23:29.63 ID:???
そんなんSQL92の範囲にあったっけ?
951939:2012/07/24(火) 22:28:35.43 ID:???
>>941-944
MySQL 5.5 と ACCESS2003です

オプティマイザ及びアクセスパスについて調べてみることにします
レスありがとうです (_ _)
952NAME IS NULL:2012/07/24(火) 23:46:11.86 ID:???
>>943
> DBMS名書いてないから

そんなこと言うなら、case もダメだろ。
Access かも知れないんだし。

前提書いてないなら、SQL-92 あたりを想定してもいいと思うんだが。
953NAME IS NULL:2012/07/26(木) 11:15:02.64 ID:???
MySQL5.1

セール価格表(P)
商品CD 適用日 単価
aaa 2012-08-01 2500
aaa 2012-08-20 3000
bbb 2012-08-01 10000
bbb 2012-08-15 8500

予約表(Y)
商品CD 購入日 数量
aaa 2012-08-01 2
aaa 2012-08-05 3
aaa 2012-08-25 1
bbb 2012-08-13 4
bbb 2012-08-19 5

ほしい表
aaa 2012-08-01 2 2500
aaa 2012-08-05 3 2500
aaa 2012-08-25 1 3000
bbb 2012-08-13 4 10000
bbb 2012-08-19 5 8500

購入日時点で適用日以降の単価が反映された表を得るにはどうしたらいいでしょうか
954NAME IS NULL:2012/07/26(木) 13:15:07.54 ID:???
>>953

SELECT
商品CD,
購入日,
数量,
(SELECT 価格 FROM セール価格表 WHERE セール価格表.商品CD = 予約表.商品CD AND セール価格表.適用日 < 予約表.購入日 ORDER BY 適用日 ASC LIMIT 1) AS 価格,
FROM
予約表

みたいのでいけない?
思いつきで確認してない上に普段こうならんように組んじゃうから間違っているかもだけど。
あと、もっと効率のいいのがると思うけど。
955NAME IS NULL:2012/07/26(木) 13:22:03.93 ID:???
予約表に単価を持たせる
冗長だけど我慢する
956NAME IS NULL:2012/07/26(木) 13:50:59.48 ID:???
>>954

下記のように少し直しましたら、動きました・・☆。
ありがとうございました。

SELECT
商品CD,
購入日,
数量,
(SELECT 価格 FROM セール価格表 WHERE セール価格表.商品CD = 予約表.商品CD AND セール価格表.適用日 <= 予約表.購入日 ORDER BY 適用日 DESC LIMIT 1) AS 価格,
FROM
予約表
957NAME IS NULL:2012/07/26(木) 13:56:30.95 ID:???
>>955
セール価格表には単価だけでなく、期間立てで持っているフィールドがあるんです。
958NAME IS NULL:2012/07/26(木) 13:58:30.67 ID:???
>>956
決して効率よくないはず。
可能であれば、ホスト言語側でマージして
DB側に負担かけないようにしたほうが後日幸せになれるはず。
959NAME IS NULL:2012/07/26(木) 14:37:47.34 ID:???
MySQL 5.1です。

テーブル1
15:30:20 カツ丼
15:35:40 天丼
15:50:15 他人丼

テーブル2
15:30:30 400円
15:35:45 550円
15:51:00 480円

というテーブルがあって、テーブル1と2の時刻が近いものをマッチさせて
15:30:20 カツ丼 400円
15:35:40 天丼 550円
15:50:15 他人丼 480円

のような結果を出したいのですが、どのようにすればいいでしょうか。

よろしくお願いします。
960NAME IS NULL:2012/07/26(木) 15:52:58.39 ID:???
夏休みだからかな。
なんかの設問ぽいのが来ているな。

>>959
UNIX_TIMESTAMP()とABS()使って最も差分が最小値のを取り出せばいいんじゃないかな。
これ以上は、>>4見て質問書き直して。

UNIXTIME_TIME
961NAME IS NULL:2012/07/26(木) 16:12:19.74 ID:???
>>959
ごめん。
TIME_TO_SEC()だわ。
962NAME IS NULL:2012/07/26(木) 17:54:19.18 ID:???
>>960-961
設問じゃないのですが、ありがとうございます。
963NAME IS NULL:2012/07/27(金) 10:17:32.88 ID:KIhgtPiw
・DBMS名とバージョン
SQLite3

・テーブルデータ
テーブル名 directory
folder   val
/contact/  index
/test/    connect
/example/  foo
/hoge/    bar
/fuga/    com

・欲しい結果
問い合わせ内容とfolderの内容が部分一致していればvalを返す
/contact/ にアクセスがあった場合はindexを返す
/contact/foo の場合もindexを返す

・説明
$folder_hensuu = "%/contact/%";
select * from directory WHERE folder LIKE $folder_hensuu
とした場合はヒットするが

$folder_hensuu = "%/contact/hogehoge%";
の場合はヒットしない。
この場合はどうすれば一致判定が出来るようになりますか?
964NAME IS NULL:2012/07/27(金) 12:03:20.04 ID:???
SQLite3はよくわからないんだけど、なんか逆にすべきな気がする。
つまり、部分一致する際にそのWHEREの基準となるのがfolderカラムのほうでしょ。
だから、カラムのほうに文字列結合でみたいにすればいいんではないでしょか。
MySQLしか出来ないのでこれ以上は申し訳ない…。

MySQLで書くとこんな感じ。
SELECT val FROM test WHERE '/connect/hogehoge' LIKE CONCAT('%',folder,'%');
965NAME IS NULL:2012/07/27(金) 15:51:18.54 ID:???
休憩時間が設定されているときに、指定日時より'HH:MM'後の時刻を求めたいです。

・データベース:PostgreSQL 8.4
・テーブル:
休憩時間
開始時刻 終了時刻
08:00 08:30
19:00 19:30
22:00 22:30

使うかどうかわかりませんが、次のマスタもあります。
カレンダー
日付
...
2012-07-26
2012-07-27
2012-07-28
...

・説明
指定した日時から休憩時間を除いた'HH:MM'後を計算します。
計算結果が休憩時間内(開始終了時刻を含む)の場合は、休憩時間終了時刻を結果とします。

・欲しい結果
'2012-07-27 09:00'の'09:00'後 => '2012-07-27 18:00'(休憩時間がないのでそのまま足す)
'2012-07-27 09:00'の'10:00'後 => '2012-07-27 19:30'(10時間後は19:00の休憩と重なるので、19:30が答え)
'2012-07-27 09:00'の'11:00'後 => '2012-07-27 20:30'
'2012-07-27 09:00'の'13:00'後 => '2012-07-27 23:00'(19:00〜と22:00〜の二回の休憩を挟む)
966NAME IS NULL:2012/07/27(金) 16:12:55.58 ID:???
>>965
難問。
967NAME IS NULL:2012/07/27(金) 16:20:08.40 ID:???
>>965
確かに難問だ。
何を聞かれているのか説明を見るとすさまじく混乱する。

つまり、
1.出勤時刻と実労時間数を入力されたら
2.休憩時間を実労時間からはずした上で
3.勤務終了予定時刻を出力しろ。
4.ただし、終了予定時刻が休憩時間内である場合は、休憩終了時刻を出力する
ってこと?

それだけだと、欲しい結果のその日付の存在理由がなんなのかわからなくなるけど。

入力されるデータの例を出して。
ただし、ちゃんとフォーマットした形でね。
968967:2012/07/27(金) 16:31:53.50 ID:???
ごめん、1〜4を踏まえた上で例を考え直してってことでお願いします。
おそらく最後の例のままでいいんだろうけど
ちょと日本語読み直してたら混乱してきてた。
969NAME IS NULL:2012/07/27(金) 17:56:09.34 ID:???
>>967
私は出題者ではないのですが、
次の休憩開始時刻 - 一つ前の休憩終了時刻 = 就業時間 とすると
後・時間からこの就業時間を切り取って行く問題ですね。
さらに最後の休憩時間の後の就業時間をどう表現するかなど、
考えどころの多い問題のようです。
970965:2012/07/27(金) 18:19:05.67 ID:???
すみません。ちょっと欲張りすぎました。問題を一段階簡略化します。

休憩時間がマスタに設定されているとき、「与えられた日時」から実働9時間後の日時を求める。
(※)実働とは、休憩時間を除いた勤務時間。

この結果は、残業届けを出すときの残業開始日時を計算するときに使います。
(その後、月締め処理で残業届けに基づいて残業時間合計を計算します。)

「与えられた日時」は、未来の日付の残業届けを出すときは定時開始時刻(例えば09:00)になり、
過去の日付の残業届を出すときは、遅刻をしていればその日時になります。

例えば、'2012-07-27 09:00'と'09:00'という即値を使ったクエリで、 '2012-07-27 18:00'が計算
できるでしょうかというのが質問です。

勤務している時間を'+'、休憩時間を'_'で表すと、一日は、
++++++___++++++__+++_++_++++
みたいに表せて、任意の開始日時(下の*)から9時間後を求めたいということです。
+*++++___++++++__+++_++_++++
+++*++___++++++__+++_++_++++

うまく説明できたでしょうか?
971965:2012/07/27(金) 18:28:24.50 ID:???
>>969
そう、その通りです。

Excelでイメージするなら、休憩時間と勤務時間の累計をして、目視で判断すればすぐに
わかりそうな問題なんですが、クエリでできないものかと…。

最も好ましいのは、一つのクエリで結果を計算できること、
次に好ましいのは、ワークテーブルを使わずにPostgreSQLのFunctionで計算できること。

最悪はワークテーブルに「実休憩時間」を展開して、複数ステップを踏んで計算するか、
Functionを再帰呼び出しして(できるのだろうか)結果を求めるか、クライアントアプリ側で
ゴリゴリやるかになると思います。
972NAME IS NULL:2012/07/27(金) 19:10:02.82 ID:???
いやそれ、SQLでゴリゴリやる内容じゃないと思うぞ。
973NAME IS NULL:2012/07/27(金) 19:40:57.39 ID:???
休憩時間じゃなくて、実働時間をもたせたら
実働時間のサマリが指定時間を超える最大のものとかで求まらんかな
974NAME IS NULL:2012/07/29(日) 00:41:03.59 ID:???
データベース:MySQL 5.1

ストアドファンクションを作成しているのですが、
ストアド内ではGetDate()は使用できないのでしょうか?
また、何か代替のものはあるのでしょうか?

初歩的な質問で申し訳ありません。
975NAME IS NULL:2012/07/29(日) 19:49:26.46 ID:???
WHERE句の(+)ってどういう意味なのですか?
ぐぐっても出なかったもので(^_^;)
976NAME IS NULL:2012/07/29(日) 20:02:30.69 ID:???
Oracleだと外部結合演算子でググれ
他は知らん
977NAME IS NULL:2012/07/29(日) 20:38:52.00 ID:???
Oracle方言でしょ、それ
978NAME IS NULL:2012/07/29(日) 20:59:27.96 ID:???
>>976-977
ありがとうございました。
979965:2012/07/30(月) 11:43:54.03 ID:???
やはり簡単にはいかないようですね。

休みの間も考えたのですが、どうもうまくいかないので、結局、ワークテーブルを使って、
Excelでやるような累計をしながら、Functionで実装することにしました。
方針は、>>973さんの方法です。

考えて下さった方、ありがとうございました。
980NAME IS NULL:2012/07/31(火) 12:36:18.52 ID:RZdi1fDI
・Microsoft SQL2012を使っています。ちょっと質問なのですが

テーブル作成時における検査制約で、とある列の列名の長さ
が”6文字以内”という可変長の条件にしたいのですがどのよう
に書けばよいのでしょうか?

CONSTRAINT CK_stor_id CHECK(stor_id >=6 ))

上記では間違いでしょうか?よろしくお願いします。
981NAME IS NULL:2012/07/31(火) 13:42:13.86 ID:???
なぜ試して見ないの?
982NAME IS NULL:2012/07/31(火) 19:22:20.34 ID:???
間違いだろうね。
983NAME IS NULL:2012/07/31(火) 20:40:25.97 ID:???
列名の長さ?
984NAME IS NULL:2012/08/01(水) 13:26:17.32 ID:???
・SQL Server2008R2Express
テーブルデータ
・2012-08-01 11:35:00, りんご, 1
・2012-08-01 16:22:00, みかん, 2
・2012-08-02 13:54:00, りんご, 2
・2012-08-02 14:32:00, りんご, 1
・2012-08-04 16:22:00, みかん, 3

・欲しい結果
2012-08-01
2012-08-02
2012-08-04

・説明
件数に関係なく売り上げがあった日だけのリストが欲しいのですが
うまい方法あるでしょうか
985NAME IS NULL:2012/08/01(水) 15:07:44.19 ID:???
distinct と having count(*)>1
986NAME IS NULL:2012/08/01(水) 15:08:33.26 ID:???
ごめん間違えた
distinct でいい
987NAME IS NULL:2012/08/01(水) 20:08:54.81 ID:???
データベース:MySQL 5.2

table bbs(
uid INT,
rid INT,
text TEXT
);

table users(
id INT UNIQUE,
name VARCHAR(32)
);

欲しい結果のイメージ
uid, rid, uid.name, rid.name

.name は users テーブルの name の項目

掲示板で、投稿者ID (uid) と 返信先ID(rid) のそれぞれの名前を users から取得したいです。
988NAME IS NULL:2012/08/01(水) 20:22:21.92 ID:???
bbsテーブルにusersテーブルを2回JOINするだけだろ
989NAME IS NULL:2012/08/01(水) 20:47:20.02 ID:???
>>984-986
dateをformatかけて日付だけ取り出したいんじゃないかな?
Transaction-SQLわからなかったのでレスできなかったけど。

>>987
それぞれのID用にusersテーブルを別名つけて2回JOIN
やってみてダメだったら、作ったSQL文張ってみて
990NAME IS NULL:2012/08/01(水) 21:35:15.73 ID:???
>>988-989
SELECT a.id, a.name, b.id, b.name, bbs.text FROM bbs LEFT JOIN users AS a ON bbs.uid=a.id LEFT JOIN users AS b ON bbs.rid=b.id;

a とか b とかっていう名前はともかく、これでなんとか取得出来ました。
ありがとうございます m(_ _)m

(bbs にあるデータは全て取りたいので INNER ではなく LEFT にしました)


こう言った文が長くなったときに、他の言語の様にブロックで囲むと言った記述は出来ないのでしょうか?

それとも可読性を求める時は改行で分けるのが一般的なのでしょうか?
991NAME IS NULL:2012/08/01(水) 22:26:47.53 ID:???
改行とインデント使うのが一般的かと
よくやる人は>>990のSQL使うと
SELECT
a.id,
a.name,
b.id,
b.name,
bbs.text
FROM
bbs
LEFT JOIN
users AS a
ON
bbs.uid=a.id
LEFT JOIN
users AS b
ON
bbs.rid=b.id
;
くらいやる
992NAME IS NULL:2012/08/01(水) 22:43:34.35 ID:???
( ´_ゝ`)フーン
993NAME IS NULL:2012/08/02(木) 00:29:26.77 ID:???
>>991
これは改行しすぎだろ。
select みたいに、フィールド名がずらずら続く奴はべつにして
キーワードと関連するオペランドは基本的に同じ行にしといたほうが読みやすいと思うぞ。
俺ならこんな感じ。

SELECT
 a.id,
 a.name,
 b.id,
 b.name,
 bbs.text
FROM bbs
LEFT JOIN users AS a ON bbs.uid = a.id
LEFT JOIN users AS b ON bbs.rid = b.id;
994NAME IS NULL:2012/08/02(木) 00:42:40.38 ID:???
なるほど
プログラムから使うときは SQL 文を複数に分けて連結してたけど、
改行で分けて書いた方が見た目分かりやすいですね。
995NAME IS NULL:2012/08/02(木) 01:05:44.58 ID:???
>>993
俺もこんな感じで書くな

どうでもいいが俺はアプリのソースに直接SQLを埋め込む実装は好きじゃない。
SQL文は別のファイルにして、アプリからそれを読み出してwhere句の部分とかをアプリから変数で置換するのが好きだな。
アプリもSQLも仕変や改修も管理も楽になる。

と言っても元々NEとかSE出身でアプリやDBは素人のお馬鹿さんなんだがw
996NAME IS NULL:2012/08/02(木) 01:12:59.91 ID:???
>>994
あと、DBMS によってはキーワードなんかの間違い箇所を行で教えてくれるものがあるから、
長大な SQL を書く時はデバッグが楽。
997NAME IS NULL:2012/08/02(木) 16:19:44.69 ID:???
SELECT
 col1,
 col2
FROM
 (
   aTab
  INNER JOIN
   bTab
  ON
   aTab.id = bTab.id
 )
INNER JOIN
 cTab
ON
 cTab.id = aTab.id

すごく人によって差がありますなぁ…。
998NAME IS NULL:2012/08/02(木) 19:58:49.69 ID:???
999NAME IS NULL:2012/08/02(木) 20:29:23.83 ID:???
>>991-997
こっち行け

[大文字/小文字]SQLの正しい書式[改行/インデント]
http://toro.2ch.net/test/read.cgi/db/1272761178

>>998
おつ
1000NAME IS NULL:2012/08/02(木) 20:30:18.44 ID:???
1000
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。