SQL質疑応答スレ 10問目

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

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

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

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

前スレ:
SQL質疑応答スレ 9問目
http://pc11.2ch.net/test/read.cgi/db/1252492296/
2NAME IS NULL:2010/05/25(火) 21:50:33 ID:???
3NAME IS NULL:2010/05/25(火) 21:51:14 ID:???
過去スレ
SQL質疑応答スレ 8問目
http://pc11.2ch.net/test/read.cgi/db/1236253554/
SQL質疑応答スレ 7問目
http://pc11.2ch.net/test/read.cgi/db/1223525474/
SQL質疑応答スレ 6問目
http://pc11.2ch.net/test/read.cgi/db/1210940477/
SQL質疑応答スレ 5問目
http://pc11.2ch.net/test/read.cgi/db/1193486961/
【帰ってきた】SQL質疑応答スレ 4問目
http://pc11.2ch.net/test/read.cgi/db/1176553195/
【帰ってきた】SQL質疑応答スレ 3問目
http://pc11.2ch.net/test/read.cgi/db/1160458216/
【帰ってきた】SQL質疑応答スレ 2問目
http://pc8.2ch.net/test/read.cgi/db/1141622643/
【帰ってきた】SQL質疑応答スレ
http://pc8.2ch.net/test/read.cgi/db/1124178925/
SQL質疑応答スレ Part 2
http://pc8.2ch.net/test/read.cgi/db/1103113155/
SQL質疑応答スレ
http://pc8.2ch.net/test/read.cgi/db/1056973582/
4NAME IS NULL:2010/05/25(火) 21:51:55 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:2010/05/25(火) 21:52:36 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:2010/05/25(火) 21:53:17 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:2010/05/25(火) 21:54:00 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/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html
8NAME IS NULL:2010/05/26(水) 05:20:59 ID:bivGLNrt
さぐぇ
9NAME IS NULL:2010/05/26(水) 21:13:53 ID:???
>>1
10NAME IS NULL:2010/05/26(水) 21:38:51 ID:???
質問です。

・DBMS名とバージョン
  MySQL5.1.42

・テーブルデータ(アクセスログのようなもの)

ID CREATED
--+---------------------
1 2010/5/10 12:00:00
2 2010/5/10 15:00:00
3 2010/5/11 13:15:00
4 2010/5/14 10:00:00
5 2010/5/15 16:30:00

・欲しい結果
対象テーブルの日毎のレコード数
ただしグラフ化したいのでゼロの日はゼロと出力したい

・説明
SELECT date_format(created,'%Y/%m/%d') d, count(*) from test_table group by d;
とすると、日毎のレコード数が出力できるのは確認済です。
スキマ(5/12&5/13分)をゼロで出力する簡単な方法はないでしょうか。
11NAME IS NULL:2010/05/26(水) 21:47:00 ID:???
>>10
カレンダーテーブルを別途用意してOUTER JOIN

てかこれもFAQにしたほうがよかったかも?
1210:2010/05/26(水) 22:01:56 ID:???
>>11
薄々そんな気はしてたんですが、これが一番ですよね。
ありがとうございました。
13NAME IS NULL:2010/05/26(水) 22:57:21 ID:???
まあテーブルでもいいけどそこだけなら当月の日付一覧を検索するサブクエリでいいしょ。
1410:2010/05/27(木) 22:22:26 ID:PcEBL+w/
>>13
うわ、それ気になります!!

例えば今月の日付一覧を出力するSQLってどう書くんでしょう。
お願いします。
15NAME IS NULL:2010/05/27(木) 22:59:16 ID:???
アンケート生成システムを作っているのですが、
アンケート項目数が可変なのでアンケートテーブルを別途作り
さらに回答項目数(チェックボックスとか)も可変なので回答項目テーブルも作りました。

アンケートテーブル→アンケート項目テーブル→回答項目テーブル
という感じで紐づいてます。
ユーザさんが(会員制ではないためユーザテーブルはありません)回答したログはどこに置こうかと悩んで
結局回答ログテーブルを回答項目テーブルと紐付けて
1.ユーザID(回答時に暫定的に割り振る) 2.回答項目ID 3.テキストエリアの場合の回答用カラム
として作成しました。

精一杯考えて結局上記のようになったのですが
これだと例えばあるアンケートの回答一覧をユーザごとに出したい場合
アンケートIDから全ての項目IDを割り出してその項目ID全てに紐づいた回答項目IDを出し
その回答項目IDから回答テーブルを検索しなくてはならず煩雑です。

他の方法としてはアンケートテーブルに質問1 質問2 質問3...と数十個カラムを足すしか思いつかないのですが
何かいい方法がないでしょうか。
16NAME IS NULL:2010/05/27(木) 23:08:55 ID:???
回答項目テーブル、回答テーブルにアンケートID項目をつくる。
17NAME IS NULL:2010/05/27(木) 23:14:14 ID:???
ご回答ありがとうございます。そうします。こんな長い質問読んでくださりありがとうございます。
しかも以下間違ってました。読みづらくてごめんなさい。
×アンケート項目数が可変なのでアンケートテーブルを別途作り
○アンケート項目数が可変なのでアンケート項目テーブルを別途作り
18NAME IS NULL:2010/05/28(金) 00:01:52 ID:???
>>15
もしかしてjoinを知らない?
19NAME IS NULL:2010/05/28(金) 00:09:32 ID:???
>>18
知ってます。in句が重なるとパフォーマンスも落ちるし
もうちょっと簡潔に出来る方法ないかな…と思ってお聞きしました。
20NAME IS NULL:2010/05/28(金) 16:48:05 ID:???
>>19
もしかしてjoinを理解してない?
inなんて使う所が思い浮かばないんだが

つか、自分で考えたテーブルレイアウトとSQL書いてみ
21NAME IS NULL:2010/05/28(金) 21:16:30 ID:???
INNER JOINで質問。
2つのテーブルに同じ名前のフィールドがある時、結合するとどうなるか、どこかに解説はないでしょうか。
PHPからMySQLでやってみて、そのフィールド名のデータを取ったら片方のデータは取り出せた。もう片方は取り出せない。
phpMyAdminで試してみたら結果には両方のフィールドが入っています。
好きな方のデータを取り出すにはどうやったら良いのでしょうか。テーブル名.フィールド名だとエラーでした。
22NAME IS NULL:2010/05/28(金) 22:03:51 ID:???
まさか列名はテーブル名で修飾できるって知らないのか?
23NAME IS NULL:2010/05/28(金) 22:50:47 ID:???
それが何故か上手くいかないんで。
テーブル名付きで指定すると、そんな名前ありませんみたいなエラーが出ちゃう。
24NAME IS NULL:2010/05/28(金) 23:19:29 ID:0+Zm+ajr
ぐだぐだ書いてないでそのSQL晒した方が早いんでね?
25NAME IS NULL:2010/05/29(土) 00:59:17 ID:???
うまくいくのでSQL待ちだな
26NAME IS NULL:2010/05/29(土) 03:56:39 ID:???
テーブル名に別名つけてるのにその別名で修飾してないと予想
27NAME IS NULL:2010/05/29(土) 06:32:44 ID:???
MySQL5.0.77
テーブルAの中の特定のidを持つレコードのうち特定の範囲だけをUPDATEしたい場合、例えば
UPDATE A SET flag=1 WHERE id=1 ORDER BY date DESC LIMIT 10,10
とやるとMDB2 Error: syntax errorになります。
UPDATE A SET flag=1 WHERE id=1 ORDER BY date DESC LIMIT 10
なら大丈夫なんですが、オフセットを指定するにはどうすればいいでしょうか。
28NAME IS NULL:2010/05/29(土) 07:05:12 ID:???
id以外にキーはないのか?
29NAME IS NULL:2010/06/02(水) 06:50:35 ID:CZR/Bmnf
まったくわからないのです教えてください・・

1、名前はわかっているが、コードが不明な商品の受注明細を照会するSELECT文を記述せよ。
副照会:商品名からコードを求めるSELECT文
主照会:商品コードから商品の受注明細を照会するSELECT文

2、平均受注個数を超える商品に仕入れ先を照会するSELECT文を記述せよ。
副照会:商品の平均受注個数を求めるSELECT文
主照会:商品コード別に受注個数合計を求め、受注個数合計 > 平均受注個数であれば、仕入れ先を表示

3、1月と2月に\50,000以上の注文があった顧客からの3月受注額を照会するSELECT文を記述せよ。
副照会:4月と5月に受注額合計が共に50000以上であるという条件をみたす顧客を照会
主照会:顧客別に6月の受注額合計を求めるSELECT文。

よろしくお願いいたします・
30NAME IS NULL:2010/06/02(水) 07:12:31 ID:???
宿題は自力でやれ
31NAME IS NULL:2010/06/02(水) 09:18:29 ID:???
答えられる人がいないスレw

32NAME IS NULL:2010/06/02(水) 09:36:11 ID:???
まあ、質問テンプレ全部守れとは言わないが
ここはエスパーに回答してもらうスレじゃないんでな
33NAME IS NULL:2010/06/02(水) 11:29:29 ID:???
元のテーブル構成まで推測しろとw
34NAME IS NULL:2010/06/02(水) 11:32:13 ID:???
学校の宿題は自分でな。
35NAME IS NULL:2010/06/02(水) 22:59:15 ID:???
だめだw
1はまず間違いないだろうが2と3は別解がありすぎるw
36NAME IS NULL:2010/06/02(水) 23:25:18 ID:???
>>29

1.
select 商品コード from コードテーブル where 商品名 = ?

select 商品受注明細 from 商品受注明細テーブル
join 商品コードテーブル on 商品コード = 商品受注明細テーブル.商品コード
where 商品コードテーブル.商品名 = ?

2.
select 商品平均受注個数 from 商品平均受注個数テーブル

select 商品コード別受注個数合計, 仕入先
from 商品コード別受注個数合計テーブル
where 受注個数合計 > 商品平均受注個数

3.
select 顧客 from 顧客テーブル
where4月の受注額合計 > 500000
and 5月の受注額合計 > 500000

select 6月の顧客別受注額合計
from 顧客別受注額合計テーブル
37NAME IS NULL:2010/06/03(木) 00:30:50 ID:???
俺の質問に誰か答えてくれよ
38NAME IS NULL:2010/06/03(木) 00:31:40 ID:???
質問どれだよw
39NAME IS NULL:2010/06/03(木) 13:53:58 ID:???
MySQL5です。

maindata
-----------------------------
main_id | main_name | junle
-----------------------------
1000001 | aaaaaaaaa | 1
1000002 | bbbbbbbbb | 2
1000003 | ccccccccc | 1
1000004 | ddddddddd | 3
1000005 | eeeeeeeee | 1

itemdata
--------------------
item_id | item_name
--------------------
9000001 | AAAAAAAAA
9000002 | BBBBBBBBB
9000003 | CCCCCCCCC
9000004 | DDDDDDDDD
9000005 | EEEEEEEEE

itemlist
------------------
main_id | item_id
------------------
1000001 | 9000001
1000001 | 9000004
1000002 | 9000002
1000002 | 9000005
1000004 | 9000002
1000004 | 9000004
1000004 | 9000005

という3つのテーブルがある場合に、maindata.junle='1'を条件に
main_id | main_name | itemlists
----------------------------------------------------
1000001 | aaaaaaaaa | AAAAAAAAA DDDDDDDDD
1000003 | ccccccccc |
1000004 | eeeeeeeee | BBBBBBBBB DDDDDDDDD EEEEEEEEE
----------------------------------------------------
※itemlistsは空白で連結

という結果を求めたいと思います。
サブクエリを利用して一度に求めることは可能でしょうか?
それとも、アプリケーション側でループの際に都度itemlistsを生成する必要がありますでしょうか?
40NAME IS NULL:2010/06/03(木) 13:59:31 ID:???
>>39
maindataテーブルとitemdataテーブルをitemlistテーブルを媒介にしてinner join
あとは普通に検索条件をかければいい
4139:2010/06/03(木) 15:15:55 ID:???
>>40
ありがとうございます。

・・・でも、そのSQLの書き方が判りません…
大変申し訳ありませんが、サンプルをご提示いただけると助かります。
よろしくお願いいたします。
42NAME IS NULL:2010/06/03(木) 16:20:14 ID:???
ああ縦を横にしようとしているのか
43NAME IS NULL:2010/06/03(木) 18:07:05 ID:???
44NAME IS NULL:2010/06/03(木) 18:28:19 ID:???
>>39
つ GROUP_CONCAT
4539:2010/06/03(木) 19:50:07 ID:???
>>44
ありがとうございました。
おかげさまで、目的を達成する事ができました。
46NAME IS NULL:2010/06/03(木) 21:29:20 ID:???
テーブルの主キーを日付にする時、一般論としてDate型で持つのとNumber(14)やNumber(17??年くらいからのミリ秒・・16桁くらい?)で持つのとで速度に差は出ますか?
? <= xx_date and xx_date < ? のように範囲検索を多用する場合です。
データベースはMySQLかPostgreSQLだと思ってください。
47NAME IS NULL:2010/06/03(木) 23:29:21 ID:???
厳密には当然違いはある。一般論としては悩むだけムダ。
48NAME IS NULL:2010/06/04(金) 19:36:50 ID:???
【質問テンプレ】
・DBMS名とバージョン
 MySQL5.0.77

・テーブルの構造
CREATE TABLE IF NOT EXISTS table (
id integer NOT NULL auto_increment,
value integer NOT NULL,
PRIMARY KEY (id),
);

・テーブルデータ
ID  VALUE
--+--------
1  相沢
2  飯田
3  上井


・操作
INSERT INTO table(id, value) values
(NULL, '遠藤'), (NULL, '岡田');

・欲しい結果
4
5

・説明
ID列をauto_incrementにしているのですが、要素を追加したときに
そのIDを取得したいと考えています。どのようにしたらいいでしょうか?
49NAME IS NULL:2010/06/05(土) 09:06:58 ID:???
放置されてる質問はわかる奴がここにはいないってことか
手頃な金額で依頼したSQL書いてくれるサービスないかな
50NAME IS NULL:2010/06/05(土) 15:17:12 ID:???
>>48
INSERTは一件ずつにする。
INSERTしたら
SELECT LAST_INSERT_ID() AS LAST
51NAME IS NULL:2010/06/05(土) 19:47:59 ID:IU+phbd/
【質問テンプレ】
・DBMS名とバージョン
 postgresql 8.2.4

・説明
 left join や right join を例えばsybaseでのwhere句の式"*="ように
 postgresqlでも符号であらわすことはできるのでしょうか?
 (テンプレに沿ってなくてすみません。)
52NAME IS NULL:2010/06/05(土) 20:47:31 ID:???
出来ないんじゃね。メリットないし。
OracleとSQLServer(sybase)だけだろうな。
53NAME IS NULL:2010/06/05(土) 22:40:48 ID:???
【質問テンプレ】
・DBMS名とバージョン
Oracle Database 10g 10.2.0.1

・テーブルデータ
 なし

・欲しい結果
 指定した年月に対応する年月日

・説明
年月(yyyyMM)を指定し、その年月に対応する年月日を取得したい

---------
yyyyMMdd
---------
20100601
20100602
 ・
 ・
 ・
20100630

できるにはできたのですが、スマートでなかったので・・・
お願いします。

hoge:201006

SELECT  TEST
FROM   (
      SELECT hoge || '01' AS TEST FROM DUAL
      UNION ALL
      SELECT hoge || '02' AS TEST FROM DUAL
      UNION ALL
      ・
      ・
      ・
      SELECT hoge || '31' AS TEST FROM DUAL
     )
WHERE  TEST <= TO_CHAR(LAST_DAY(hoge || '01'),yyyyMMdd)
ORDER BY TEST
54NAME IS NULL:2010/06/05(土) 23:23:59 ID:???
55NAME IS NULL:2010/06/05(土) 23:37:35 ID:???
最大でも31行までのレコードを得られれば良いので、適当なビューを使えば
行数を返す関数を作る必要も無い。

↓適当に作ってみた
SQL> select to_char(TEST,'YYYYMMDD') as TEST from
2 ( select to_date( '201006','YYYYMM' )+rownum-1 as TEST from all_catalog where rownum<=31 )
3 where trunc(TEST,'MM')=to_date('201006','YYYYMM');

TEST
------------------------
20100601
20100602
 :
20100629
20100630

30行が選択されました。

10gなら
SQL> select to_char(TEST,'YYYYMMDD') as TEST from
2 ( select to_date( '201006','YYYYMM' )+level-1 as TEST from dual connect by level<=31 )
3 where trunc(TEST,'MM')=to_date('201006','YYYYMM');
なんての可能だけど、使い所が限られるかも。
56NAME IS NULL:2010/06/06(日) 00:24:26 ID:???
SQLでデータを「作りたがる」人は相変わらずいるもんだね。
57NAME IS NULL:2010/06/06(日) 03:16:00 ID:???
まあ、なんでもSQLでやりたくなる気持ちはわからんでもないが...
>>11も言ってるけど、本気でFAQのテンプレ化したほうがいいかもな

ただ、PostgreSQLみたいに連番生成する関数がもっとほかのDBに広まってもいいとも思う
58NAME IS NULL:2010/06/06(日) 08:27:10 ID:???
PostgreSQLは新しい実装に積極的だよね。
果敢にチャレンジし続けるイメージがある。
5953:2010/06/06(日) 10:07:57 ID:???
>>54-55
ありがとうございます
60NAME IS NULL:2010/06/06(日) 19:29:43 ID:sC7klrj/
create databaseとcreate schemaのsqlがあるわけですが、
database=schemaじゃないんですか?
61NAME IS NULL:2010/06/06(日) 19:37:25 ID:???
違う。
6260:2010/06/06(日) 19:59:13 ID:sC7klrj/
それじゃ、スキーマって何なんですか?
63NAME IS NULL:2010/06/06(日) 20:02:47 ID:???
心と心の間を埋めるものだよ
64NAME IS NULL:2010/06/06(日) 20:04:06 ID:???
SQL92 には CREATE DATABASE なんて存在しないな。
6560:2010/06/06(日) 20:24:09 ID:sC7klrj/
そんじゃ、ユーザー=スキーマってことでおk?
66NAME IS NULL:2010/06/06(日) 20:47:23 ID:???
厳密には違うが、ユーザー=スキーマな実装もあるかもしれない
6760:2010/06/06(日) 20:59:25 ID:sC7klrj/
>>66
それだけわかれば十分だよ
厳密な意味はそのうち勉強することにする

thx
68NAME IS NULL:2010/06/06(日) 21:48:50 ID:???
>>62
「テーブルを作った人」くらいの感覚でいいよ。
69NAME IS NULL:2010/06/06(日) 22:44:45 ID:???
昔受けた講習で「スキーマとはテーブルなどの所有者のことです」って
臆面もなく説明されたことがあったな
70NAME IS NULL:2010/06/07(月) 01:32:16 ID:???
>>65
スキーマはオブジェクトの集合。
Oracleのようにユーザとスキーマが一対一で不可分の場合は
ユーザ=スキーマで差し支えないけど、
SQL Serverのようにユーザとスキーマが別々に定義されていて、
それぞれを結び付けるようなデータベースもある。
71NAME IS NULL:2010/06/07(月) 19:43:29 ID:???
【質問テンプレ】
・Oracle10g


TableA
IDa C1
-------------
A1  X
A2  Y
A3  Z

TableB
IDb C2
-------------
B1  S
B2  T
B3  U

TableC(TableAとTableBを紐付けているテーブル)
IDa IDb
-------------
A1  B1
A3  B3


欲しい結果
IDa IDb C1 C2
-----------------
A1  B1 X  S
A2    Y  
A3  B3 Z  U
   B2    T

説明
TableA,B,Cの3つのテーブルからTableCに存在しないIDのTableAとTableBのデータも出力したい
>>39と似てる気もしますが、よろしくお願いします。
72NAME IS NULL:2010/06/07(月) 19:59:01 ID:???
ヒント:OUTER JOIN
73NAME IS NULL:2010/06/07(月) 20:18:17 ID:???
SELECT IDa, IDb, C1, C2 FROM TableA LEFT OUTER JOIN TableC USING(IDa) FULL OUTER JOIN TableB USING(IDb) ORDER BY IDa
74NAME IS NULL:2010/06/07(月) 20:36:29 ID:???
>>73
こんな単純にできたんですね・・・
2時間試行錯誤してた自分ェ・・・
ありがとうございました。
75NAME IS NULL:2010/06/07(月) 21:56:16 ID:???
mysqlでsqlの勉強をしているところなのですが、
alter databaseでdbの名前を変えられないんですか?
76NAME IS NULL:2010/06/07(月) 22:17:46 ID:???
RENAME DATABASE xdb TO ydb
77NAME IS NULL:2010/06/07(月) 23:01:55 ID:???
>>76
thx
78NAME IS NULL:2010/06/09(水) 00:34:22 ID:???
SQLを仕事で書いてますが、困ってます。

○テーブルA
number
nendo
gaku
riyu

○テーブルB
number
code

テーブルAのgakuの値を更新するSQLを作りたいです。条件は

・テーブルAのriyu <> -1の全てのレコードのgakuに値をセットする。
セットする値は、レコードそれぞれのnumberでテーブルAとテーブルB
 を結合して、テーブルBのcode=1なら1000,code=2なら2000、code=3なら3000

以下のようなSQLを書きましたがうまくいきません。


update テーブルA a set gaku = (
select
case
WHEN b.code = 1 1000
WHEN b.code = 2 2000
WHEN b.code = 3 3000
ELSE 0
END gaku
from テーブルA a,テーブルB b
where a.number = b.number
and (a.number,a.nendo) IN ( select number,nendo from テーブルA where riyu <> -1 )
)
where (a.number,a.nendo) IN ( select number,nendo from テーブルA where riyu <> -1 )


DBはOracle10gです。
よろしくお願いします。
79NAME IS NULL:2010/06/09(水) 02:23:38 ID:???
UPDATE テーブルA a
 SET a.gaku = (CASE (SELECT b.code FROM テーブルB b WHERE b.number = a.number) WHEN '1' THEN '1000' WHEN '2' THEN '2000' WHEN '3' THEN '3000' ELSE NULL END)
WHERE a.riyu != '-1'

結合する必要ない・・よね?
UPDATEは一気にぜんぶ書くんじゃなくて、更新したいレコードを抽出するSQL→SETの中身と順に書くのがええかと。
80NAME IS NULL:2010/06/09(水) 18:53:04 ID:???
MYSQLやSQLITEでTIMESTAMP型の比較ってどうやって書くのでしょうか?
条件に現在の時間から3時間以内のデータを取り出す等のようなSQL文を書きたいのですが。
ただ現在の時間からというのなら
select * from hoge where time < CURRENT_TIMESTAMP
で良さそうなんですが、時間の指定がよくわかりません。
81NAME IS NULL:2010/06/09(水) 20:09:13 ID:???
そのDBMSで試してないけど、たとえば
'2010/06/09 02:23:38'::timestamp
82NAME IS NULL:2010/06/09(水) 21:11:50 ID:???
83NAME IS NULL:2010/06/09(水) 21:26:44 ID:???
create databaseでデータベースを作成したわけですが、
rootでデータベースを作成しました
rootでshow tables;をすると作ったデータベースが見えるのですが、
一般ユーザからはshow tables;をしてもデータベースが見えません

なんでですか?
dbms:mysql 5
84NAME IS NULL:2010/06/09(水) 21:51:26 ID:???
権限がないからです
そしてSQL言語でない、MySQL固有のコマンドの質問はスレ違いです
85NAME IS NULL:2010/06/09(水) 21:52:18 ID:???
>>84
そうですか
86NAME IS NULL:2010/06/09(水) 23:04:49 ID:???
MySQLでのやり方をお尋ねします。

table1
−−−−−−−−−−−
| id1 | column1 |
−−−−−−−−−−−
|  1 | ああああ1 |
|  2 | ああああ2 |
−−−−−−−−−−−

table2
−−−−−−−−−−−−−−−
| id2 | id1 | column2 |
−−−−−−−−−−−−−−−
|  1 |  2 | かかかか1 |
|  2 |  1 | かかかか2 |
|  3 |  2 | かかかか3 |
−−−−−−−−−−−−−−−

id1が一致するものをくっつけたいのですが、table2でid1=2のレコードが2つあるので
その場合はid2が大きいほうを選びたいと思っています(つまりid2=3のレコードです)。
−−−−−−−−−−−−−−−−−−−−−
| id1 | id2 | column1 | column2 |
−−−−−−−−−−−−−−−−−−−−−
|  1 |  2 | ああああ1 | かかかか2 |
|  2 |  3 | ああああ2 | かかかか3 |
−−−−−−−−−−−−−−−−−−−−−

CREATE TEMPORARY TABLE tmp SELECT MAX(id2) AS id2 FROM table2 GROUP BY id1;
SELECT * FROM table1,table2 WHERE table1.id1=table2.id1 AND table2.id2=tmp.id2;
試行錯誤してこのようになりましたが、一文にすっきりまとめることはできないでしょうか?
87NAME IS NULL:2010/06/09(水) 23:11:22 ID:???
8878:2010/06/09(水) 23:45:21 ID:???
>>79
レス遅れて申し訳ありません。

なるほど、こんな書き方があったんですね。


明日早速試してみます。
ありがとうございました。
89NAME IS NULL:2010/06/10(木) 00:26:53 ID:???
>>87
ありがとうございます。
>>4はテーブルが1つの場合で、>>86は2つの場合ですが、
やり方は同じですか?

4行目の「from TableName A」の部分をテーブル2つにする方法が
わからなくて困っています。

from table1 A,table2 C とか
from table1,table2 A とか
やってみましたが、エラーが出ます。
9086、89:2010/06/10(木) 00:45:34 ID:???
度々すみません。

SELECT A.id1,
A.column1,
B.*
FROM table1 A
INNER JOIN
(SELECT *,MAX(id2) as max_id2
FROM table2
GROUP BY id1
) B
ON A.id1 = B.id1

とやってみたら

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
| id1 | column1 | id2 | id1  | column2 | max_id2 |
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
|  1 | ああああ1 |  2 |  1  | かかかか2 |   2  |
|  2 | ああああ2 |  1 |  2  | かかかか1 |   3  |
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

という結果になってしまいました。
最後の行に「AND B.max_id2 = table2.id2」のような指定をする必要があるんでしょうか。
これを追加すると、Unknown column 'table2.id2' in 'on clause'というエラーになります。

91NAME IS NULL:2010/06/10(木) 00:50:22 ID:???
table2に>>4を適用して、その結果とtable1を結合すればいいんじゃね?
92NAME IS NULL:2010/06/10(木) 00:51:03 ID:???
JOINしたら1テーブルに扱えるでしょ。普通に並べて書けば。

SELECT a.id1, b.id2, a.column1, b.column2, c.max_id2
FROM table1 a
INNER JOIN table2 b ON a.id1 = b.id1
INNER JOIN (SELECT id1, MAX(id2) AS max_id2 FROM table2 GROUP BY id1) c ON b.id1 = c.id1
WHERE b.id2 = c.max_id2

個人的には>>4のやり方より↓の方が直感的だと思うんだが。

SELECT a.id1, b.id2, a.column1, b.column2
FROM table1 a INNER JOIN table2 b ON a.id1 = b.id1
WHERE id2 = (SELECT MAX(id2) FROM table2 WHERE id1 = a.id1 GROUP BY id1)
9386、89:2010/06/10(木) 01:00:03 ID:???
>>91-92
ありがとうございます。
>>92さんのSQL文はどちらも正しく動きました!
下のほうがスッキリしているので、じっくり見て仕組みを考えてみたいと思います。
こういうのをさっと書けるようになりたいですけど、もっと慣れないと混乱して無理っぽいです。
精進します。
94NAME IS NULL:2010/06/10(木) 04:00:00 ID:???
>>92
GROUP BYは要らないだろ。
WHERE b.id2 = (SELECT max(id2) FROM table2 WHERE table2.id1 = a.id1)
95NAME IS NULL:2010/06/10(木) 12:47:18 ID:???
>>94
おうふ
全くそのとおりでござる
96NAME IS NULL:2010/06/10(木) 15:06:59 ID:???
教えてください
MS Accessで下記の(dept,place)でのくくりで
count のtop3を抽出したいです

table a
dept|place|ext|count
aaaa|aaaaa|jar|10
aaaa|aaaaa|com|4
aaaa|aaaaa|scr|20
aaaa|aaaaa|exe|80
aaaa|aaaaa|bat|2
aaaa|bbbbb|ace|10
aaaa|bbbbb|arj|4
aaaa|bbbbb|zip|20
aaaa|bbbbb|rar|80
aaaa|bbbbb|lzh|2
bbbb|aaaaa|mdb|10
bbbb|aaaaa|xls|4
bbbb|aaaaa|ppt|20
bbbb|aaaaa|doc|80
bbbb|aaaaa|txt|2
bbbb|bbbbb|gif|10
bbbb|bbbbb|png|4
bbbb|bbbbb|jpg|20
bbbb|bbbbb|bmp|80
bbbb|bbbbb|tif|2

aaaa|aaaaa|exe|80
aaaa|aaaaa|scr|20
aaaa|aaaaa|jar|10
aaaa|bbbbb|rar|80
aaaa|bbbbb|zip|20
aaaa|bbbbb|ace|10
bbbb|aaaaa|doc|80
bbbb|aaaaa|ppt|20
bbbb|aaaaa|mdb|10
bbbb|bbbbb|bmp|80
bbbb|bbbbb|jpg|20
bbbb|bbbbb|gif|10

こんな感じ
さっぱりわかりません
助けてください
97NAME IS NULL:2010/06/10(木) 16:22:37 ID:???
countが重複したときは?
98NAME IS NULL:2010/06/10(木) 16:57:32 ID:???
count のtop3 ってのはトータルでのトップ3なのか、
(dept,place)でのくくり ごとのトップ3なのか?
99NAME IS NULL:2010/06/10(木) 18:02:31 ID:???
>>97
重複は稀すぎるので、今回考えなくてかまいません

>>98
>>96の出力例みればわかってもらえると思ったのですが
>(dept,place)でのくくり ごとのトップ3なのか?
こちらです

100NAME IS NULL:2010/06/10(木) 18:46:52 ID:???
>>99
>出力例みればわかってもらえると思ったのですが
お前の出力例ではトップ3は全部の組み合わせで同じだから判断できねえだろうが

SELECT * FROM TableA a WHERE count IN (
SELECT TOP 3 count FROM TableA WHERE dept=a.dept AND place=a.place ORDER BY count DESC
)
ORDER BY dept,place,count DESC
101NAME IS NULL:2010/06/10(木) 18:57:36 ID:???
>>100
>お前の出力例ではトップ3は全部の組み合わせで同じだから判断できねえだろうが
ここの意味がわからなくてイラッっとしてますが
ものすごく正解のSQLいただいたので、土下座して感謝します
まじでありがとうございました
102NAME IS NULL:2010/06/10(木) 19:01:05 ID:???
>>101
お前もう来るな。
103NAME IS NULL:2010/06/10(木) 19:15:43 ID:???
「重複は考えなくていい」もそうだが、仕様とは何かをまずわかってないんだろうな
104NAME IS NULL:2010/06/10(木) 19:34:40 ID:X6f9EMRL
>イラッっとしてますが


www
105NAME IS NULL:2010/06/10(木) 23:52:11 ID:???
俺もイラッとしたw

もちろん
>お前の出力例ではトップ3は全部の組み合わせで同じだから判断できねえだろうが
がわからないからだ。
106NAME IS NULL:2010/06/11(金) 00:49:06 ID:???
日付順で並べ替えて10件目から20件目までUPDATEしたい場合
どう書けばいいでしょうか?
LIMIT 10,20が使えないぽい
107NAME IS NULL:2010/06/11(金) 01:20:16 ID:???
UPDATE table1 a
SET column1 = 'hoge'
WHERE a.主キー IN (table1の日付順の10件目から20件目までの主キーを取得するSELECT文)
108NAME IS NULL:2010/06/11(金) 22:44:13 ID:???
table as a
table a
この2つってどう違うんでしょうか?

ついでに、そういう細かいことがわかるサイトも
教えていただけると助かります。
109NAME IS NULL:2010/06/11(金) 23:59:30 ID:???
その2つは同じなのでそういう細かいことって言われても何とも答えづらい。
>>2を見ればDBMSごとの文法は知ることができるし
http://savage.net.au/SQL/ で標準SQLの正しい文法が分かる。
110NAME IS NULL:2010/06/12(土) 00:06:10 ID:nH6zlsmE
今日、OracleでFULL OUTER JOINを使って、ちょっとはまったのですが、
SQL ServerとOracleでSQLの解釈に違いってあるもんでしょうか?

SQL Serverの場合

SELECT *
FROM 名簿 A
FULL OUTER JOIN ON 名簿 B
ON A.部活 = 'テニス部' AND B.部活='陸上部'
A.名前=B.名前

のような書き方で、名簿テーブルの中でテニス部に所属している人の一覧
と、陸上部に所属している人の一覧を結びつけられると思ったのですが、
どうもOracleの場合は、ON句でWHERE句の条件を書いても絞り込まれない
ような印象でした。

最終的には、
SELECT *
FROM ( SELECT *
     FROM 名簿
     WHERE 部活='テニス部') A
FULL OUTER JOIN
     (SELECT *
     FROM 名簿
     WHERE 部活='陸上部') B
ON A.名前 = B.名前
のような形にして対応しました。

どうもOracleはなんでもかんでもサブクエリにしないとまともな
SQLが書けない印象。わたしの勘違いなのかなぁ。
111NAME IS NULL:2010/06/12(土) 00:51:44 ID:???
SQLServerはそんなまともじゃないSQLでも動くんだな。
112NAME IS NULL:2010/06/12(土) 01:03:47 ID:???
>>109
ありがとうございます。
読んで勉強します!
113NAME IS NULL:2010/06/12(土) 02:33:36 ID:???
>>110,111
SQL Serverでも上のSQLはそのままじゃ動かないぞ
ONが多いのとANDが抜けてるとしても、そもそもその二つのSQLは同じ結果じゃないと思うが
なにがしたいのかいまいちよくわからん

それぞれのDBMSのバージョンいくつだ?
とりあえず full join バグ あたりでググってみるとなんかあるかもよ
114NAME IS NULL:2010/06/12(土) 02:34:29 ID:???
SQLServerで複数列を更新する際に、
同じ条件なんだけど更新する内容が列によって違う場合、
以下のように同じ条件をだらだらと書かずに出来ないもんでしょうか?

UPDATE table_a SET
 cd5 = CASE WHEN fee IN (80, 90) THEN SUBSTRING(cd, 1, 5)
       ELSE NULL
       END,
 cd2 = CASE WHEN fee IN (80, 90) THEN SUBSTRING(cd, 1, 2)
       ELSE NULL
       END,
 varkey = CASE WHEN fee IN (80, 90) THEN post + user
       ELSE post
       END


↓こんな感じにまとめられないですかね?
UPDATE table_a SET
 (cd5, cd2, varkey) = CASE WHEN fee IN (80, 90)
                THEN (SUBSTRING(cd, 1, 5), SUBSTRING(cd, 1, 2), post + user)
                ELSE (NULL, NULL, post)
                END
115NAME IS NULL:2010/06/12(土) 02:39:03 ID:???
2回投げるのが楽そうだけど、どうしても一回でやりたいのかなぁ
116NAME IS NULL:2010/06/12(土) 02:51:54 ID:???
最初は二回に分けてたけど、レコードが数十万件あるから一回で済ましたほうが効率良いかと思いまして・・・
117NAME IS NULL:2010/06/12(土) 02:58:00 ID:???
>>114
特定のDBMSに固有のSQLはそのDBMSのスレで聞け

CASE使ってまで1文で更新したい理由がわからん
俺なら素直に
UPDATE table_a SET
cd5=SUBSTRING(cd, 1, 5),
cd2=SUBSTRING(cd, 1, 2),
varkey=post + user
WHERE
fee IN (80, 90)

UPDATE table_a SET
cd5=NULL,
cd2=NULL,
varkey=post
WHERE
fee NOT IN (80, 90)
の二つ流すが
118NAME IS NULL:2010/06/12(土) 03:18:13 ID:???
>>117
二つ流すのははっきり率悪いだろう・・・。

>>114
そのSQLでしょうがないんじゃね。
119NAME IS NULL:2010/06/12(土) 09:53:54 ID:d+6B+4E8
120NAME IS NULL:2010/06/12(土) 09:59:45 ID:???
すなおに二つにします。
皆さんありがとうございました
121NAME IS NULL:2010/06/12(土) 10:02:18 ID:???
あ、まだどっちがパフォ良いか試してないんでそれから検討します。
122NAME IS NULL:2010/06/12(土) 11:15:33 ID:1rzl2/wK
Oracleでの「定数との比較を含む外部結合」をACCESS形式に変換したいです。

<TABLE1>      <TABLE2>
|COLUM1|COLUM2| |COLUM3|COLUM4|COLUM5|
├――――┼――――┤ ├――――┼――――┼――――┤
| あああ |  XX  | | かかか |  XX  | AAA  |
├――――┼――――┤ ├――――┼――――┼――――┤
| いいい |  YY  | | ききき |  XX  | BBB  |
└――――┴――――┘ ├――――┼――――┼――――┤
                 |  くくく  | YY   |  AAA |
                 └――――┴――――┴――――┘

上の2つのテーブルに対して以下のSQLを実行すると下の実行結果が得られると思います
(今机上ででっちあげたもんだから試してないけど)

SELECT TABLE1.COLUM1, TABLE2.COLUM3
FROM TABLE1, TABLE2
WHERE TABLE1.COLUM2=TABLE2.COLUM4(+) AND 'AAA'=TABLE2.COLUM5(+)

<実行結果>
|COLUM1|COLUM3|
├――――┼――――┤
| あああ | かかか |
├――――┼――――┤
| いいい |      |
└――――┴――――┘

これを、ACCESS文法に変えたいのですが、「TABLE1.COLUM2=TABLE2.COLUM4(+) AND 'AAA'=TABLE2.COLUM5(+)」
の部分(定数との比較を含む外部結合)のやり方がわかりません。
「TABLE1 LEFT JOIN TABLE2 ON TABLE1.COLUM2=TABLE2.COLUM4 AND TABLE2.COLUM5='AAA'」
では上手くいきませんでした。
123NAME IS NULL:2010/06/12(土) 11:32:54 ID:???
・まずACCESS文法って造語が意味分からない
・結果の2行目に"くくく"が表示されないのが意味分からない
・定数との外部結合をする意味がわからない
・行選択のための条件をWHERE句でなくON句で書く意味がわからない
124NAME IS NULL:2010/06/12(土) 11:39:04 ID:???
実行結果が(いいい,くくく)じゃ無いのはおかしくないか?
なにがしたいのか不明だ。どう上手くいかなかったんだよ
外部結合である必要ないんじゃないのか?
125NAME IS NULL:2010/06/12(土) 12:00:02 ID:???
>まずACCESS文法って造語が意味分からない
Oracle用のSQL表記とmdbファイル参照する時のSQLと違うでしょ?

>結果の2行目に"くくく"が表示されないのが意味分からない
TABLE1.COLUM2=TABLE2.COLUMと'AAA'=TABLE2.COLUM5をともに満たすTABLE2の
レコードがある場合はCOLUM3を表示し、無い場合は外部結合なんでCOLUM1だけ
表示する、と思うだけど

>定数との外部結合をする意味がわからない
だって元のSQLがそうなってるんだもん
Oracleサーバを参照してたSQLをサーバ負荷軽減のためにローカルにDLした
mdbを参照するようにしたいんで、OracleSQLと等価なmdb用SQLに変換したいんだ

>行選択のための条件をWHERE句でなくON句で書く意味がわからない
でも「'AAA'=TABLE2.COLUM5(+)」(COLUM5が'AAA'に等しいTABLE2のレコードがあれば
実行結果のCOLUM3を表示し、なければCOLUM3はNULLにしてCOLUM1だけ表示する)
っていうのはmdb用SQLじゃWHERE句に乗せられないでしょ
Oracleなら(+)付ければ一発だけど
126NAME IS NULL:2010/06/12(土) 12:03:46 ID:???
TABLE2の3行目は ('くくく', 'YY', 'BBB') の間違いじゃないの?
でなければOracleだってその実行結果にはならん。
そうだと仮定して、
select T1.COLUM1,
    T2.COLUM3
from  TABLE1 T1
    left outer join
    (select *
    from  TABLE2
    where COLUM5 = 'AAA'
    ) T2
    on T1.COLUM2 = T2.COLUM4
;
127NAME IS NULL:2010/06/12(土) 12:22:16 ID:???
>>126
ありがとうございます
まあぶっちゃけ実行結果はどうでもよくてOracle形式と等価なmdb用SQLさえ
わかればよかったんで適当でした
すいません

ただFROM句に副問合せを含むとDAOからの実行が出来なくなる気が・・・
(似たようなSQLでmdbのSQLビューからは実行できたのにDAOからは出来なかったことあり)
ともあれありがとうございます
参考にします
128NAME IS NULL:2010/06/12(土) 12:32:52 ID:???
サンプルが不適切なんで要件が捻じ曲がった可能性があるけど
まあ質問者の自業自得だな
129NAME IS NULL:2010/06/12(土) 13:59:38 ID:???
つかそれなら本人がダメだったって言ってるSQLで行ける気がするんだがな
130NAME IS NULL:2010/06/13(日) 19:03:28 ID:???
alter tableで列にnot null制約を追加したいのですが、
modify 列名 データ型 not null
と、わざわざデータ型を入力しないと駄目なのでしょうか?
いちいちデータ型を記入するのは面倒なんですが
131NAME IS NULL:2010/06/13(日) 19:31:24 ID:???
少なくともOracleではデータ型は書かなくてもいいんだけど
DBMSは何なの?
132130:2010/06/13(日) 21:41:34 ID:???
>>131
mysqlを使っています
133NAME IS NULL:2010/06/13(日) 21:42:00 ID:bWmBmCbn
mysqlと見た
134NAME IS NULL:2010/06/14(月) 06:43:40 ID:???
>>121
そもそもそのSQLってしょっちゅう流すわけじゃないでしょ?
移行かなんかのバッチだよね。
もしそうなら、高々数十万件の更新の処理なんてバッチとしてはすぐ終わる部類だし、
せっせとCASE文書いて漏れがないかを検証する作業がもったいないと思わんかね。
135NAME IS NULL:2010/06/14(月) 07:22:12 ID:???
>>134
しょっちゅう流します
136NAME IS NULL:2010/06/14(月) 12:24:45 ID:???
>>135
設計見直した方がいいんじゃねえか
137NAME IS NULL:2010/06/14(月) 13:02:55 ID:???
どう見直すんだろw
138NAME IS NULL:2010/06/14(月) 13:45:08 ID:???
まあ、設計はスレ違いだし、提示されてない前提条件もあるのかもしれんが
たとえば
初めからCD1を分割しておけば、一部切り出して別コードにするなんて不要
毎回UPDATEしないで、UPDATE後の値を取得できるVIEWをつくるなりトリガで更新する
とか
139NAME IS NULL:2010/06/14(月) 19:08:55 ID:???
期間の抽出について相談です。

元情報
ID    START    END
-----   -----    -----
10    2010/06/01  2010/06/12
10    2010/06/13  2010/06/14
10    2010/06/15  NULL
20    2010/06/01  2010/06/11
20    2010/06/13  2010/06/15



欲しい情報
ID    START    END
-----   -----    -----
10    2010/06/01  NULL
20    2010/06/01  2010/06/11
20    2010/06/13  2010/06/15


・開始日、終了日の期間重複はなし
・IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日
・期間は綺麗に連続(ID=10)することもあれば非連続することもある(ID=20)

アドバイス願います。
140139:2010/06/14(月) 19:13:32 ID:???
追記、DBはOracle 11gです。
141NAME IS NULL:2010/06/14(月) 20:11:58 ID:???
こうかな?
select "ID",
    min("ROOT_START"),
    "END"
from (select "ID",
       connect_by_root "START" as "ROOT_START",
       "END"
   from "TableName"
   where connect_by_isleaf = 1
   connect by "ID" = prior "ID"
   and    "START" = prior "END" + 1
   )
group by "ID", "END"
order by "ID", "END"
;
142NAME IS NULL:2010/06/14(月) 20:47:22 ID:???
今気づいたけどサブクエリにしなくてもいいんだな
select "ID",
    min(connect_by_root "START"),
    "END"
from "TableName"
where connect_by_isleaf = 1
connect by "ID" = prior "ID"
and    "START" = prior "END" + 1
group by "ID", "END"
order by "ID", "END"
;
143NAME IS NULL:2010/06/14(月) 21:39:38 ID:???
○○idという列が主キーになる時が多いですが、
それ以外が主キーになる時ってあんまりないんですか?
144NAME IS NULL:2010/06/14(月) 22:18:35 ID:???
設計によりますが、
どの列も主キーになりうります。
145NAME IS NULL:2010/06/14(月) 22:23:46 ID:???
どっちかっつーと○○idという列は主キーにするために作ることが多いと思う
別にそうでなければならないわけではない
146143:2010/06/14(月) 22:37:51 ID:???
>>144-145
thx
147139:2010/06/14(月) 22:40:28 ID:???
>>142
thx
葉から根を参照するようにすればいいのか・・・。
根を基準に見ていたから気づかなかったよ
148NAME IS NULL:2010/06/15(火) 05:53:35 ID:???
すみません
SELECT user_id FROM member_m WHERE user_id = {$user_id} AND password = {$password}"

これはphpのソースなんですが
{ } は多分SQL側に渡されると思うのですが、なにか意味があるのでしょうか?
149NAME IS NULL:2010/06/15(火) 06:22:12 ID:???
>>148
すれ違いだか、{ } はSQL側へは渡らない。
$a="hoge";echo "a={$a}"; ってして見りゃわかる。
意味とか、その例だけだとプログラマ側の癖みたいなものだが、
詳しくはPHP関係のスレでどーぞ。
150NAME IS NULL:2010/06/15(火) 06:50:28 ID:???
>>149
ありがとうこざいます
perlだと ${a} だったので先入観がありましたorz

スレ違い申し訳ありませんでした
151NAME IS NULL:2010/06/16(水) 05:38:06 ID:???
2つの列の値の重複を調べたいのですが
aとbは重複なしの値にしたいのです。

SELECT COUNT(a, b) FROM test WHERE a = '入力データ1' OR b = '入力データ2'
これで結果が 0行 ならデータを追加としたいのです。

aかb片方だけだと上手くいくのですがエラーがでます。
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' b

どうしたらいいのでしょうか

152NAME IS NULL:2010/06/16(水) 06:24:09 ID:???
>>151
結果が0行か否かなら、
SELECT EXISTS(SELECT * test WHERE a = '入力データ1' OR b = '入力データ2');
でboolが返るが、行数が欲しいのなら、
SELECT COUNT(1) FROM test WHERE a = '入力データ1' OR b = '入力データ2';
でいける。COUNT(1)の他にSUM(1)でもいいが。
153151:2010/06/16(水) 16:05:45 ID:???
>>152
ありがとうこざいます!
154NAME IS NULL:2010/06/18(金) 03:57:32 ID:???
質問です。
Oracle10gです。

部門の親子関係を示す以下のようなテーブルがある。

親部門ID 子部門ID 子部門の区分
1       2      0
1       3      1
3       4      0
3       5      1
5       6      0
7       8      0
7       9      1
9       10     0

ある親部門IDを指定し、その部門以下の階層に含まれる部門のうち区分が0となっているものを取得したい。
上の例だと部門ID=1と指定した場合2,4,6を取得したい。

よろしくお願いします。
155NAME IS NULL:2010/06/18(金) 06:12:15 ID:???
>>154
Oracle10gって再起クエリ使えたっけ?
カラム名やテーブル名を以下のように変えて書くけど、
親部門ID=p_id
子部門ID=c_id
子部門区分=c_sec
部門テーブル sector

WITH RECURSIVE Temp(p_id,c_id,c_sec) AS
(SELECT T1.* FROM sector AS T1 WHERE p_id=1
UNION ALL
SELECT T2.* FROM sector AS T2 WHERE T2.p_id = T1.c_id)
SELECT * FROM Temp WHERE c_sec=0;
156NAME IS NULL:2010/06/18(金) 07:14:01 ID:???
Oracleの場合はCONNECT BY
>>142を参考に、あと>>154の場合はSTART WITHも使う
詳しくは
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/queries.html#1719
157NAME IS NULL:2010/06/18(金) 07:44:54 ID:???
階層クエリって結構使うのかね。
練習になるからもっとこういう問題出して欲しいわw
158NAME IS NULL:2010/06/18(金) 08:06:43 ID:???
再起クエリってなんだよ > 俺 < 再帰クエリだった

>>157
部品展開とか、メールや掲示板のツリーとかぐらいしか思い浮かばん。
以前、隣接リストで入れ子集合やってみたけど、スッキリしなくてめんどいだけだった。
階層構造って、入力する人がどこに入れりゃいいのか迷うのよね。
最近ならタグ(ラベル)的扱いの方が、楽なのかも。
159NAME IS NULL:2010/06/18(金) 16:33:02 ID:DdYe8KWn
再帰SQLは、oracleの11gのR2から使えるそうだ。
11gのR1までは、階層問い合わせを使うしかない!!!

select 子部門ID
from テーブル
where 子部門の区分 = 0
start with 親部門ID= ある親部門ID
connect by prior 子部門ID= 親部門ID


ところで、これは参考になったお。
http://codezine.jp/article/detail/4847
160NAME IS NULL:2010/06/18(金) 18:31:37 ID:???
ID | mail
----------------------
というテーブルがあったとして複数のIDのmailを取得するには

where ID = '***' OR ID = '***'
と OR で繋げていくのでしょうか?
161NAME IS NULL:2010/06/18(金) 19:28:02 ID:???
その複数のIDはどこで定義されているんだ?

とりあえず ID in ('***','***', ... )とか
ID in (select ID from 条件のテーブル) みたいなやり方もあるぞ
162NAME IS NULL:2010/06/18(金) 19:46:55 ID:???
ありがとうこざいました!
IDは別テーブルです
163NAME IS NULL:2010/06/19(土) 01:03:48 ID:mva1Tcfi

Oracleなんですが下記のSQLが通りません。
問題は★部分で、ここのNVLを外すか、内部結合にすれば
通ります。

しかしNVLで変換は必要です。また外部結合にもできない。
どういうSQLを組み立てたら良いのでしょうか?

SELECT main.*, sub.*
FROM maintbl main
, subtbl sub
WHERE main.depertment = 'hogehoge'
 AND sub.fkey (+) = main.key
 AND NVL(sub.date,'20990101') (+) <= '20100510'(★)

164NAME IS NULL:2010/06/19(土) 07:57:26 ID:???
NVL(sub.date(+),'20990101') <= '20100510' じゃないのか?
165NAME IS NULL:2010/06/19(土) 08:12:41 ID:???
>>164
NVL部分にも(+)書かないと内部結合になっちゃうようです。
166NAME IS NULL:2010/06/19(土) 08:46:00 ID:???
>>163
>, subtbl sub

ここの部分を

, (SELECT fkey, NVL(sub.date,'20990101') AS date FROM subtbl) sub
にすりゃ通るだろうけど。
167NAME IS NULL:2010/06/19(土) 09:10:02 ID:mva1Tcfi
>>166
こんな感じですかね。

SELECT main.*, sub.*
FROM maintbl main
, (SELECT fkey,NVL(date,'20990101') as date FROM subtbl) sub
WHERE main.depertment = 'hogehoge'
 AND sub.fkey (+) = main.key
 AND sub.date (+) <= '20100510'

条件付けをしないでサブクエリを書いてしまっても、
速度的には問題ないのですかね?

今回の場合、fkeyにはindexが貼ってあるのですが、
サブクエリにしたテーブルをさらに結合した場合、
indexは有効なんでしょうか?


168NAME IS NULL:2010/06/19(土) 09:10:37 ID:???
内部結合になるって言う意味がわからん
どういうデータでどういう結果が欲しいんだ?
169NAME IS NULL:2010/06/19(土) 09:15:47 ID:???
なんで>>164じゃダメなのかワカンネ

それかもっと素直に
 sub.fkeyが存在しない場合は結果に含める
 sub.fkeyが存在してdateがnullの場合は含めない
 sub.fkeyが存在してdateがnullでない場合は'20100510'以下
ってことだとして最後の行を
 and (sub.fkey is null or sub.date <= '20100510')
にするとか
170NAME IS NULL:2010/06/19(土) 09:28:56 ID:???
パフォーマンス的なものは今どきのDBMSなら意外とうまくやってくれることが多いけど
実際にプラン見てみないと分からんね
171NAME IS NULL:2010/06/19(土) 09:29:58 ID:???
>>167
テーブル側のカラムに関数をかましてる時点で(NVL(date,'20990101')のこと)
subtblの全レコードを舐めるのが確定なので、FROM句サブクエリ、WHERE句サブクエリとも速度には期待できない。
172NAME IS NULL:2010/06/19(土) 09:48:06 ID:???
>>164
すいません、詳細を見落としていました。

NVL(sub.date(+), ・・・
なんですね。
こんな書き方もあるんですか。

NVL(sub.date,'20990101') (+) <= '20100510'
これは試して内部結合になっちゃったのは確認したのですが
>>164さんのやり方はまだ試してないです。

>>171
sub.fkeyはPKになっていて、これだけで
一意に定まるんですよ。あとは、そのレコードが有効か
無効かを日付で判断したいだけです。
それでも全件検索になるんですかね?
173NAME IS NULL:2010/06/19(土) 10:28:42 ID:???
それじゃ AND sub.fkey (+) = main.key の(+)はどういう意味なんだよw
174NAME IS NULL:2010/06/19(土) 10:47:26 ID:???
だから、どういうデータでどういう結果が欲しいんだ
ちょっと例だして書いてみろよ
内部結合になるとか意味不明だぞ
175NAME IS NULL:2010/06/19(土) 10:59:20 ID:???
てか結合条件と検索条件の区別がついてない?
Oracle記法じゃなくてOUTER JOIN ・・ ON ・・ WHEREでやりたい事を書き直してみ。
176NAME IS NULL:2010/06/19(土) 11:14:32 ID:???
まあそんな感じか
外部結合した上でその行を全部はじく検索条件書いてその結果だけみて
内部結合になってると言ってると予想

そもそも
NULL <= '20100510' は成立しないし
'20990101'<= '20100510' も成立しないんだが
NVL(sub.date,'20990101')<= '20100510'な理由もわからん
sub.date <= '20100510' でいいんじゃないか
177NAME IS NULL:2010/06/20(日) 17:47:01 ID:Pj6iNEOz
質問させてください。

・DBMS名とバージョン
MySQL 5.0.27-1

・テーブルデータ
DATE    | DATA
------------+----------
2010-06-01 | aaa
2010-06-02 | bbb
2010-06-03 | ccc
2010-06-04 | ddd
2010-06-05 | eee
2010-06-06 | fff
2010-06-07 | ggg

・欲しい結果
最新3件を昇順で。
DATE    | DATA
------------+----------
2010-06-05 | eee
2010-06-06 | fff
2010-06-07 | ggg

・説明
select DATE, DATA from TABLE order by DATE desc limit 3;
とすれば、最新3件を降順で取得できますが、
できれば降順でなく昇順で最新3件を取得したいです。
178NAME IS NULL:2010/06/20(日) 18:01:55 ID:???
も一度ソートすればいいだけじゃないの?
179NAME IS NULL:2010/06/20(日) 18:22:42 ID:???
MySQLで未検証だけど、SELECT * FROM (そのSQL) ORDER BY date とか
180NAME IS NULL:2010/06/20(日) 19:33:10 ID:???
select * from
(select DATE, DATA from TABLE order by DATE desc limit 3) t
order by DATE;
181177:2010/06/20(日) 23:41:17 ID:Pj6iNEOz
>>178-180
ありがとうございます。select結果をselectし直す方法でうまくいきました!ありがとうございます
182NAME IS NULL:2010/06/21(月) 01:29:44 ID:???
SELECTやFROMのようなキーワードを大文字、
テーブル名やカラム名を小文字
で書くように学んだけど、
>>180みたいにその逆の書き方をするのは何か意味があるの?
183NAME IS NULL:2010/06/21(月) 01:33:32 ID:???
大文字より小文字のほうが見やすい
ならたくさんある方を小文字にすれば、見やすいってことだ
184NAME IS NULL:2010/06/21(月) 03:44:13 ID:???
大文字はうるさいよ
185NAME IS NULL:2010/06/21(月) 06:31:06 ID:???
>>182
カラム名を大文字表記で定義してるからでしょ。
186NAME IS NULL:2010/06/21(月) 06:33:23 ID:???
>>183-185
オッケーわかった、ありがとう
187NAME IS NULL:2010/06/21(月) 06:41:48 ID:???
DATEとか予約語だしなw
188NAME IS NULL:2010/06/24(木) 01:30:52 ID:???
学校でSQLの授業とっててこんな問題が出たけど理解不能だったんで助けてくだしあ。
どなたかお願い致します。

全くもって意味が分からなかった\(^o^)/
コンピュータの意味処理ってどういう意味なんですかねぇ・・・

>XMLについて、その概要をコンピュータの意味処理という視点から書いて下さい。
>また、実際にどのような分野で使われていますか?
>具体例を一つあげて説明してください。

XMLスレで聞こうと思ったら最終書き込みが2009年とか見てスッ、って帰ってきた。
189NAME IS NULL:2010/06/24(木) 01:48:24 ID:???
意味は意味解析や構文解析でぐぐれ。
あとSQL質疑応答とXMLはカスリもしてないw
というかXMLとデータベースが全く関係ないのでこんな過疎板の過疎スレでなくてプログラミング板にでもいくといい。w
190NAME IS NULL:2010/06/24(木) 02:32:07 ID:???
意味処理って単語は初めて聞いたな。
まあスレチ
191sage:2010/06/24(木) 07:25:52 ID:S+fksH8m
>>189
あとSQL質疑応答とXMLはカスリもしてないw <- 真.
というかXMLとデータベースが全く関係ないので <- 偽.
192NAME IS NULL:2010/06/24(木) 07:30:29 ID:???
いや、関係ないだろ。
193NAME IS NULL:2010/06/24(木) 07:41:43 ID:???
>>191
データ保持の実装がXMLだろうが実ファイルだろうが関係なかろう。
RDBのスレでOSのファイルシステムについての質問はありなのか?
194NAME IS NULL:2010/06/24(木) 08:11:23 ID:???
質問自体はスレチつうより板違いだろうけど、
「XMLとデータベースが全く関係ない」と言い切るのはおかしいだろ。

>>193
データベースに適したFSは? とか、データベース専用FSについて
なんてのはありなんじゃね。
195NAME IS NULL:2010/06/24(木) 08:12:02 ID:???
EsTerra
196NAME IS NULL:2010/06/24(木) 22:49:04 ID:???
ほとんど関係ない。でいいよ。スレ違いだから、この話題はそろそろ終了な。
197NAME IS NULL:2010/06/25(金) 22:07:41 ID:???
・DBMS名とバージョン
VB2008でOLEDBを使ってOracle10gに繋いでます。

・テーブルデータ
どの部品にはどの部品が使われてて〜といううような、
部品の構成を表す、下記のような親子関係と必要数のテーブルがあります
-------------
OYA KO KAZU
-------------
A   B  1
A   G  1
B   C  1
B   F  1
C   D  1
C   E  1
G   C  2
G   H  1


ツリーで表記すると、
A
├B
│├C
││├D
││└E
│└F
└G
 ├C
 │├D
 │└E
 └H

Aという部品は、BとGの部品で出来ている。
Bという部品はCとFの部品で出来ている〜という感じです。

・欲しい結果
これを階層のレベルと、それぞれの子の合計数を出したい。
ここでいうBの下のCは1なので、DもEも1だが、
Gの下のCは2なので、DもEもx2されて2になる
----------------
LV KO  GOUKEI
----------------
1  B   1
2  C   1
3  D   1
3  E   1
2  F   1
1  G   1
2  C   2
3  D   2
3  E   2
2  H   1


今は、プログラム側で親から子を見る所をサブルーチンで組み、回帰処理でループさせてるので、
リクエストが多く、あまりにも酷いかなぁ。。。と。
色々サンプルを見てconect byとかよく似てるんで、何かやり方があるのかな?と思い質問してみました。
198NAME IS NULL:2010/06/25(金) 22:31:19 ID:???
答えじゃないけど、

>回帰処理でループさせてるので

「再帰」な。
199NAME IS NULL:2010/06/25(金) 22:34:28 ID:???
これでGOUKEIの結果をアプリ側で演算する・・・とか?(格好悪っ)

select level as LV
,    KO
,    sys_connect_by_path(KAZU, '*') as GOUKEI
from  TableName
start with OYA = 'A'
connect by prior KO = OYA
;
200NAME IS NULL:2010/06/25(金) 23:06:47 ID:???
JDK1.4とオラクル9iです

TESTのテーブルから下の結果を得たいのですが可能でしょうか?

1カラム目はIDで
2カラム目は開始日で
3カラム目は終了日です


テーブルTEST
a,20110403,20110611
b,20110505,20110721

結果
a,201104
a,201105
a,201106
b,201105
b,201106
b,201107
201NAME IS NULL:2010/06/25(金) 23:09:59 ID:???
不可能とは言いませんがアプリ側でやったほうがいいです
202200:2010/06/26(土) 00:56:49 ID:???
>>201
レスありがとうございます。

方法を教えてもらいたいです。

203NAME IS NULL:2010/06/26(土) 02:13:51 ID:???
SQLはデータを生成するためのものではありません
やっぱりこれFAQに入れようぜ
204NAME IS NULL:2010/06/26(土) 08:18:42 ID:???
>>200
Javaでしょ?
20110403、20110611を日付変換して
FOR 201104 TO 201106 EACH 1 MONTH
とかでいいんじゃない
205NAME IS NULL:2010/06/26(土) 08:45:51 ID:???
>>202
select distinct ID
,        to_char(add_months(to_date(substr(開始日, 1, 6), 'YYYYMM'), level - 1), 'YYYYMM')
from TEST
connect by add_months(to_date(substr(開始日, 1, 6), 'YYYYMM'), level - 1) <= to_date(substr(終了日, 1, 6), 'YYYYMM')
order by 1,2
;
テーブルの規模によっては非常に残念なパフォーマンスになると思う
206NAME IS NULL:2010/06/26(土) 14:44:02 ID:???
>>53,>>55あたりを参考にFAQ書いてみた

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

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

   20100601
   20100602
    ・
    ・
    ・
   20100630

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

どうしてもやりたければ以下のような方法もなくはないですが、
これを見て意味が分からない人は使わないほうが良いでしょう。
(意味が分かる人はなおさら使いません。)

select to_char(to_date('201006', 'YYYYMM') + NUM, 'YYYYMMDD')
from (select row_number() over (order by 1) - 1 as NUM from all_catalog)
where to_date('201006', 'YYYYMM') + NUM < add_months(to_date('201006', 'YYYYMM'), 1)
;

select to_char(to_date('201006', 'YYYYMM') + level - 1, 'YYYYMMDD')
from dual
connect by to_date('201006', 'YYYYMM') + level - 1 < add_months(to_date('201006', 'YYYYMM'), 1)
;

※後者はOracle限定です。他のDBMSの場合はconnect byの代わりに
 再帰問合せを使えばできるかもしれません。
207NAME IS NULL:2010/06/26(土) 15:12:13 ID:???
初心者なんですけど、エラーを調べるコマンドってありますか?
208NAME IS NULL:2010/06/26(土) 15:23:24 ID:???
マニュアル見ればいいじゃない
209NAME IS NULL:2010/06/26(土) 15:27:10 ID:???
>>206
後半のどうしてもってとこのSQLいらなくね?

どうしてもやりたいなら再帰SQLでできなくもないです
ぐらいでいいと思う

>後者はOracle限定
前者もall_catalogが存在して必要な行数以上の行をもってないと無理
実質ORACLE専用だろ
ダミーテーブルと結合させるのはSQLの手段としては間違ってると思う
210NAME IS NULL:2010/06/26(土) 16:05:34 ID:???
いらんよね。逆に、>>206の通りにやったけどできません、とか
MySQLで同じことするにはどうすればいいですか?なんて
質問が出そう。
211NAME IS NULL:2010/06/26(土) 16:07:34 ID:???
ちょっと修正した

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

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

   20100601
   20100602
    ・
    ・
    ・
   20100630

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

どうしてもやりたければ以下のような方法もなくはないですが、
こんなSQLを書いているとセンスを疑われます。
やめておくことを強くお奨めします。
(PostgreSQLのgenerate_series()関数なら辛うじてセーフかもしれませんが
 微妙なところでしょう。)

select to_char(to_date('201006', 'YYYYMM') + NUM, 'YYYYMMDD')
from (select row_number() over (order by 1) - 1 as NUM from all_catalog)
where to_date('201006', 'YYYYMM') + NUM < add_months(to_date('201006', 'YYYYMM'), 1)
;

select to_char(to_date('201006', 'YYYYMM') + level - 1, 'YYYYMMDD')
from dual
connect by to_date('201006', 'YYYYMM') + level - 1 < add_months(to_date('201006', 'YYYYMM'), 1)
;

※いずれの例もOracleの場合です。
 他のDBMSの場合でもどのみちお奨めしません。
212NAME IS NULL:2010/06/26(土) 16:39:34 ID:???
俺も別に要らんと思うが、WITH RECURSIVEなら! と思ってみたがLIMIT付けないと無限ループする。
LIMITクエリって相変わらず処理系依存? 以下、PostgreSQL用

WITH RECURSIVE Temp(datedata) AS
(SELECT to_timestamp('201006','YYYYMM')
UNION ALL
SELECT datedata+interval'1 day' FROM Temp)
SELECT to_char(datedata,'YYYYMMDD') FROM Temp
LIMIT EXTRACT(day FROM to_timestamp('201006','YYYYMM')+interval'1 month -1 day');

>>211にも書かれてあるが、PostgreSQLならgenerate_seriesを使った方が楽。
ま、こんなのも出来るって参考程度に。
213NAME IS NULL:2010/06/26(土) 17:20:50 ID:???
LIMITじゃなくて普通にWHEREじゃダメなのか?
214212:2010/06/26(土) 18:05:55 ID:???
>>213
可能だった。

WITH RECURSIVE Temp(datedata) AS
(SELECT to_timestamp('201006','YYYYMM')
UNION ALL
SELECT datedata+interval'1 day' FROM Temp WHERE datedata <to_timestamp('201006','YYYYMM')+interval'1 month -1 day')
SELECT to_char(datedata,'YYYYMMDD') FROM Temp

そうか、最後の行にWHERE句ではなくて、再帰される分のところに入れりゃいいのか。

>>200は9iだそうなのでWITH RECURSIVEがつかるのかな、
でもその質問でWITH RECURSIVEをつかった解はまだわからない。
215212:2010/06/26(土) 18:17:40 ID:???
でけた。

WITH RECURSIVE Temp(mark,startdate,enddate) AS
(SELECT mark,startdate,enddate FROM testtable
UNION ALL
SELECT mark,(startdate+interval'1 month')::date,enddate FROM Temp
WHERE date_trunc('month',startdate)<date_trunc('month',enddate))
SELECT mark,to_char(startdate,'YYYYMM') FROM Temp ORDER BY mark;

date_truncってひょっとしてPostgreSQL依存な関数をつかっているが、
Oracleにも似たような関数あるっしょ。
216212:2010/06/26(土) 18:24:38 ID:???
> (startdate+interval'1 month')::date
PostgreSQL表記がここにも残っていた。
DATE型+INTERVAL型=TIMESTAMP型になるので、DATE型にキャストしている。
startdateがTIMESTAMP型ならキャスト不要。
他なら、適当にキャスト演算子or関数つかってくれ。

連投スマソ
217NAME IS NULL:2010/06/26(土) 18:31:31 ID:???
Oracleでwithを使った再帰問合せが書けるのは11g(R2?)からかな
recursiveキーワードはつけない(というかキーワードじゃない)
日付の演算も違うけど面倒臭いんで書かない
218197:2010/06/26(土) 22:42:12 ID:???
>>198
再帰デスね、、寝ぼけてました。。

>>199
ありがとうございます。
参考にさせてもらいますー。
219212:2010/06/26(土) 23:36:59 ID:???
>>217
わりぃ、上で出ていたけど、アルファベット表記のところしか覚えてなかった。
g->h->i でiの方が新しいと思ったが、9iと11g-R2じゃ11g-R2の方が新しいんだね。

ところで、WITH RECURSIVEが使えるOracleで比較的簡単そうな以下のようなSQLでもダメなの?
WITH RECURSIVE t(n) AS (
VALUES (1)
UNION ALL
SELECT n+1 FROM t WHERE n < 100)
SELECT sum(n) FROM t;
--PostgreSQLのマニュアルより
220NAME IS NULL:2010/06/26(土) 23:56:40 ID:???
>>219
ダメなの?って11gなら通るよ。
ただしrecursiveキーワードは要らないのと
valuesを使ったTable Value Constructorは使えない。

WITH t(n) AS (
SELECT 1 FROM DUAL
UNION ALL
SELECT n+1 FROM t WHERE n < 100)
SELECT sum(n) FROM t;
221212:2010/06/27(日) 00:14:52 ID:???
>>220
サンクス。
なるほど、そういうことなのね。
222211:2010/06/27(日) 21:29:59 ID:???
さらに修正した
(ダミーテーブルを使うのはいくらなんでもアレなのでボツ、
 代わりに再帰問合せにした)

(問)
年月(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)
;

select to_char(to_date('201006', 'YYYYMM') + level - 1, 'YYYYMMDD')
from dual
connect by to_date('201006', 'YYYYMM') + level - 1 < add_months(to_date('201006', 'YYYYMM'), 1)
;

※いずれの例もOracleの場合です。(前者は11gR2以降)
※再帰問合せをサポートするDBMSなら前者を適当に改変すれば動きますが
 どのみちお奨めしません。
223NAME IS NULL:2010/06/27(日) 21:51:11 ID:jCqDQodk
これでいいじゃん

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

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

   20100601
   20100602
    ・
    ・
    ・
   20100630
224NAME IS NULL:2010/06/27(日) 21:53:35 ID:jCqDQodk
コピペ失敗した

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

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

   20100601
   20100602
    ・
    ・
    ・
   20100630

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

どうしてもやりたければ、再帰問合せ/階層問合せを
利用すれば可能ですが、本来の使い方ではありません。
やめておいたほうがよいでしょう。
(PostgreSQLのgenerate_series()関数なら辛うじてセーフかもしれませんが
 賛否の分かれるところでしょう。)
225222:2010/06/27(日) 22:13:38 ID:???
ちなみにSQLサンプルを残した理由は
・可能であるものをわざわざ隠す必要もないので
・「再帰問合せを使って書くってどうやるんですか?」と聞かれるのが一番ウザいので
・FAQに再帰問合せのサンプルがないので
 (そしてわざわざ再帰問合せのFAQを捏造するのもアレなので)
・せっかく書いたので ←実は最大の理由
226NAME IS NULL:2010/06/27(日) 22:25:17 ID:???
withはともかく、connect byみたいな特定のDBMSに強く依存するものをテンプレに乗せるのはどうなんだ
227222:2010/06/27(日) 22:40:11 ID:???
確かにそれは一理あるね
connect byのほうはなくてもいいかも

そういう意味では日付演算もDBMSにかなり依存するんで
問いの選び方としてイマイチっちゃイマイチなんだけど
実際に多い問いなんでこれはしょうがないな
228NAME IS NULL:2010/06/27(日) 23:25:07 ID:???
俺的にはテンプレならありなんだけどな。> 処理系依存
>>4も処理系によってはもっと簡素に書けるわけだし、ひとつのDBMSだけじゃなくて
汎用、Oracle、MS-SQL、PostgreSQL、MySQL.... って並んでると便利かも。
ただ、テンプレが太ってしまうので、どこかWikiなんぞに書ければいいが。
229NAME IS NULL:2010/06/29(火) 02:42:30 ID:???
質問です。
今から11gのbronzeやりはじめようこてこての初心者なんですが
11gインスコしてもSQL plusが起動しません。
実行したら一瞬SQL plusの画面がふわっと出てすぐ消えちゃいます。

補足
・インストールは警告無視してました。
・OSはVistaのビジネス(対応してる)
っス。よろしくおながいするッス
230NAME IS NULL:2010/06/29(火) 06:06:33 ID:???
>>229
スレ違い
231NAME IS NULL:2010/06/29(火) 07:20:08 ID:gwfYytti
tbl1にnum1,num2,id1,id2,id3
tbl2にid,name,ssというフィールドがあるとして
SELECT name, num1, num2, id1, id2, id3, time FROM tbl1, tbl2
WHERE num1 = 1
AND id1 = ( SELECT id FROM tbl2 WHERE ss = "monga")
上記のようなSQLを
特定のフィールドが他の行と重複してたら抜かすというのはどうやればいいでしょうか?
単にdistinctつけるだけだとどれかひとつでも重複していなかったら抽出されますよね。
id1,id2,id3が他のレコードのid1,id2,id3と重複してたら
検索結果に入れないみたいな感じにしたいのですが。
MYSQLです。
232NAME IS NULL:2010/06/29(火) 07:27:15 ID:???
>>231
まずtbl1とtbl2をクロス結合してるところで要件ミスか実装ミスの可能性大。

>>229
コマンドプロンプトを起動してからsqlplusを叩いてエラーメッセージを見れ。
あと仮想マシンでいいからLinuxいれろ。
233NAME IS NULL:2010/06/29(火) 13:34:11 ID:gwfYytti
>>232
レスありがとうございます。
えと、AND id1 = ( SELECT id FROM tbl2 WHERE ss = "monga")の部分で内部結合のつもりなんですが
tbl1.id1 = tbl2.id
もつけないといけないんでしょうか。
あと、要件ミス、実装ミスってことは、そういう重複の取り除き方はありえないってことでしょうか?
234NAME IS NULL:2010/06/29(火) 13:46:03 ID:gwfYytti
すいませんなんか難しく考えていましたがGROUP BYでいいんですね・・・
235NAME IS NULL:2010/06/29(火) 14:22:39 ID:???
できたようでよかった。
その質問をするときは重複判定しないカラムの扱いも書いとかないと困るよ。
236NAME IS NULL:2010/06/29(火) 22:49:22 ID:???
カレンダー作るのってアンチ多いのね。
カレンダーテーブルを作るとしても大して変わらないだろ。
237NAME IS NULL:2010/06/30(水) 14:58:43 ID:vqtVeRmY
すいません、初心者なのですが教えてください。
sqlplusにて
SQL>!ls
と打つと「ls」コマンドが実行されると思うのですが、
自宅のPCに、書籍の付録のオラクルをインストールして実行しても「SP2-0042:不明なコマンドです」
と言われてしまいます。
「!」を認識させるにはどのようにすれば良いのでしょうか?
238NAME IS NULL:2010/06/30(水) 15:50:59 ID:???
>>237
スレ違いだが。

! は、Unix(Linux)の場合のみ使える。
Windowsの場合は、$
どちらも、hostコマンドの省略形。
239NAME IS NULL:2010/06/30(水) 16:10:23 ID:???
おまけにwinだったら、ふつうはlsは入ってないわな。
240NAME IS NULL:2010/06/30(水) 16:44:43 ID:???
>>238
ありがとうございました。出来ました。
241NAME IS NULL:2010/06/30(水) 17:02:04 ID:???
Powershell経由で起動してたら、lsあるな。
242NAME IS NULL:2010/06/30(水) 22:08:37 ID:???
vistaからls使えた気がする
243NAME IS NULL:2010/07/04(日) 12:13:46 ID:???
すみません質問です。
Accessのクエリで

SELECT CASE pref_name
WHEN '徳島' THEN '四国'
WHEN '香川' THEN '四国'
WHEN '愛媛' THEN '四国'
WHEN '高知' THEN '四国'
WHEN '福岡' THEN '九州'
WHEN '佐賀' THEN '九州'
WHEN '長崎' THEN '九州'
ELSE 'その他' END AS district,
SUM(population)
FROM PopTbl
GROUP BY CASE pref_name
WHEN '徳島' THEN '四国'
WHEN '香川' THEN '四国'
WHEN '愛媛' THEN '四国'
WHEN '高知' THEN '四国'
WHEN '福岡' THEN '九州'
WHEN '佐賀' THEN '九州'
WHEN '長崎' THEN '九州'
ELSE 'その他' END;
というSQLを実行したいのですが、構文エラーとなってしまいます。
SQLの達人という参考書からそのままコピッただけのなので、
普通に考えてエラーが出るはずがないのですが、どうでしょうか??
助けてくださいお願いいたします。
244NAME IS NULL:2010/07/04(日) 12:21:24 ID:???
AccessのSQLでは、Case Whenが使えない。IIfとかで代用しろ
245NAME IS NULL:2010/07/04(日) 12:42:30 ID:???
>>244
そうなんですかぁ。。。
素早い回答どうも有り難うございました!
246NAME IS NULL:2010/07/04(日) 20:54:07 ID:???
主キーってインデックスが自動的に作成されるって書いてるけど、実際はインデックスを明示して作らない速くならない様なんだけど本当のところはどうなの?
247NAME IS NULL:2010/07/04(日) 20:58:27 ID:???
DB次第。SQL には関係ないからスレ違いだな。
248NAME IS NULL:2010/07/05(月) 22:22:34 ID:03f+1PMv
TABLE test
id | data
---+------
100 | AAA

TABLE hoge
id | value
---+------
100 | 10
100 | 20

TABLE 100
id |val1| val2
---+---+----
100 | 20 | 40
100 | 30 | 60

SELECT a.id, test.data, a.cnt + b.cnt + c.cnt
FROM
(SELECT id, SUM( aa.val1 ) cnt FROM (SELECT id, val1 FROM `100`)aa)a,
(SELECT id, SUM( bb.val2 ) cnt FROM (SELECT id, val2 FROM `100`)bb)b,
(SELECT id, SUM( value ) cnt FROM hoge WHERE id = 100)c,test
WHERE a.id = c.id AND test.id = 100

欲しい結果
id data a.cnt + b.cnt + c.cnt
----------------------------
100 AAA 180

やむなくMySQLのバージョンが5.0.77-logから5.1.22-rcに変更することになり、
5.0.77-logで動作していた上記のSQLを実行すると
#1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
と怒られてしまいます。。。
今も色々試しているのですがGROUP BYをうまく使えません。
申し訳ないのですが教えて頂けませんか><
249NAME IS NULL:2010/07/05(月) 22:27:22 ID:???
idがuniqueじゃないのって初めて見た・・・
250NAME IS NULL:2010/07/05(月) 22:36:01 ID:???
>>249
色々省略してます><
251NAME IS NULL:2010/07/05(月) 23:15:14 ID:???
>>248
test.id = hoge.id = `100`.id で連結してvalueとval1,val2を全て合計するってことでいいのかな?

SELECT test.id,test.data,T1.cnt+T2.cnt FROM test JOIN
(SELECT id,SUM(val1)+SUM(val2) AS cnt FROM `100` GROUP BY id)AS T1 ON test.id = T1.id JOIN
(SELECT id,SUM(value) AS cnt FROM hoge GROUP BY id )AS T2 ON test.id = T2.id WHERE test.id = 100;

テーブル名に`100`ってしているから、実使用とは意味が違うSQLになっているかもしれん。
252NAME IS NULL:2010/07/05(月) 23:15:45 ID:???
>(SELECT id, SUM( aa.val1 ) cnt FROM (SELECT id, val1 FROM `100`)aa)a,
                          ↑
ここの部分のサブクエリはなんか意味あるのか?
253NAME IS NULL:2010/07/06(火) 00:17:02 ID:???
どうやったらこんなテーブル構造になるのかが不思議だ
254NAME IS NULL:2010/07/06(火) 00:32:16 ID:???
>>251
ありがとうございます><
欲しい結果を得ることが出来ました!

>>252
まったくその通りですね、大切な部分を省略してしまいました。。。
実際は日付で降順ソートして上位100件の合計値が欲しかったのです。

SELECT test.id, test.date, T1.cnt + T2.cnt
FROM test JOIN
(SELECT id, SUM( VC.val1 ) + SUM( VC.val2 ) AS cnt FROM (SELECT id, val1, val2 FROM `100` ORDER BY date DESC LIMIT 100) AS VC GROUP BY id) AS T1 ON test.id = T1.id JOIN
(SELECT blog_id, SUM( value ) AS cnt FROM hoge WHERE id = 100 GROUP BY id) AS T2 ON test.id = T2.id
WHERE test.id = 100;

>>253
恥ずかしいです><
でも実際はもう少しちゃんとした構造だと・・・思いますよ!w

皆様ありがとうございました。
255NAME IS NULL:2010/07/06(火) 16:10:21 ID:wdn3FAny
同一テーブルで、自分自身を除く前回の履歴を結合したいです
SQLServer2005

設備
X

生産履歴
履歴ID 設備 製造ロット ロット枝番 状態
10 X 002 2  生産中
09 X 002 1  完了
08 X 001 1  完了

設備と生産履歴から設備稼働状況を表示
SELECT * FROM 設備
LEFT OUTER JOIN 生産履歴
ON 設備.設備=生産履歴.設備
AND 生産履歴.状態='生産中'

設備稼働状況 ※これに前回ロットを表示したい。
設備  製造ロット ロット枝番 前回ロット
X 002     2 001

製造ロット002が完了したら
設備 製造ロット ロット枝番 前回ロット
X NULL NULL 002
となる。


LEFT OUTER JOIN
SELECT MAX(製造ロット) AS MAX製造ロット
FROM 生産履歴 生産履歴前回
WHERE 製造ロット<>生産履歴.製造ロット※2
GROUP BY 設備

※2で引っかかる。
どなたか回答よろしくお願いします。
256NAME IS NULL:2010/07/06(火) 17:22:49 ID:???
>>255
「ひとつの設備に対して生産中の履歴は最大でひとつ」ということにして

SELECT *,(SELECT MAX(製造ロット) FROM 生産履歴 WHERE 設備=T1.設備 AND COALESCE(ロット<T2.ロット,TRUE) AS 前回ロット
FROM 設備 AS T1
LEFT JOIN (SELECT * FROM 生産履歴 WHERE 状態='生産中') AS T2 ON T1.設備=T2.設備;

で、いけるかな? SQL鯖で動くかどうかはしらね。
257NAME IS NULL:2010/07/07(水) 00:44:11 ID:???
>>255
別解
SELECT
E.設備,
(select MAX(製造ロット) from 生産履歴 group by 設備) AS 製造ロット
,P.ロット枝番,
(MAX(p.ロット枝番) over(partition by E.設備,P.製造ロット)) -1 AS 前回ロット番号
FROM 設備 E LEFT OUTER JOIN 生産履歴 P ON E.設備= P.設備
AND P.状態='生産中

ただしMSSQL2008で。
2005でover句が使えるかは知らん。
258NAME IS NULL:2010/07/07(水) 04:02:32 ID:???
>>255
前回ロットの定義があいまいだが
生産中でない製造ロットの最大値でいいのか?
それなら
SELECT *,
(SELECT MAX(製造ロット) from 生産履歴 where 設備=T.設備 and 製造ロット<>T.製造ロット) as 前回ロット
 FROM 設備
LEFT OUTER JOIN 生産履歴 T
ON 設備.設備=T.設備
AND T.状態='生産中'
でいいんじゃね?
前回ロットは履歴IDを見てとか言うなら2行目を適当に
259259:2010/07/07(水) 04:14:54 ID:???
ああ、違う
SELECT *,
(SELECT MAX(製造ロット) from 生産履歴 where 設備=S.設備 and 状態<>'生産中') as 前回ロット
 FROM 設備 S
LEFT OUTER JOIN 生産履歴 T
ON S.設備=T.設備
AND T.状態='生産中'
こっちで
260259:2010/07/07(水) 04:21:15 ID:???
>>259の名前は258で...
TV見ながらやるとミスだらけだなorz
261NAME IS NULL:2010/07/07(水) 06:48:31 ID:???
>>259
それは枝番違いが引っかかるから明確にNG。

俺も考えたけど>>256で正解と思う。
これの面倒なのは最新が生産中の時と完了の時とで前回ロットの取り方が違うことだよな
・・COALESCEでの回避は、こんなとこにロジック埋めこんでいいのか悩む。
262NAME IS NULL:2010/07/07(水) 07:22:50 ID:???
IF文で数値以外っていう条件にしたいんだけど、どう指定するのが良いの?
263NAME IS NULL:2010/07/07(水) 09:19:58 ID:???
IF文って?w
264NAME IS NULL:2010/07/07(水) 15:48:25 ID:???
それは数字のみで構成された文字列かどうかの判断をしたいということ?

>>263
IF文知らないの?スレ違い感は否めないけど。
265NAME IS NULL:2010/07/07(水) 20:40:02 ID:???
>>261
自演?動かないだろこれ。
266263:2010/07/07(水) 21:03:04 ID:???
あースマンPL/SQLってここ駄目なの?

聞きたかったのは、たとえばだけどselectで取ってきたものを数値か文字列かで
結果を分岐させたいんだけど、条件をどうすれば数値か文字列か判断できるのか
わからんかったんだわ。
267NAME IS NULL:2010/07/07(水) 21:17:20 ID:???
>>264
俺は263じゃないが、ここSQLスレだしな
俺はSQLのIF文はしらない

>>265
ためして無いけど、COALESCE使えて真偽値返すDBなら動くような気はする
トリッキーだけどよく考えたコードだと思う
と思って良く見たら、ASの前に閉じかっこが1個ぬけてるな

まあ、なんにせよ、JOINしてるテーブルに別名つけて、セレクトリストに
カッコつきで単一行返す相関クエリ書けばできるんじゃないかと
268NAME IS NULL:2010/07/07(水) 21:47:52 ID:???
COALESCE(ロット<T2.ロット,TRUE) のとこを
ロット<COALESCE(T2.ロット,'DUMMY') とかすりゃどこでも動く

カッコが足りないから動かない(キリッ じゃ勉強不足だぞ
269256:2010/07/07(水) 22:11:31 ID:???
ほんとだ、括弧が足りない...orz
COALESCEもCOALESCE(製造ロット<T2.製造ロット,TRUE)だったな。

>>267
ここのスレにいると、結構トリッキーなSQLでないと解けない場合が多い気がする。
COALESCEをこんな使い方したのも初めてだしw
頭の体操ってことで、結構好きなんだけどね。

>>268
ダミー文字列とか99999みたいな数値を使うのが嫌でCOALESCE(ロット<T2.ロット,TRUE)を思いついたが、
CASE文とかDB依存関数なんてのもありってことで。
270NAME IS NULL:2010/07/07(水) 23:05:31 ID:???
SQLServerなら>>268のいう
ロット < COALESCE(T2.ロット,'DUMMY')が正解。TRUEなんてかけるの?
271256:2010/07/08(木) 00:05:22 ID:???
少なくともPostgreSQLなら書ける。
しかし、後ろのTRUEで引っかかるのか?
手前の条件の方がダメなのかと思ってたわ。
あえて括弧でくくって、COALESCE((ロット<T2.ロット),TRUE)でも無理なのかな?
あとは、CASE文を試してみるとか、
CASE WHEN T2.ロット IS NULL THEN TRUE WHEN ロット<T2.ロット THEN TRUE ELSE FALSE END
272NAME IS NULL:2010/07/08(木) 02:39:46 ID:???
>>266
正確に書かないからだよ
PL/SQLだってことすら書いてないからな
DBMSはORACLEで
selectで取ってきたものってのが
VARCHAR2型であったとして(仮定が多いな)

if replace(translate(data,'1234567890','0000000000'),'0') is null then
数値の処理
else
文字の処理
end if;

もっとスマートな方法があるかもしれんが
こんなところでいかが?
273NAME IS NULL:2010/07/08(木) 10:41:53 ID:???
>>270-271
それが動く前提は、>>267で言う真偽値返すってとこだな
PostgreSQLは論理値データ型ってのがある。TRUEはこの型として判定されてるはず

>>266,272
オラクルでPL/SQLなら、TO_NUMBERしてエラー出るかどうか見ればいいんじゃね
まあ、PL/SQLはオラクル固有なんで、オラクル関係のスレで聞けってことかと
274NAME IS NULL:2010/07/09(金) 00:54:55 ID:BIBrIfiz
・DBMS名とバージョン
postgres sql

・テーブルデータ
2010/06/10,20:30
と格納されている、varchar型列

・欲しい結果
[2010/06/10],20:30
とUPDATEするバッチを作成する。

・説明
上記処理を実行するバッチ処理をフルスクラッチで作成します。
UPDATE文の書き方は判るのですが、どういう設計にしようか迷っています。

自分が最速で実装するなら、.net使って書くのですが、いかんせん仕事でして
今後の保守性を考えるとExcelマクロでSQLファイルを生成してデータバッチを
出力するようにした方がいいのでしょうか?

有識者に聞けということなんでしょうけど、いかんせん一人だけの仕事でして
実装方法で迷っています。
275NAME IS NULL:2010/07/09(金) 01:19:15 ID:???
>>274
スレ違い。PostgreSQLスレで聞いても違うっぽい気がする。
保守性なんて、運用する会社や担当者のレベルで考え方違うだろうし、
そもそもなんで、時刻をvarcher型で入れてるの? って話になる。
素直にtimestamp型にして取り出すとき摘便に書式を変えればいい。

ちなみに、挙げられたデータと欲しい結果だけ見れば、UPDATE一文で済んで不変。
そこに仕事とか、保守性云々がどう絡むのか、うまくつかめません。
276NAME IS NULL:2010/07/09(金) 16:16:58 ID:01dNrJEc
MySQL5を使用しています。


以下のようなテーブルがあります。

itemテーブル
item_id name color
1 商品1 3
2 商品2 12
3 商品3 7

colorテーブル
color_id name
1 赤
2 青
4 緑
8 黒

item.colorの部分は、ビット演算の概念を使って
3なら赤+青
12なら緑+黒
7なら赤+青+緑
の色を持っていることを意味します。

これを結合の段階で、以下のように色名を取得することは可能なのでしょうか?

1 商品1 赤
1 商品1 青
2 商品2 緑
2 商品2 黒
3 商品3 赤
3 商品3 青
3 商品3 緑
277NAME IS NULL:2010/07/09(金) 17:23:50 ID:???
>>276
MySQL5で試せてないけど、ビット演算の概念を使って取り出せばいいと思うんだ。

select item_id, item.name, color.name
from item cross join color
where item.color & color_id = color_id
order by item_id, color_id;
278276:2010/07/09(金) 18:36:38 ID:01dNrJEc
>>277
結合にビット演算子を使うのは頭にありませんでした。
MySQL5で見事に取得できました。
ありがとうございました。
279NAME IS NULL:2010/07/17(土) 08:55:41 ID:???
・DBMS名とバージョン
Oracle Database 10g 10.2.0.

SQLの実行計画で、
select count(1) from TBL_A
とした場合はSORT (AGGREGATE)が表示されるのに、
select col_a, col_b from TBL_A
などの場合にはSORT (AGGREGATE)が表示されないのはなぜでしょうか?
280NAME IS NULL:2010/07/17(土) 10:52:21 ID:???
前者は集約関数を使っているから、後者は使っていないから
むしろ何が疑問なのか分からない
281NAME IS NULL:2010/07/17(土) 11:41:13 ID:???
>>279
Oracle10gのプランナがバカ! とは言わないけど、洗練度に欠けるのかな。

以下、勝手な推測だが、
集約関数の場合、GROUP BYと併用する場合が多くて、
GROUP BYの実行には一旦ソートしてからまとめるようになっている。
だから、最終的には必要ないのだが、集約関数を見つけた時点で、
ソートしちゃった! ってところかと。
282NAME IS NULL:2010/07/17(土) 12:11:03 ID:???
SORT AGGREGATE と表示されても、実際は AGGREGATE しているだけで
SORT はしてないと思う。
ちなみに GROUP BY の場合は SORT GROUP BY とか
HASH GROUP BY とか表示される。
283NAME IS NULL:2010/07/18(日) 10:55:54 ID:wToLq7/Q
MYSQL5で
テーブルA
create table A( id int , name_id int, word varchar(128) , primary key ( id ) , index ( name_id ) )
テーブルB
create table B( id int, cid1 int, cid2 int , cid3 int , primary key ( id ) )
テーブルC
create table C( id int, name varchar(128) , primary key ( id ) , unique ( name ) )
こんな感じのテーブルを作成しました。テーブルAのname_idはテーブルBのidと、テーブルCのidはテーブルBのcid1〜cid3と関連します。
テーブルAのname_id,wordとテーブルBのcd1〜cd3をテーブルCのnameで置き換えた値で取り出したいのですが、どう書けばいいでしょうか?
284NAME IS NULL:2010/07/18(日) 11:10:54 ID:???
select A.name_id,
    A.word,
    C1.name,
    C2.name,
    C3.name
from  A
   inner join
    B
    on A.name_id = B.id
   inner join
    C as C1
    on B.cid1 = C1.id
   inner join
    C as C2
    on B.cid2 = C2.id
   inner join
    C as C3
    on B.cid3 = C3.id
;
285NAME IS NULL:2010/07/18(日) 11:14:27 ID:wToLq7/Q
>>284
おお。。。なるほど。そう書くんですね。ありがとうございます!
今まで正規化考えないでひとつのテーブルにまとめてたのを、
正規化勉強し始めてテーブル分けたものの簡単な取り出し方しかわかりませんでした。
286NAME IS NULL:2010/07/19(月) 00:47:59 ID:???
いや正規化できてねぇしw
287NAME IS NULL:2010/07/19(月) 01:05:28 ID:hKSUB/U7
えっ
288NAME IS NULL:2010/07/19(月) 15:56:24 ID:CQO73cD2
えっ
289NAME IS NULL:2010/07/19(月) 16:52:37 ID:???
なにそれこわい
290NAME IS NULL:2010/07/20(火) 00:29:41 ID:???
同じテーブルの同じ項目でで内部結合や外部結合する必要性(意味)はありますか?
291NAME IS NULL:2010/07/20(火) 01:36:00 ID:???
ある
292NAME IS NULL:2010/07/20(火) 07:17:41 ID:???
>>283はテーブルBが非正規化じゃないの
293NAME IS NULL:2010/07/20(火) 12:20:20 ID:???
>>292
んなことはスキーマ定義からだけでは判断できん。
294NAME IS NULL:2010/07/20(火) 12:26:56 ID:???
cid1〜3がどういう意味かによって正規形と言える場合もあるし
言えない場合もある
295NAME IS NULL:2010/07/20(火) 23:36:33 ID:???
C.id → B.id1
C.id → B.id2
C.id → B.id3
なんだから繰り返し項目。非正規化。
296NAME IS NULL:2010/07/20(火) 23:54:03 ID:???
質問です。SQL内に同じ計算式が2回出るときにすっきりする方法ありませんか?
例えば、現在値/その最大値というカラムがあり、現在値を増やすようなケースで

update TABLE set 現在値 = IF( 現在値+複雑な計算 => 最大値, 最大値, 現在値+複雑な計算 )
とすれば実現はできるのですが、この複雑な計算を2回書きたくないです(バグの元だし)。

尚、DBMSはMySQLです。
また、可読性よりはパフォーマンスを重視したいので、
上記よりもパフォーマンスで劣る方法しか無いようならあきらめます。
297296:2010/07/21(水) 00:04:41 ID:???
=> は >= に訂正。なんという素人ミス…。
なんかNVLとかIFNULL的な、SETMAX(複雑な計算, 最大値)とかいう関数があったら楽なんだけど。
298NAME IS NULL:2010/07/21(水) 00:33:18 ID:???
>>295
一般的に正規化されていない可能性が高いが
特殊な要件がある可能性もあるんで、今でている条件だけでは判断できない
ということを、>>293-294が言ってくれてるんだが理解できないのか?

>>296
当然その複雑な計算ってのは行ごとに値が変わるんだよな
可読性もとめるならビュー作っとけばいいんじゃね
パフォーマンスは、計算列に対する実態を保持するようなビュー(またはテーブル)
作れるならともかく、普通のビューなら落ちると思うけど
299296:2010/07/21(水) 01:09:36 ID:???
行ごとに値が違います。さらに言うと最大値も固定じゃないので、
カラムの制約な何かで最大値を制御できたとしても(出来るのか知らんけど)そういうのもNG。

やっぱ選択肢の一つはビューですよね…。もっとお手軽なのないかな。
300NAME IS NULL:2010/07/21(水) 01:44:29 ID:???
>>295
「繰り返しグループ」について正しく理解していないようだから詳しく。

属性の集まりが「繰り返しグループ」と呼ばれるのは一般的にその属性の
集まりがタプルではなく、単に何かの値の集合を意味する時。
この場合は「個々の属性値はatomic」という第一正規形の定義から間接的
に外れてしまうためこれは排除すべしとされている(歴史的にはCoddによる
元の第一正規形の定義に後付されたルール)。

例えばcid1〜cid3が「新郎、新婦、仲人」という「人名のタプル」だったり
「出発地、経由地、到着地」という「地名のタプル」だったりする場合は、
cid1〜cid3は繰り返しグループではなく、第一正規形を満たす。

cid1〜cid3が「趣味1、趣味2、趣味3」だと「趣味の集合」を意味している
「かもしれない」ので繰り返しグループ「かもしれない」。
それでも例えば趣味は常に正しく3種類入力し、その順序にも意味がある、
という仕様であればこれもまたタプルであって繰り返しグループではない。

要するにcid1〜cid3の属性名が似てるとか同じ外部キー制約を持っている
云々は正規形を判断する傍証にはなっても本質的には何の意味も無い。
実際にはcid1〜cid3が意味するところが解らないと第一正規形かどうかは
判断できないし、これはスキーマ定義からは読み取れない、ってことを
皆は言っている。ながなが。
301NAME IS NULL:2010/07/21(水) 03:00:30 ID:???
「好きな趣味」「嫌いな趣味」「どっちでもない趣味」とかでいいだろ
302NAME IS NULL:2010/07/21(水) 03:27:12 ID:???
>>301が何を言いたいのかまったく理解できない…。

「実際の仕様は本人しかわからない」という話をしてるのに
「仕様はこうでいいだろ」ってどういう意味だ?
303NAME IS NULL:2010/07/21(水) 05:58:48 ID:???
正規化はスレ違いってこともわからない馬鹿。
304NAME IS NULL:2010/07/21(水) 07:02:38 ID:???
>>299
やるじゃん

>>303
プッ
305NAME IS NULL:2010/07/21(水) 13:59:34 ID:???
>>299
複雑な計算結果を保持するカラムを作り、その内容を
トリガで行が挿入/更新されるたびに計算してセットする

現在値を更新する処理のパフォーマンス的には有利かもしれない
(現在値の更新でトリガが走るなら作り方に注意がいる)
普通に行を挿入/更新するパフォーマンスは若干落ちる

後はこれぐらいしか思いつかん

つかこの質問にしても、正規化の話にしても
設計はスレ違いだよな、ここ
306296:2010/07/21(水) 15:45:07 ID:???
SQLレベルでの解決ができるならこのスレ、と思ったけど
設計レベルでになるとスレ違いになるので難しいところ。

>>305
用途ごとのクエリの頻度次第では
トリガは一考の価値ありですね。ありがとうございます。
307NAME IS NULL:2010/07/21(水) 22:42:10 ID:???
CTE使えないの?
308296:2010/07/21(水) 22:52:44 ID:???
>>307
ググっても情報が少なめでよくわかりませんが
どうやらMySQLは非対応のようです。
309NAME IS NULL:2010/07/24(土) 01:52:58 ID:???
>>299
サブクエリでいいじゃん。
310NAME IS NULL:2010/07/24(土) 01:55:31 ID:???
良くわかんないけど、サブクエリでダメなら、RowIDで結合すれば?
311NAME IS NULL:2010/07/24(土) 14:48:57 ID:QZVGATrx
すみません、教えてください。

テーブルAとテーブルBがあり、
テーブルAには、1〜1000万までの連番を格納しています。連番はキーです。
テーブルBの方には、その連番の開始値と連番数が格納されています。

開始値 | 連番数
---------------
  1001 | 100   ←1001から1100までの意味
  5001 | 100   ←5001から5100までの意味
  9001 | 100   ←9001から9100までの意味

テーブルBで指定されている連番に一致するレコードを
テーブルAから取得するにはどのように書けばよいでしょうか。
上記の例だと300件取得する形になりますが、
テーブルBにも1万件程度のレコードがあります。

DBMSはOracle10gです。
312NAME IS NULL:2010/07/24(土) 15:10:34 ID:???
キー >= 開始値 and キー < 開始値 + 連番数

でいいでしょ。
313NAME IS NULL:2010/07/24(土) 19:26:01 ID:???
>>311
between使えという神の啓示のような例題だな
314NAME IS NULL:2010/07/24(土) 20:02:46 ID:???
>>312-313
SQLすべて書いてやれば?
1000万行x1万行のJOINや1000万行xIN(1万行)は避けたいところ。
再帰SQLなら1万行+取得行分のインデックス検索だが、10gはconnect byか。
315NAME IS NULL:2010/07/24(土) 20:15:29 ID:???
>>311

こんなんはどうだろうか?遅いかもしれんが

select * from A A1 where
  exists (
    select * from B where
      exists (
        select * from A A2 where
          A2.key = A1.key
          A2.key >= B.開始値 and
          A2.key < B.開始値 + B.連番数)
        )
  )

あ、ちなみに俺は>>312でも>>313でもない
316NAME IS NULL:2010/07/24(土) 20:23:32 ID:???
ベーシックなのから書けよ

select A.*
from  A
    cross join
    B
where  A.キー between B.開始値 and B.開始値 + B.連番数 - 1
;
317314:2010/07/24(土) 20:26:09 ID:???
>>315
EXISTSは2重にしなくとも
SELECT * FROM A WHERE EXISTS (SELECT * FROM B WHERE A1.key BETWEEN 開始値 AND 開始値+連番数-1);
でいけると思う。
EXISTSでもインデックス検索じゃねーから、遅いでしょうね。
318314:2010/07/24(土) 20:28:17 ID:???
>>317
A1.keyはA.keyの間違い。
319315:2010/07/24(土) 20:31:45 ID:???
>>317
あ、ほんとだ。なんか頭沸いてた・・・
320314:2010/07/24(土) 20:50:47 ID:???
SELECT A.* FROM A LEFT JOIN B ON A.key BETWEEN B.開始値 AND B.開始値+B.連番数-1 WHERE B.開始値 IS NOT NULL;
Oracleは持っていないので、通るのかどうかわからないが、
これなら、1000万行+1万行ですみそうな気がする。
321NAME IS NULL:2010/07/24(土) 20:52:46 ID:???
>>313
BETWEENって
MIN <= Value < MAX
って可能なの?最小値、最大値にイコールが入ってるパターンしかダメなんじゃなかったっけ
322NAME IS NULL:2010/07/24(土) 21:31:35 ID:???
>>320
わざわざOUTER JOINしてチェックする意味ある?
素直にINNER JOINで良い気がするんだが

OUTER JOINってINNER JOINより遅いイメージなんだがそんなことない?
323314:2010/07/24(土) 21:47:29 ID:???
>>322
Σ(゜д゜;)
なんか、Nested Loopを回避したくて、なんとなくINNER JOINを避けたけど、
いわれてみりゃ、そんな根拠ないなw
俺も頭の中、偏ってる。
324NAME IS NULL:2010/07/26(月) 19:08:08 ID:???
CentOSのMySQLを5.0系から5.1.49にアップデートしました。
そして、service restart mysqldとしたところ、起動せず、ログに以下の記録が残っていました。
100726 18:54:05 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
100726 18:54:50 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
100726 18:54:50 [Note] Plugin 'InnoDB' is disabled.
/usr/libexec/mysqld: Table 'mysql.plugin' doesn't exist
100726 18:54:50 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
100726 18:54:50 [ERROR] /usr/libexec/mysqld: unknown option '--skip-bdb'
100726 18:54:50 [ERROR] Aborting
100726 18:54:50 [Note] /usr/libexec/mysqld: Shutdown complete
100726 18:54:50 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
書いてある通りに、mysql_upgradeをやってみたのですが、
mysqlcheck: Got error: 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) when trying to connect
とでて、起動しませんでした。
どうすれば起動するようになりますか?
325NAME IS NULL:2010/07/26(月) 19:23:06 ID:???
スレ違い。MySQLスレへGo
326NAME IS NULL:2010/07/26(月) 19:36:54 ID:???
分かりました。
そっちで聞いてきます。
327NAME IS NULL:2010/07/26(月) 22:30:48 ID:???
ID 名前   カテゴリID 数字 日付
1 たぬき  1      5 7月3日
2 たぬき  1      8 7月4日
3 かっぱ  2      3 8月5日
4 きつね  3      9 1月3日
5 きつね  3      5 9月3日
のようなテーブルで
カテゴリIDごとでさらに名前ごとに数字の最小値を求めたいのですがどう書けばいいでしょうか?
この場合だとID1、3,5が取り出せるようにしたいのですが。
MYSQL5.1を使っています。
328NAME IS NULL:2010/07/26(月) 22:32:50 ID:???
329NAME IS NULL:2010/07/26(月) 22:34:34 ID:???
>>328
すみません >>4を見て自分で試そうとしたのですが、
むずかしすぎてわかりませんでした。
330NAME IS NULL:2010/07/26(月) 22:36:48 ID:???
あきらめろ。
331NAME IS NULL:2010/07/26(月) 22:45:06 ID:???
そこをなんとか
332NAME IS NULL:2010/07/26(月) 23:03:29 ID:???
>>329
まず最初に、「最小の数字」がすでに分かっている固定値(5とか3とか)だとするSQLを書く

次に最小値を求めるSQLを書く

やったね!
333NAME IS NULL:2010/07/27(火) 00:32:17 ID:???
>>327
select A.ID from テーブル A
join (select カテゴリID,名前,min(数字) as 最大数字 from テーブル group by カテゴリID,名前 ) B
 on A.カテゴリID=B.カテゴリID and A.名前=B.名前 and A.数字=B.最大数字

指定条件でダブりがあったりNULLがあったりした場合はどうなるかしらね
334NAME IS NULL:2010/07/27(火) 00:50:39 ID:???
でんすらんく
335NAME IS NULL:2010/07/27(火) 17:38:55 ID:???
品目 日付
-------------------------------
酢だこ 7/20
酢だこ 6/20
まだこ 7/21
まだこ 7/1
まだこ 6/25
大だこ 7/1
いか 6/20

こんな感じのテーブルがあり、品目名に"だこ"を含むデータを出現頻度の高い順に取り出そうとしていますが、
select 品目,日付 from table where 品目 in (select 品目 from table 品目 like '%だこ%' group by 品目 order by count(品目) desc;
で、やってみたのですが、遅すぎて使えませんでした。

何かいいやり方は無いでしょうか? お願い致します。
336NAME IS NULL:2010/07/27(火) 18:50:49 ID:???
like は前方一致じゃないとインデックスを使えない。
「○○だこ」のパターンがあらかじめ全部分かっていれば
 where 品目 in ('酢だこ','まだこ','大だこ')
などにすればインデックス(があれば)使ってくれるはず。
337NAME IS NULL:2010/07/27(火) 18:59:14 ID:???
>>335
いまいち何がやりたいかわからんな
select 品目,count(*) as 件数 from table where 品目 like '%だこ%'
group by 品目 order by count(*) desc
とかじゃダメなのか?
338NAME IS NULL:2010/07/27(火) 20:41:43 ID:???
個人的に気になったんで調べてみたけど
今どきはどのDBMSも無償オプションなり何なりで
全文検索機能提供してるのね。
日本語全文検索がどの程度使い物になるかは
やってみないと分からんけど。
339NAME IS NULL:2010/07/27(火) 21:03:06 ID:???
>>335
この手の検索を今だけ刹那的に行うのか、定型作業として頻繁に
行うのかわからないけど、後者であれば普通にカテゴリを管理した
マスタ表を用意するのが無難かと。

品目  カテゴリ
==========
酢だこ  たこ
まだこ  たこ
大だこ  たこ
たこ   たこ
いたこ  ひと
いか   いか
はまぐり かい
やきぐり くり
340NAME IS NULL:2010/07/27(火) 23:14:51 ID:???
>>335
品目の重複が多いのなら、HAVINGが早いかも。

SELECT T1.* FROM Table AS T1 JOIN
(SELECT 品目,count(品目) AS cnt FROM Table GROUP BY 品目 HAVING 品目 like '%だこ%') AS T1
USING(品目)
ORDER BY cnt DESC;
341NAME IS NULL:2010/07/27(火) 23:16:09 ID:???
>>340
2行目の(サブクエリ) AS T1 は AS T2の間違い。
スマソ。
342NAME IS NULL:2010/07/27(火) 23:43:56 ID:???
mysqlです。
レコードの削除処理でlimitを使用した残りを全て削除するようなSQLはどのように記述すればいいでしょうか
343NAME IS NULL:2010/07/27(火) 23:56:42 ID:???
EXCEPTでぐぐるといいことがあるかもしれんよ
344NAME IS NULL:2010/07/28(水) 00:25:12 ID:???
MySQLでEXCEPT使えるようになったっけ?

>>335のデータで最新日付3件を残して他を削除
DELETE FROM Table AS T1 WHERE 3< (SELECT count(*) FROM Table T2 WHERE T1.日付 < T2.日付);
でも、3件目の7/1が2件あるから、4件残ってしまう。
そもそもこれもMySQLで動くかどうかも不明。
345342:2010/07/28(水) 23:11:05 ID:???
>>343
mysqlに打ちのめされました
346NAME IS NULL:2010/07/29(木) 17:52:57 ID:VSFhFikc
はじめまして
データベースの勉強中です(基本情報技術者試験)

SQLの問題で 選択と射影の違いをよく問われます

・選択 条件に合った行を抽出
・射影 特定の列を抽出

(例)
表 syain(syanid,syainmei,age)

例1 select * from syain where age >= 20
(syain表から、ageが20以上の行を抽出しているので選択)

例2 select syainmei from syain
(syain表から、syainmeiの列のみ抽出しているので射影)

ということですが 以下の例だと

例3 select syainmei from syain where age >= 20

syainmeiという特定の列を指定して さらに ageが20以上という条件もあります

参考書やネットで調べてみると where条件があれば「選択」という意見と
特定の列を指定していれば「射影」という意見に分かれているようです


例3の場合 選択と射影 どちらと見るべきなのでしょうか?
アドバイスよろしくお願いします
347NAME IS NULL:2010/07/29(木) 23:31:28 ID:???
>>346
射影は重複も省くからdistinctしなきゃいけないよ。
それをぬきにしても射影や選択は関係演算のプリミティブな単位だから、例3は射影と選択を使っているといえる。
348 [―{}@{}@{}-] NAME IS NULL:2010/07/30(金) 02:53:36 ID:???
デジタル工房です
只今オープン価格中
http://gekiyasu.issekinicho.com

349NAME IS NULL:2010/07/30(金) 04:12:28 ID:9Np/J98F
>>346
選択(制限)や射影といった関係代数の演算は算数の足し算引き算
かけ算割り算と一緒で組み合わせて使うことができるんだよ〜

なので正解は「選択してから射影」だね。「射影してから選択」
ではないので要注意。
35039:2010/07/30(金) 07:10:30 ID:???
「選択」とか「射影」とか初めて聞いた。
勉強になりました。

by 開発技術者歴10年
351NAME IS NULL:2010/07/30(金) 07:21:28 ID:???
射影って普通、高校の数学で習わないか
352NAME IS NULL:2010/07/30(金) 07:33:40 ID:???
射精なら・・・
353NAME IS NULL:2010/07/30(金) 08:23:23 ID:???
>>351
今は大学に行かないと習わない。
354NAME IS NULL:2010/07/30(金) 08:37:25 ID:???
>>353
顔面蒼白…日本って想像以上にやばくなってんだな
355346:2010/07/31(土) 01:19:24 ID:A1610sXI
>>347
>>349
>>352

ありがとうございました
どっちかである必要はないのですね

すっきりしました
356NAME IS NULL:2010/08/02(月) 17:12:02 ID:6clj2YAP
次のようなSELECTをするケースではどのようなSQLが妥当でしょうか?

・テーブルAとBをJOINしたい
・テーブルCとDをJOINしたい
・A+BとC+DはLEFT JOINしたい

とりあえず次のような2ケースは思いつくのですが、

【2回LEFT JOINする】
SELECT *
FROM A
JOIN B USING( key_ab )
LEFT JOIN C USING( key_ac )
LEFT JOIN D USING( key_cd )

これだと理論的には1回でいいはずのLEFT JOINが2回になりパフォーマンスがもったいない気が。

【CDをサブクエリにする】
SELECT *
FROM A
JOIN B USING( key_ab )
LEFT JOIN (
SELECT *
FROM C
JOIN D USING( key_cd )
) CD USING( key_ac )

これはこれでしなくてもいいサブクエリにしてるようでやはりパフォーマンスが。
他に方法はあるでしょうか。
357356:2010/08/02(月) 17:16:25 ID:???
情報不足でした、DBMSはMySQL5です。
標準SQLとして気になるところですが、さしあたってMySQLでできればいいです。
358NAME IS NULL:2010/08/02(月) 18:02:36 ID:???
>>356
SELECT * FROM
A JOIN B USING(key_ab)
LEFT JOIN
(C JOIN D USING(key_cd)
USING(key_ac);

標準なのか、MySQLで動くのかも知らないけどね。
359NAME IS NULL:2010/08/02(月) 18:04:10 ID:???
括弧ひとつ抜けてた
(C JOIN D USING(key_cd))

最初のも括弧で括った方が、後からわかりやすそう。
(A JOIN B USING(key_ab))
360356:2010/08/02(月) 18:25:55 ID:???
動いた!括弧でくくるだけの話だったとは…試したことあったと思ったんだけどなぁ。
ありがとうございました!
361NAME IS NULL:2010/08/02(月) 20:14:10 ID:???
いやまて、動いた動かなかったレベルの話なのか?
パフォーマンス的にはFROM句サブクエリはいいもんじゃないぞ。
362356:2010/08/02(月) 21:34:30 ID:???
>>361
え、FROM句サブクエリってのは>>356の後者のことであって
括弧でくくるのはサブクエリにはならないでしょ?
explainしてみた限りじゃ大丈夫そうですが。
363NAME IS NULL:2010/08/10(火) 21:51:28 ID:???
test
364NAME IS NULL:2010/08/11(水) 07:44:11 ID:7xoB/G7y
oracle 10gです。

商品コード|売上店舗|売上個数

というテーブルから、
店舗毎の売上をまとめた列を追加した以下のようなテーブルを作りたいです。

商品コード|店舗a売上個数|店舗b売上個数|店舗c売上個数|

現在は店舗毎の売上を集計したテーブルを別に作って、それを結合させて作っていますが、それ以外で単一のsqlで書く場合どうなるでしょうか?

簡単かと思ったら思いつきません。。
お願いします。
365NAME IS NULL:2010/08/11(水) 07:48:19 ID:7xoB/G7y
↑テーブルを作りたい、ではなく下のように抽出したい、です。
すみません。
366NAME IS NULL:2010/08/11(水) 08:11:31 ID:???
ある期間に、大阪府と京都府に転入して来た人の数を出したい時のSQLを、

select count(*), 都道府県, 日付 from 共通テーブル as t1 join
(select 都道府県, 日付 from 共通テーブル where 日付 between 'YYYY-MM-DD' and 'YYYY-MM-DD' and 都道府県 like '%府') as t2
using (都道府県、日付)

としてMYSQL5.0.88でやってみたのですが、1行しか出ません。
sortを掛けてdescを、別の1行が表示されます。

Q1) 複数行を表示するにはどうしたらいいのでしょうか?
Q2) 他に何かいいSQL文はありるのでしょうか?

ご助言お願いします。
※実際は、日本語名と日本語データは使っていません。
367NAME IS NULL:2010/08/11(水) 08:36:29 ID:???
>>364
>>5

>>366
共通テーブルの定義がどのようになっているか、イマイチなんだが。
行数をカウントすればいいのか?

SELECT 都道府県,日付,count(*) FROM 共通テーブル
WHERE 日付 BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND 都道府県 LIKE '%府'
GROUP BY 都道府県,日付;
368NAME IS NULL:2010/08/11(水) 20:08:22 ID:???
>>367
有難う御座いました。
369NAME IS NULL:2010/08/12(木) 23:16:07 ID:UMUtuT0a
会社コード|部署コード|課コード|給料

というテーブルがあったとき、
GROUP BY 会社コード , 部署コード
で部署毎の給料合計を出したいけど、
抽出結果の列には課コードも含めたい、
というときってどうしたら良いのでしょうか?
イメージは↓の感じです。
A会社|B部署|C課|100万円
A会社|B部署|D課|100万円
A会社|E部署|F課|500万円
A会社|E部署|G課|500万円
370NAME IS NULL:2010/08/12(木) 23:22:12 ID:???
371NAME IS NULL:2010/08/12(木) 23:38:29 ID:UMUtuT0a
>>370
ありがとうございます。
テンプレは見たのですが、これが>>4に該当すると気づかずスルーしてしまいました。
これは自己結合というやつでしょうか。
GROUP BY したものと、それ以外の自分を結合する感じってことなのかな?
ちょっと書いたことないので、試しにやってみます。
372NAME IS NULL:2010/08/13(金) 01:50:47 ID:???
>>369
そういうのはpartition byを使う。
あとdbmsとバージョンかけ。
373NAME IS NULL:2010/08/17(火) 10:20:54 ID:???
>>5のSUMの中をcaseじゃなくifを使って書こうと思って
SELECT KEY,
SUM(IF data = 'a' THEN 1 END) AS a,
SUM(CASE data WHEN 'b' THEN 1 END) AS b
FROM table
GROUP BY key
ORDER BY key
;
としてみたのですが、
「ORA-00907: 右カッコがありません。

とエラーが出て実行できませんでした。
どうすればifを使って書き換えられますか?
環境はOracle 11gです
374NAME IS NULL:2010/08/17(火) 15:13:02 ID:S3HPeix8
はじめまして

・Access2000

下のようなテーブルがあったときに

テーブルA
名前 科目 点数
----------------------
岡村 国語 51
岡村 数学 48
岡村 英語 39
徳田 国語 60
徳田 数学 30
徳田 英語 48
渡辺 国語 28
渡辺 数学 67
渡辺 英語 25

下のように各科目の最高点を名前つきで取得するにはどうすればいいのでしょうか?

結果(各科目の最高点)
----------------------
徳田 国語 60
岡村 数学 48
徳田 英語 48


よろしくおねがいします。
375NAME IS NULL:2010/08/17(火) 15:44:31 ID:???
>>374

>>4 なんだけど、ACCESS2000でどうなるかなー
376NAME IS NULL:2010/08/17(火) 19:31:36 ID:???
>>373
書き換えられません。
377NAME IS NULL:2010/08/17(火) 19:37:30 ID:???
>>373
OracleのSQLにifなんかない
378374:2010/08/17(火) 20:54:04 ID:???
できました
ありがとうございました
379NAME IS NULL:2010/08/18(水) 00:29:15 ID:???
>>373
なんで勝手に書き換えるんだよw
>>374
accessでも同じ
エイリアスの書き方が通らないかもだけど
380373:2010/08/18(水) 03:16:10 ID:???
すいません
SQLにIFなんてないんですね
勉強のためにIF使って書いてみようと思ったのですが
ありがとうございました
381NAME IS NULL:2010/08/18(水) 22:28:49 ID:???
382NAME IS NULL:2010/08/19(木) 15:54:27 ID:???
SQLServer2005で質問です
主キーをauto incrementにして
INSERT時に連番が振られるようにしています。
このidをintではなくvarchar(10)で'0000000001'から
振られるようにしたいのですが、
id_str などのフィールドを宣言して
id(int)で連番を振った後で、id_strを更新するしかないのでしょうか。
383NAME IS NULL:2010/08/19(木) 21:31:24 ID:???
うん。
384NAME IS NULL:2010/08/21(土) 00:01:07 ID:???
id_strを計算列として定義したら、いちいち更新しなくて済むよ。
385NAME IS NULL:2010/08/21(土) 00:10:48 ID:???
こんな感じ
CREATE TABLE TBL (
id int IDENTITY(1, 1) NOT NULL,
id_str AS REPLACE(STR(id, 10, 0), ' ', '0'),
col1 varchar(50),
CONSTRAINT PK_TBL PRIMARY KEY (id)
)
386NAME IS NULL:2010/08/21(土) 19:15:24 ID:???
・DBMS名とバージョン
  SQL Server Compact 3.5

・テーブルデータ 家計簿のようなデータです
Cd1 Cd2  Item      Cost
---+----+-----------+----------------
1   0    食費      NULL
1   1    弁当      500
2   0    光熱費     NULL
2   1    水道料     1000
2   1    水道料     2000
2   2    ガス料     4000  

・欲しい結果
Cd1 Cd2  Item      Sum
---+----+-----------+----------------
1   0    食費      500
2   0    光熱費    7000

・説明
Cd1が大分類、Cd2が中分類を表してます。
Cd2が0の場合、Itemは大分類の名称。それ以外の場合、中分類の名称が入ってます。
大分類ごとにItemと合計額が欲しいです。
387NAME IS NULL:2010/08/21(土) 19:19:10 ID:???
>>4の修正で
388NAME IS NULL:2010/08/21(土) 22:05:03 ID:???
>>386
SELECT 家1.Cd1, 家1.Cd2, 家1.item,
(SELECT SUM(家2.cost) FROM 家計簿 家2 WHERE 家2.Cd1 = 家1.Cd1) AS sum
FROM 家計簿 家1 WHERE 家1.Cd2 = '0'
389NAME IS NULL:2010/08/23(月) 07:08:36 ID:7A4MqZEH
>>396

select
cd1,0 as cd2,
max(case cd2 when 0 then Item end),
sum(Cost)
from 家計簿
group by cd1;

今日読んだこの記事は勉強になった
http://codezine.jp/article/detail/3231
390NAME IS NULL:2010/08/23(月) 15:13:15 ID:CCVEhEto
SQLServer 2005 EE

注文
顧客|注文番号
A   1
B   2
C   3

注文明細
注文番号|商品|時刻
1    ミルク 10:53
1    納豆  14:00
2    ミルク 10:55
2    豆腐  11:05
2    納豆  12:00
3    ミルク 11:03
3    納豆  9:50

 これらのテーブルに対して、ある時刻の間にある商品を発注した
明細と同じ注文の明細一覧を出したいです。

10:50〜11:00の間の「ミルク」の場合
A   1   ミルク 10:53
A   1   納豆  14:00
B   2   ミルク 10:55
B   2   豆腐  11:05
B   2   納豆  12:00

とう出力を得たいです
よろしくお願いします。
391NAME IS NULL:2010/08/23(月) 15:20:05 ID:???
結果の例がおかしいけど、あまりにも初歩的な内容な気が・・・
JOIN と BETWEENでいけるよね?
392NAME IS NULL:2010/08/23(月) 15:45:24 ID:???
>>39
10:50〜11:00にミルクが含まれている注文の注文明細の一覧なのですが、
JOINとBETWEENでいけますか?
あと、結果の例は合ってます。
393NAME IS NULL:2010/08/23(月) 20:17:50 ID:???
まず指定の条件の明細を含む注文番号をもとめる。

select 注文番号, 商品, 時刻 from 注文明細 where 注文番号 in (
 select distinct(注文番号) from 注文明細
  wehere 商品='ミルク' between 時刻 '10:50' and '11:00'
 )

inでもjoinでも好きなほうで。注文テーブルとのjoinは省略した。
394NAME IS NULL:2010/08/23(月) 20:30:27 ID:???
>>393
ありがとうございます
注文と明細を結びつける注文番号が2カラムからなるのですが、どうしたらいいでしょうか?
395NAME IS NULL:2010/08/23(月) 20:55:01 ID:???
複合キーってこと?
396NAME IS NULL:2010/08/23(月) 21:07:19 ID:???
>>395
複合キーって言うんでしょうか?
実際には、日付とセットじゃないとユニークにならないんです
397NAME IS NULL:2010/08/23(月) 22:52:48 ID:???
>>390

select b.顧客,a.商品,a.時刻
from (select 注文番号,商品,時刻,
max(case when 時刻 between '10:50' and '11:00'
then 1 else 0 end) over(partition by 注文番号)
as flag
from 注文明細) a,注文 b
where a.flag = 1
and a.注文番号 = b.注文番号


max overは、この記事のを応用した。
http://codezine.jp/article/detail/3231
398NAME IS NULL:2010/08/23(月) 23:39:45 ID:???
>>397
ありがとうございます
ちょうと今メンテ中で試せないので後で試してみます
399NAME IS NULL:2010/08/24(火) 04:10:39 ID:4e1wvTf+
>>398
390はちょっとな。普通は393のように書くと思う…
390はレスポンス的に大丈夫なの?
(Enterprise Editionっていうくらいだから数千万件以上の大規模DB?
実行計画等で検証しないとさ…)

あと「日付とセットじゃないとユニークにならないんです」ってあるけど
注文明細テーブルに「注文明細番号」ってカラムを追加して
 ・注文書番号
 ・注文書明細番号
の2カラムを主キーにすればい…い…ん…じゃ…な…い…か?

400NAME IS NULL:2010/08/24(火) 04:13:13 ID:4e1wvTf+
ごめんなさい。
「397はちょっとな」「397はレスポンス的に大丈夫なの?」
の間違いです。
401NAME IS NULL:2010/08/24(火) 04:32:59 ID:4e1wvTf+
注文明細の件数が著しく大きくなった時397は危険な気が…

このクエリのみに限定すれば、

 (「注文書番号」、「注文書明細番号」)を非クラスタな主キーにして、
 時刻をクラスタ化インデックスに設定して範囲検索を高速化させる

とかの考慮を緻密にしていかないと大規模DBはマジフリーズ…

402NAME IS NULL:2010/08/24(火) 04:34:45 ID:4e1wvTf+
「このクエリ」ってのは393だよ。
くどい?
403NAME IS NULL:2010/08/24(火) 04:50:33 ID:???
>>399
>>397まだ試せてないです。
するどいですね。もう億に乗っている件数です。このパターンの検索が一番多いので、パフォーマンス出ない
なら、テーブル構成も変えることも考えてます。
実は今は以下の検索をしてるんですが、遅いので他の解があればと質問してみました。もしくは、テンポラリ
テーブル or プログラムで吸収という最悪の事態も考えています。

SELECT * FROM 注文
INNER JOIN 注文明細
ON 注文.注文番号 = 注文明細.注文番号
WHERE EXISTS(SELECT * FROM 注文明細 AS 検索明細
WHERE 検索明細.商品 = 'ミルク' AND 検索明細.時刻 BETWEEN 10:50 AND 11:00)
404NAME IS NULL:2010/08/24(火) 07:05:52 ID:???
>>397
正しくは、こうだぜ

select b.顧客,a.商品,a.時刻
from (select 注文番号,商品,時刻,
max(case when 商品 = 'ミルク'
and 時刻 between '10:50' and '11:00'
then 1 else 0 end)
over(partition by 注文番号) as flag
from 注文明細) a,注文 b
where a.flag = 1
and a.注文番号 = b.注文番号
405NAME IS NULL:2010/08/24(火) 07:39:40 ID:???
inをjoinに変えるだけだろうからこんな感じでいいだろう

select a.日付. a.注文番号, a.商品, a.時刻 from 注文明細 as a
 join (
  select distinct 日付, 注文番号 from 注文明細
   where 商品='ミルク' between 時刻 '10:50' and '11:00' 
 ) as b
 on a.日付 = b.日付 and a.注文番号 = b.注文番号
406NAME IS NULL:2010/08/24(火) 20:10:44 ID:vSbQzCaU
>>403
399です。以下は393のクエリ前提。
※397はありえない。唯一の絞込条件の時刻をcase変換→max→whereで=1?
 1億件全件なめて下さいっていってんの?

インデックスはどうなってんの?
年月日指定の上での時刻範囲指定なの?
そうだったら(年月日,時刻)に非クラスタ化インデックスは必須。
※1億件想定なので、年月日指定で絞込度がかなり高い→非クラスタでよい。

年月日指定無しの時刻範囲指定だったら、
(商品,時刻)にクラスタ化インデックスを張れば
このクエリに関しては速くなる。
非クラスタだとBookmarkLookup回数が多すぎでレスポンス上がらない懸念。

現在のインデックスを教えて
407NAME IS NULL:2010/08/24(火) 20:44:21 ID:???
>>403
このクエリちゃんと意図どおりに動く?なんか写し忘れてにない?
408NAME IS NULL:2010/08/24(火) 21:36:50 ID:2QSEhmny
よろしくお願いいたします。

・DBMS名とバージョン
  HiRDB Ver8

・テーブルデータ
<Aテーブル>
A1   A2   A3   A4   A5
------- ------- ------- ------- ----------
XXXXXXX XX1   ABC 3 2009/05/08
WWCWWCW WW2   CCB 1 2008/03/21
DDDDDDD DD1   JPN 5 2007/08/08
GGGGGGG GX9   SOX 2 1977/01/04
FFFFFFF USJ   NPB 3 2001/09/11


<Bテーブル>
B1   B2   B3   B4   B5
------- ------- ------- ------- ----------
XXXXXXX XX1  ibicha  oshimu 2002/07/05
XXXXXXX XX1  takeshi okada 2005/07/15
XXXXXXX XX1  kamo shu 1857/09/25
WWCWWCW WW2  wao wao 2008/10/22
DDDDDDD DD1  ui hhh 2006/06/30
DDDDDDD DD1  jojoj x5xx 1999/09/09
DDDDDDD DD1  momo hara 2005/03/07
DDDDDDD DD1  itai u- 2003/12/22
DDDDDDD DD1  koma nogoal 2007/04/26
GGGGGGG GX9   dame record 2009/11/14
FFFFFFF USJ   iki tai 1995/08/15
FFFFFFF USJ  sst ebuspi 2004/01/05
FFFFFFF USJ  bb pp 2009/08/23

・欲しい結果
A1   A2   B1   B2   A4 B1andB2COUNT
------- ------ ------- ------- ------- ------------
GGGGGGG GX9 GGGGGGG GX9 2 1


・説明
SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
A1とB1は、A2とB2は同じデータが基本です。
Aテーブルの「A4」カラムにはBテーブルのレコード数を持っています。
しかし、よくよく見るとAテーブルの「GGGGGGG」のA4には「2」のはずなのにBテーブルには実際にレコードは1つしかありません。
こういう状態になってしまっているのを割り出したいのですがどのようにA4とBテーブルで数があってないものを抽出できるでしょうか。
よろしくお願いいたします。
409NAME IS NULL:2010/08/24(火) 21:39:36 ID:???
B1でGroup ByしてCount()した結果とA4を比較すればいいだけだろ。
410NAME IS NULL:2010/08/24(火) 21:40:05 ID:2QSEhmny
すみません 書体がずれて見栄えがすごく悪い・・・
Aテーブルの例は
XXXXXXXがA1カラム
XX1がA2カラム
ABCがA3カラム
3がA4カラム
2009/05/08がA5カラムです
411NAME IS NULL:2010/08/24(火) 21:43:22 ID:2QSEhmny
>409
申し訳ないです。
group by B1, B2 とcountした結果とA4の比較方法がわからなくて困っています。
JOINとかの使い方がいまいち分かりづらくて・・・
ごめんなさい
412NAME IS NULL:2010/08/24(火) 21:46:02 ID:???
少しは自分で考えろ。
413NAME IS NULL:2010/08/24(火) 21:53:31 ID:2QSEhmny
考えましたよ(;_+)そんなきつい言い方竹刀でください・・・
SELECT
A.*
FROM
A
INNER JOIN
(SELECT B1,B2,COUNT(*) CNT FROM B GROUP BY B1,B2) B
ON A.A1=B.B1 AND
A.A2=B.B2 AND
A.A4 <> B.CNT;

なんてやってみたのですがJOINの後が無効な識別子エラーが出ます。
JOINの規格が違うのか・・・
414NAME IS NULL:2010/08/24(火) 22:32:18 ID:???
HiRDB!
このスレに答えられるやついるのか?
415414:2010/08/24(火) 22:41:36 ID:???
あ、ちなみに>>413のSQLは標準SQLとしては別におかしくはない。
ちょっと引っかかるのはテーブル名と同じ相関名って使えたっけな?ってくらい。
(サブクエリの括弧の後の B のとこね。)
あとはHiRDBでどういうSQLなら使えるのかってことだけど・・・
416NAME IS NULL:2010/08/24(火) 23:35:48 ID:2QSEhmny
あっ。。。相関名同じのはまずかったすね。。。でも変えてみても
識別子がおかしいと怒られちゃいました。。。
エラー変わらずでス(汗)
HiRDBなんてマイナーすぎなのかなぁ

HiRDBの準拠しているものを調べてみたのですがどこにも出ていないようで見つけられてはいないです。
近似したRDBってあるのかも???
417NAME IS NULL:2010/08/25(水) 18:42:03 ID:???
MySQL Ver5以降で質問です。

まずテーブルの説明をします。
user_dataテーブル user_id, level
friendテーブル user_id, friend_user_id
という2つのテーブルがあります。

friendテーブルは 1, 2 というレコードであれば
「user_id=2は、user_id=1の友達である」
という意味となり、必ずそれぞれを入れ替えた「2, 1」というレコードも存在します。

user_dataテーブルから
「levelが4で、かつあなたの友人ではないユーザーのレコードを全て取得する」
ということをやりたいのですが、可能でしょうか。

「levelが4で、かつあなたの友人『である』ユーザー〜」であれば(あなたのIDは1とします)
SELECT * FROM user_data INNER JOIN friend ON user_data.user_id = friend.user_id AND 1 = friend.friend_user_id;
でOKかと思います。
この逆がやりたいのですが…

サブクエリーを使って、NOT IN を使うなどすれば不可能では無さそうですが、1の友達が1000人くらいいるときつそうです。
418NAME IS NULL:2010/08/25(水) 19:04:40 ID:???
>>417
select *
from  user_data T1
where  T1.level = 4
and   not exists (
        select *
        from  friend T2
        where  T1.user_id = T2._user_id
        and   T2.friend_user_id = 1
    )
;
419NAME IS NULL:2010/08/25(水) 19:09:48 ID:???
>>413
INNER JOINのキーワードを使わない、昔ながらのJOINにすれば
いけるんじゃなかろうか。

SELECT A.*
FROM A, (SELECT B1,B2,COUNT(*) CNT FROM B GROUP BY B1,B2) BB
WHERE A.A1=BB.B1
AND A.A2=BB.B2
AND A.A4 <> BB.CNT;
420NAME IS NULL:2010/08/25(水) 19:10:27 ID:???
>>417
AND 1 <> friend.friend_user_id AND level=4

レベルを忘れていそうだから足しといた。
421NAME IS NULL:2010/08/25(水) 19:57:59 ID:???
AND 1 <> friend.user_id
も必要だな。
422NAME IS NULL:2010/08/25(水) 21:43:00 ID:VtTC/Lir
>>419
感謝です。
後で試してみます。
423NAME IS NULL:2010/08/26(木) 10:26:52 ID:???
>>418
ありがとうございます
EXISTSというのは初めて知りましたが、望んだとおりの結果が得られました
勉強しておきます
424NAME IS NULL:2010/08/29(日) 10:26:44 ID:???
ちょっとした質問なんですが
SQLで落ちた過去ログをdatで自動的に保存できたりしますか?
もし出来たとしたらどういった構文を使えばよいのでしょうか?
425NAME IS NULL:2010/08/29(日) 23:35:52 ID:???
426NAME IS NULL:2010/08/29(日) 23:39:06 ID:???
日本語でOK
427NAME IS NULL:2010/09/01(水) 16:35:56 ID:???
SYBASEのSQLについてお聞きしたいです。
現在大量なデータの入った複数のテーブルを
INDEXを持った項目でJOINし、DELETを行う
SQLを作成しています。

このとき、発行するSQLがINDEXを使用するかを
SQL実行前に確認できるすべがあれば教えてください。
428NAME IS NULL:2010/09/01(水) 19:43:18 ID:???
たぶんない。
スレ違いだから、二度と来んな。
429NAME IS NULL:2010/09/02(木) 03:14:11 ID:???
>>427
SYBASEよく知らないしバージョンとか書いてないからなんとも言えんが
実行計画ぐらい取れるとおもうんだが

まあ、SYBASE 実行計画 でググって二度と来るな
430NAME IS NULL:2010/09/02(木) 08:20:42 ID:???
>>428、429
了解しました。
ありがとうございます。
431NAME IS NULL:2010/09/02(木) 14:05:15 ID:???
ぶっちゃけここにいる人ってかじった程度の知識の人ばっかだよね、笑えるw
432NAME IS NULL:2010/09/02(木) 20:29:43 ID:???
2chだし。
433NAME IS NULL:2010/09/05(日) 15:05:29 ID:???
SQLのインデントできないし、過去ログ落ちしたら見れなくなるし

普通は、OTNとかMSDNに行くんじゃね
434NAME IS NULL:2010/09/08(水) 09:23:20 ID:???
>かじった程度の知識の人ばっかだよね、笑えるw
勘違いしているようだから、教えよう。

教える人は、SQL勉強中の人。
教えることにより、知識を得ることができる。
マスターした人は、常駐しない。得るものがないから。
よって、俺もここに2度と来ないだろう。
435NAME IS NULL:2010/09/08(水) 21:46:32 ID:???
その「かじった程度の人」が得意げに書き込む回答の間違いを
突っ込んでやろうと虎視眈々と狙っているベテランも結構いるぞ。
自分からはあんまり回答しないけどな。
436NAME IS NULL:2010/09/08(水) 22:35:51 ID:???
何この不毛な雑談
437NAME IS NULL:2010/09/08(水) 23:07:43 ID:???
以下のようにSQL定義をしたのですが
最後の部分でAS付近に〜と言うエラーが出てしまい
コンパイルが出来ませんでした。
何が間違っているのか良く分かりません・・・
お力お貸しください・・・

SQL = "SELECT メインテーブル.*,"
-----------------------------------------------------------------
SQL = SQL & " (SELECT A.ABC AS テスト1 "
SQL = SQL & " FROM テーブルA A "
SQL = SQL & " WHERE A.ナンバー = メインテーブル.ナンバー"
SQL = SQL & " GROUP BY A.ナンバー) AS テスト1,"
-----------------------------------------------------------------
上記の---の中と同じようにその他に4つ定義
今まで4つだけ定義してたのですが、今回改修作業があり同じように
1つ追加することで最初に書いたエラーが出るようになってしまいました。

SQL = SQL & "FROM メインテーブル LEFT OUTER JOIN "
SQL = SQL & " マスタ ON "
SQL = SQL & " A.顧客ID = マスタ.顧客ID "
438NAME IS NULL:2010/09/09(木) 00:19:46 ID:???
意味不明だし勝手に省略したらわかるもんもわからんだろ。

まあエスパーレスするとFROMの前に「AS テスト1,」のカンマが残って文法エラーとかだろ。
439NAME IS NULL:2010/09/09(木) 00:34:36 ID:???
>>434
> マスターした人は、常駐しない。得るものがないから。
> よって、俺もここに2度と来ないだろう。

マスターしたんだ。
すごいなー。
440NAME IS NULL:2010/09/09(木) 11:31:16 ID:???
>>437
最低限、使ってるDBMSぐらいかけ
追加したってなら追加したSQLも書け
何が間違ってるか?お前が追加した結果SQLが間違ってるに決まってるだろう
>>438
1個追加したってんだから、どっちかって言うと追加する直前にカンマ付加してないだけだと予想

どうでも良いけどこのSQL、文法チェックは通っても実行時のデータ次第で
実行時エラーになる可能性あるのは判ってるんだろうかね
441NAME IS NULL:2010/09/09(木) 15:25:21 ID:???
>>437
もともと定義されていた4つのうち、上3つは最後にカンマがついていて、
4番目のものにはカンマがなかったはず。
それにしたがって追加するとよいよ。

>>438
意味不明って
442NAME IS NULL:2010/09/09(木) 15:35:11 ID:???
いきなりコンパイルができませんでしたとか意味わからんダロw
443NAME IS NULL:2010/09/13(月) 10:54:25 ID:???
ひとつのテーブルで各レコードは他のレコードと1:Nの親子関係にあります
コード  親コード データ
1     1     A
2     1     B
3     2     C
4     3     D
5     1     E
6     2     F

まあこんな感じで1以外は全部親を1つ持ち親はひとつ以上の子を持ちます(子が無い親も居ますが)
これである親の子レコード以下を下記のような感じで全部抽出したいのですが
SQLだけで出来ますでしょうか

コード=2のときの抽出結果
コード データ 世代
3    C    1
4    D    2
6    F    1

世代は2から何世代下にいるかです、子なら1孫なら2…ということです

また無理ならこうゆうことを可能にするデータ構造を教えてください
DBはFireBird1.5を想定していますがフリーのDBなら何でも良いです


444NAME IS NULL:2010/09/13(月) 12:48:44 ID:???
>>443
PostgreSQLなrWITH RECURSIVEかconnevt_by関数で出来る。

WITH RECURSIVE Temp(code,data,tree) AS
(SELECT code,data,1 FROM Table1 WHERE pcode=2
UNION ALL
SELECT T1.code,T1.data,Temp.tree+1 FROM Table1 AS T1,Temp WHERE T1.pcode=Temp.code)
SELECT * FROM Temp;

再帰クエリが使えないのなら、入れ子集合モデルってのがあるにはあるがな。
445NAME IS NULL:2010/09/13(月) 19:36:28 ID:???
>>443
Firebird 2.1から再帰CTE(WITH RECURSIVE〜)に対応してるよ

ttp://firebirdsql.org/rlsnotesh/rlsnotes210.html#rnfb210-cte
446NAME IS NULL:2010/09/14(火) 19:27:46 ID:???
>>444
>>445
ありがとうございました
色々やってみます
447NAME IS NULL:2010/09/16(木) 01:20:13 ID:???
pl/sql

カーソルFORループを宣言して
該当するレコードが1つもなかったとき
NO_DATA_FOUND
で拾えますか?
448NAME IS NULL:2010/09/16(木) 07:24:24 ID:???
スレ違い
449NAME IS NULL:2010/09/17(金) 07:18:14 ID:???
の純情
450NAME IS NULL:2010/09/17(金) 09:55:49 ID:???
三分の一の
451NAME IS NULL:2010/09/23(木) 17:04:17 ID:qAHVmbyC
最近になってDBの勉強を始めたのですが詰ってしまったのでちょっと質問させてください。

使っているのは、derbyです、バージョンはij起動時に10.5と表示されています

・テーブルデータ
受注表
-------------------
顧客コード | 受注個数
-------------------
001 | 100
002 | 200
003 | 100
001 | 300
003 | 400

・欲しい結果
結果
---------------------------------
顧客コード | 個人平均値 | 全体平均値
---------------------------------
001 |200 |240
002 |200 |240
003 |250 |240

・説明
SELECT
  顧客コード,
  AVG(受注個数) AS 個人平均値,
  (SELECT AVG(受注個数) FROM 受注表) AS 全体平均値 
FROM
受注表
GROUP BY
顧客コード;

上記のSQLだとエラーが出て動かない(エラーメッセージ失念してしまいました)
どこがどう悪いのか現在の自分では分からなくてどうしようもない状態です。
452NAME IS NULL:2010/09/23(木) 17:19:48 ID:???
SELECT
  顧客コード,
  AVG(受注個数) AS 個人平均値,
  全体平均値
FROM
受注表,
(SELECT AVG(受注個数) AS 全体平均値 FROM 受注表)
GROUP BY
顧客コード;
453451:2010/09/23(木) 19:38:41 ID:???
>>452
ありがとうございます、今試す環境がないので明日確認してみます。

それにしても、SQLって色んな書き方あって一筋縄では行かないのね・・・・
大変だけど楽しいですね
454451:2010/09/24(金) 23:33:49 ID:???
今日試してきたが452では動かなかった

SELECT
  顧客コード,
  AVG(受注個数) AS 個人平均値,
  TOTAL_AVG.全体平均値
FROM
  受注表,
  (SELECT AVG(受注個数) AS 全体平均値 FROM 受注表) AS TOTAL_AVG
GROUP BY
  顧客コード;

でやっと動いてくれました。
何はともあれ、>>452 のお陰で突破できたよ、本当にありがとう

455NAME IS NULL:2010/09/25(土) 13:10:05 ID:???
質問です。
where句が膨大な数の条件式による論理和(OR)で構成されているselect文において、
得られた各レコードがどの条件式によるものかを判断したい場合どのようにするべきですか?

例えば下のようなテーブル(t)に対して
id name sex age
0 tanaka male 25
1 yamada female 18
2 suzuki male 16

select name from t where age < 20 or sex = 'male';

を発行した場合すべてのnameが得られますが、それぞれのレコードがどの条件式によって得られたものかを判断したいと考えています。
456NAME IS NULL:2010/09/25(土) 13:24:46 ID:???
個々の条件式で得られた結果との差分を取ればいいんじゃね?
457NAME IS NULL:2010/09/25(土) 14:37:30 ID:???
プログラム上で分岐させるために判断するなら条件ごとに別SQLにすれば良いじゃん
458NAME IS NULL:2010/09/25(土) 16:25:53 ID:???
UNION ALL 使えば〜〜
459NAME IS NULL:2010/09/25(土) 17:11:33 ID:???
なぜそんなことをしたいのか分かんないと適切な答えができないな
こんなんでもいいんか?
select name,
    case when age < 20 then 1 end as 条件1,
    case when sex = 'male' then 1 end as 条件2
from  t
where  age < 20
or   sex = 'male'
;
460NAME IS NULL:2010/09/27(月) 00:05:44 ID:???
今回1回だけならなんとでもなるだろうけど、今後もそれをちょくちょく調べるなら、
ORを全部ばらしてUNIONに書き換えておくほうがいいだろうねぇ。
461NAME IS NULL:2010/09/27(月) 00:08:38 ID:HpHUNuXu
じゃなかった、質問しに来たんだ。

PKが二つあるテーブルで、WHERE句のサブクエリで
(hoge, moge) IN (SELECT homo, momo FROM xxx WHERE xxx.x1 = yyy.x2)

をやりたいのだけど、↑の記法が出来ない場合(H2Database)に一般的な方法ってどんなんがあります?
(hoge || moge) IN ・・がすぐ思いついたけど、ちょっとそりゃパフォーマンスわるいでそ!って感じなので。
462NAME IS NULL:2010/09/27(月) 00:35:54 ID:???
普通EXISTSだろ。
463NAME IS NULL:2010/09/27(月) 00:38:28 ID:???
俺なら普通にjoinしてからhoge=homo and moge=momoだな
from句以外にサブクエリ書くのはなんか格好悪い(exists除く)
464NAME IS NULL:2010/09/27(月) 00:54:39 ID:???
おうふ
たしかにそのとおりでござるな。
がんばって書き換えてみよう。

>>463
そもそも実際はこのSQLはSELECT句にあって入れ子になってたりするので
FROM句に移動するのはちょっと難しいというかパフォーマンスかなり悪くなるようで厳しかったりします。
465NAME IS NULL:2010/09/27(月) 10:44:10 ID:???
EXISTSかサブクエリの外で内部結合
466NAME IS NULL:2010/09/27(月) 16:12:58 ID:???
 テーブルを作るとき、キーにしにくいデータの場合は
オートナンバーを使ったほうがいいでしょうか?
それてもオートナンバーのような番号を自分で作って
キーにしたほうがいいでしょうか?
 データは削除や追加を頻繁に行う可能性があります。
467NAME IS NULL:2010/09/27(月) 20:12:51 ID:???
>>466
キーにしにくいデータっていうのは
きかない表現だけど、どういうこと
ですか?
468NAME IS NULL:2010/09/27(月) 20:25:17 ID:???
タイムスタンプを入れないとユニーク(主キー)にならない系かの??
469NAME IS NULL:2010/09/27(月) 21:14:21 ID:???
履歴とかログの類ならそうだね
普通にシーケンスやBIGSERIALを使えばおk
470NAME IS NULL:2010/09/28(火) 01:51:18 ID:???
追加、削除が頻繁に起こるってことはログ関連じゃないだろう。
代替キー(サロゲートキー)は複合キーをまとめるために使うこともあるから具体的に例を出してくれ。
471NAME IS NULL:2010/09/28(火) 11:52:20 ID:???
ぶっちゃけると予定表です。
重複というか交差してはいけないものが開始日時と終了日時くらいで
他の項目は重複するのが前提になっています。
逆にこういう設計がいいってのがあれば教えていただきたい。
472NAME IS NULL:2010/09/28(火) 12:30:06 ID:???
予定表であれば予定表に書き込む予定イベント毎にオートナンバー
等でユニークなIDを振った方が良いような。

>重複というか交差してはいけないものが開始日時と終了日時くらい

これが仕様として本当なのかもじっくり検討した方が良いと思う。
473NAME IS NULL:2010/09/28(火) 21:13:42 ID:???
・使用FB
derby 10.5

・テーブルデータ

受注表
----------------
顧客名 | 受注個数
----------------
あああ | 100
いいい | 200
ううう  | 100
えええ | 300

・欲しい結果
結果
------
顧客名
------
いいい
えええ

・説明
受注個数150以上の顧客名を取得
これを、ストアドプロシージャ使ってやりたいがストアドの作成、使用方法が分かりません。
手元にORACLEの資料がありとりあえず試してみるもderbyでは動作しなく、ネットを探し回ったのですが
手掛かりが見つからず手詰まり状態です。
分かる方大変お手数ですが、助けてください。
また、ココ読んどけ見たいなサイトあったら教えてください。
474NAME IS NULL:2010/09/29(水) 00:30:51 ID:???
まずDBをOracleにします
475NAME IS NULL:2010/10/01(金) 17:17:18 ID:???
>>472
やっぱりオートナンバー等を使ったほうがいいんですね。
その方向で検討して次のような疑問が出ました。

1、IDENTITYを使った場合、自動で割り振られた値をすぐに取得
する方法はあるでしょうか?
2、自分で割り振る場合
 select MAX(ID) + 1 from table
とするとデータが無い場合NULLが帰ってくるようですが
SQL内でNULLであれば特定の値を返すようにするにはどのように
書けばいいでしょうか?
(出来るようなら許容最大値の検出も考えています)
3、頻繁な追加と削除が考えられるので最終手段で番号の
再割り当てを用意したいのですがオートナンバー、もしくは自分で
割り振った番号を連番にするのにいい書き方はあるでしょうか。

>これが仕様として本当なのかもじっくり検討した方が良いと思う。
これは具体的にどのような問題が考えられるのでしょうか。
まだ検討中ですが、予定表としてそれでいいのかという事でしたら
そういう使用を考えています。
476NAME IS NULL:2010/10/01(金) 23:21:01 ID:???
477NAME IS NULL:2010/10/01(金) 23:21:46 ID:???
あ。スレ間違えた。SQL Server スレと勘違い。ごめんなさい・・・。
478NAME IS NULL:2010/10/03(日) 13:44:50 ID:???
1はDBによる。先にナンバーを予約してそれを使ってINSERtするケースもある。
2はCOALESCEを使う、、でいいのかな?
3は運用によるんじゃない?別テーブルでオートナンバーと連番管理してもいいし
479NAME IS NULL:2010/10/03(日) 18:17:09 ID:???
>>475
1.sqlserverならoutput句が便利。identityじゃなくても使える。
2.データが無い時ようにunion allでselect 1 を加える。許容最大値はsqlでやることじゃない。
3.再割り当てをする必要性は?オートナンバーは表にでない番号だから飛び番号でかまわないと思う。

472ではないけど予定がかぶっちゃいけないっておかしくね?
「予定」の定義にもよるだろうけどさ。
480475:2010/10/05(火) 16:05:47 ID:???
>>476-479
回答ありがとうございます。

1について
 @@IDENTITY があったんですね。変数っぽいのは関数内
だけかと思ってました。
outputは色々応用出来そうなのでoutputで検討しています

2について
 COALESCEのSQL Server用はISNULLのようでしたので
こちらを使わせていただきます。
unionは使ったこと無かったのですがこんな感じでしょうか?
select MAX(ID) + 1 from (select ID from table union all select 1)

3について
 確かに表に出さなくて連番も気にしていなかったのですが、
例えばintの最大値に近づいてきた時に連番に再割り当てして
新規に登録できる番号を増やす手段を用意しておいたほうが
いいのではと考えていました。
 ちなみにこのオートナンバーはそのテーブルのみで使用し
他のテーブルには影響しません。

また疑問が出たら書かせてもらいます。
ありがとうございました。
481NAME IS NULL:2010/10/06(水) 05:23:19 ID:???
intなら2,147,483,647、bigintなら9,223,372,036,854,775,807まで連番に使える。
うちの使い方じゃ困ったことはないな。
482NAME IS NULL:2010/10/07(木) 05:02:44 ID:???
intが枯渇する場面には割と出くわすとおもう。
bigintはまだぶつかったことないなw
483NAME IS NULL:2010/10/07(木) 19:09:16 ID:???
unsignedが指定できればさらに倍。
484NAME IS NULL:2010/10/07(木) 19:14:46 ID:???
はらたいらさんに3000点
485NAME IS NULL:2010/10/07(木) 22:39:44 ID:???
postgresqlです。副問合せの結果を2つの列の条件にするには
どうしたらよいでしょうか?

SELECT * FROM TABLE_A
WHERE [TABLE_Aの列1または列2] IN (SELECT ID FROM TABLE_B WHERE NAME LIKE '%あ')
486NAME IS NULL:2010/10/07(木) 23:38:06 ID:???
WHERE (SELECT ID FROM TABLE_B WHERE NAME LIKE '%あ') IN (TABLE_A.列1, TABLE_A.列2)
487NAME IS NULL:2010/10/08(金) 07:25:31 ID:???
>>486
ありがとう!
488NAME IS NULL:2010/10/08(金) 10:48:42 ID:???
updateのwhere in句でワイルカードを使いたいのですが、
mysqlで、 UPDATE table SET col='新しいデータ' where col in ('001古%', '003古%'.) としたのですが、
上手く出来ませんでした。

どうしたら出来るのでしょうか。
489NAME IS NULL:2010/10/08(金) 18:26:30 ID:???
where col like '001古%' or col like '003古%'
490NAME IS NULL:2010/10/12(火) 07:51:07 ID:???
SQLite3を使用しています。
select distinct(hoge)
でhogeのユニークな値一覧が取得できますが、
この結果の数を得る方法はないでしょうか?

よろしくお願いします。
491NAME IS NULL:2010/10/12(火) 09:30:56 ID:HeSOKsGB
SQLiteは使ってないから知らんけど

select count(distinct(stock_code))

は?
492491:2010/10/12(火) 09:31:44 ID:HeSOKsGB
ごめん 中のstock_codeは忘れてくれ w
493NAME IS NULL:2010/10/12(火) 12:26:11 ID:???
group byで項目を括って、そのレコード数をcount()で出しています。

select 項目,count(項目) from table group by 項目;

この時、count()の最大数のものが、幾つか出したいのですが、
maxなどを試しても上手くいきませんでした。

どうすれば、最大数だけを出せますか。
494NAME IS NULL:2010/10/12(火) 12:32:09 ID:???
日本語でOK
495NAME IS NULL:2010/10/12(火) 12:34:47 ID:???
having とかの話では?
496NAME IS NULL:2010/10/12(火) 12:52:46 ID:???
項目の値の集計値でなら、havingを使った事があるのですが、
この場合は、よく分かりません。

どうすればいいのか、教えて頂けないでしょうか。
497NAME IS NULL:2010/10/12(火) 13:23:10 ID:???
何がしたいのか、きちんと日本語で説明するなり、
例を挙げるなりしろ、ってことですよ。
498NAME IS NULL:2010/10/12(火) 13:27:09 ID:???
もしかして1位タイが何組あるかってこと?
499490:2010/10/12(火) 14:44:37 ID:???
>>491
それだと、何故か
near "distinct": syntax error
が出てしまいます。
500NAME IS NULL:2010/10/12(火) 15:13:57 ID:???
No-色
レコード1 001,赤
レコード2 002,赤
レコード3 003,青
レコード4 004,青
レコード5, 005,赤
レコード6, 006,黒

このデータで、 『select 色,count(色 from テーブル group by 色 』とした時
最大レコード数(この場合、赤の5)を取得したいのですが・・・
501NAME IS NULL:2010/10/12(火) 16:18:18 ID:???
赤の5ってことは、countが最大のものの中でレコード番号が最大のものってこと?
502NAME IS NULL:2010/10/12(火) 22:33:15 ID:8RPVSXuH
元データの日付(スケジュールとかログの日付)を全件検索するとします。
その時、「その時刻より後の18時」を取得(生成)するうまい方法はあるでしょうか。
言い換えると、日付の繰り上がりに対して小技があったら教えてください。

ターゲットデータベースはH2Databaseですが、「Oracleならこんな方法が(ry」とかでも
勉強になりますのでお願いします。

元データ
-------------------
2010-10-01 01:00:00
2010-10-03 17:00:00
2010-10-04 20:00:00
-------------------

欲しいデータ
-------------------
2010-10-01 01:00:00 2010-10-01 18:00:00
2010-10-03 17:00:00 2010-10-03 18:00:00
2010-10-04 20:00:00 2010-10-05 18:00:00
-------------------
503NAME IS NULL:2010/10/12(火) 22:39:22 ID:???
時刻だけ取り出して、18時より小さかったら18時に。大きかったら
+1日して18時にすればいい。
504NAME IS NULL:2010/10/12(火) 22:59:44 ID:???
とりあえず6時間足す → 日付単位にtrunc → 18時間足す
でいいんじゃね?
505NAME IS NULL:2010/10/13(水) 20:43:11 ID:???
>>502
原理的には、時刻を取り出し、
(対象時刻 - 元データ時刻 + 24時間)/ 24時間の剰余を計算し、元データに足す。

例示されたデータの場合
mod((18時 - 01時 + 24時), 24時) = +17時間
mod((18時 - 17時 + 24時), 24時) = +01時間
mod((18時 - 20時 + 24時), 24時) = +22時間

ただし、時刻間の剰余を求めることはできなさそうなので、時刻 <-> 数値に変換する関数を用意する必要はありそう。
506NAME IS NULL:2010/10/13(水) 23:43:46 ID:???
>>503-505
ありがとう。大変参考になりました。やはり基本は腕力演算ですかね・・。
なんとか効率よい方法を探ってみます。
507NAME IS NULL:2010/10/14(木) 07:01:46 ID:???
日付に+18時して元データと比較の結果で、+1日するかしないか決めればいい
508NAME IS NULL:2010/10/16(土) 15:23:52 ID:???
http://www.dotup.org/uploda/www.dotup.org1202425.jpg
これQ1,2,3の答えおかしいですか?
あとQ4の答え教えて頂けないでしょうか
509NAME IS NULL:2010/10/16(土) 15:57:28 ID:???
>>508
Q1〜Q3合ってる。Q4 150。
宿題は自分でやろう。これくらいのテーブル自分でCREATEして確認すればいいじゃん。大学生かい。
510NAME IS NULL:2010/10/16(土) 20:16:39 ID:???
ありがとうございます
どうでもいい話でしょうがこういった知識はほぼ0に等しく
1からググって解いていったのですがQ4,150を入力しても正解にならなかったので
詳しい知人もいませんしこちらで質問させてもらいました
問題側がおかしかったんですね
511NAME IS NULL:2010/10/17(日) 14:09:47 ID:???
ググって解いて身に付くもんなのか?
512NAME IS NULL:2010/10/28(木) 20:37:12 ID:q6JO7OhN
いまどきのオプティマイザなら、

・WHERE hoge = 999
・WHERE hoge IN ( 999 ) -- INを使ってるくせに値が1個

は同じ速度で検索してくれますか?
ちなみにMySql5です。
513NAME IS NULL:2010/10/28(木) 21:38:04 ID:???
知らん。実行計画見れ
514NAME IS NULL:2010/11/02(火) 04:49:23 ID:SseX3HDC
「10機の赤い飛行機」「赤い飛行機」「白い飛行機」「飛行機が黄色い」「飛行機の音」という5項目があるとして
前者4つは「飛行機」というキーワードで検索できるようにしたいです
LIKE検索だと5つめもかかってしまうのですが
こういう場合は検索用のテーブルを作るべきなのでしょうか?
あと「10機の赤い飛行機」の他にも「●機の赤い飛行機」も同様に「飛行機」というキーワードにしたいのですが
その場合検索用テーブルにいちいち1機からx機まで書くわけにもいかないですが
こういう場合はどうしたらいいのでしょうか?
515NAME IS NULL:2010/11/02(火) 05:26:15 ID:???
like '%飛行機'
516NAME IS NULL:2010/11/02(火) 06:59:02 ID:???
>>515だと4つめがひっかからない
>>514は主語(?)としての「飛行機」を検索したいってことなのかな?
だとしたら自然言語処理をストアドで組むしかないんじゃないだろうか
517NAME IS NULL:2010/11/02(火) 07:03:32 ID:???
SQLの出る幕じゃないな。
518NAME IS NULL:2010/11/02(火) 07:17:07 ID:???
「飛行機が黄色い」とか「飛行機が黄色い飛行場」とかは?
SQLじゃ厳しいし、アプリ内で単純に形態素解析ライブラリ使うとかだけじゃ解決しないねぇ。
519NAME IS NULL:2010/11/02(火) 07:47:00 ID:0+zwsUdT
LIKE '%い飛行機'
520514:2010/11/02(火) 08:53:15 ID:???
みなさんレスありがとうございます
簡単にできるのかな?と思ってたら考えが甘かったようですね
よくわからないことだらけでてんぱってますが
なんとかアプリ側で実装するよう頑張ってみます
521NAME IS NULL:2010/11/02(火) 10:50:02 ID:???
複数のLIKEをAND/OR/NOTでつないで見る程度じゃだめなのかな
522NAME IS NULL:2010/11/02(火) 14:02:50 ID:???
別途キーワードだけを格納するテーブル(かカラム)を用意するのが簡単じゃないかな
まあ、キーワードをどうやって選定するかって問題は残るが
523490:2010/11/02(火) 14:40:15 ID:???
SQLite2を使用していたようです。。
3に変更したところ、count(distinct(hoge))が使えました。
一応報告です。
524NAME IS NULL:2010/11/02(火) 18:23:19 ID:???
ハハハ
和む
525NAME IS NULL:2010/11/02(火) 18:23:47 ID:???
>>519
直感的に嫌な感じ
526NAME IS NULL:2010/11/02(火) 23:23:38 ID:???
~ '[^音]*飛行機[^音]*';
527NAME IS NULL:2010/11/03(水) 00:49:15 ID:???
>>514の言う「前者4つ」と「5つめ」は何が違うのかがわからない
528NAME IS NULL:2010/11/03(水) 03:51:40 ID:S1vOLRbk
Webアプリケーションで使う仮登録テーブルと本登録テーブルがあります
仮登録テーブルは誰でもINSERTできるようになっていて
仮登録テーブルに内容があった場合
本登録するスクリプトを数時間おきに叩くようなシステムになっています

ここで仮登録テーブルは複数人がINSERTのみを行う(DELETEやUPDATEは行わない)
本登録テーブルはスクリプトが数時間おきに仮登録テーブルの内容をINSERTをする
本登録テーブルの内容に不備があった場合管理スクリプトからDELETEやUPDATEを行えることになっています

こういう場合どちらともトランザクション処理は必要でしょうか?
529528:2010/11/03(水) 03:56:34 ID:???
すみません一応補足しておきます

仮登録テーブルは本登録テーブルに内容をうつした後
仮登録テーブルの内容はすべてDELETEされます
530NAME IS NULL:2010/11/03(水) 07:05:42 ID:???
それ、SQLの質問と違うやん。
531NAME IS NULL:2010/11/03(水) 16:42:49 ID:???
ACCESS SQLで以下のような処理はできるでしょうか?
(VBAの機能等を含めないSQLの処理結果のみで)

【テーブル】
Tくだもの(名前, 名前)
Tアンケート(名前, 評価) ←評価には1〜5の数値が入る

【結果】
みかん, 1, 3, 5, 3, 4, ... (以降アンケートの数だけ続く)
532NAME IS NULL:2010/11/03(水) 17:02:34 ID:???
533NAME IS NULL:2010/11/03(水) 17:04:34 ID:???
>>529
普通に考えて、本登録するスクリプトは1トランザクションで処理すべきだろう

微妙にトランザクションを勘違いしてる気がするんだが
お前の言うどちらともの、どちらって、何と何を指してるんだ?

534NAME IS NULL:2010/11/03(水) 17:10:21 ID:???
>>528
トランザクションは一連の処理をひとまとまりで不可分なものとしたいときに使う。
例えば一連の処理が終わるまで対象データを他のトランザクションから
変更できなくしたいとか、途中で処理が失敗したらまとめてROLLBACKしたいとか。
535528:2010/11/03(水) 17:45:10 ID:???
レスありがとうございます
トランザクションを微妙に勘違いしてるというのはそうなのかもしれません
処理をひとまとまりというのはなんとなく理解しているのですが
トランザクション処理とデッドロックのテーマをよく取り扱っているので
(副次的効果で?)更新中に他の人は更新できないようにロックする処理みたいな認識でした
仮登録テーブルから本登録テーブルにデータを移行して仮登録テーブルからデータを削除する
というのが1トランザクションだと思うのですが
この間に他者が仮登録テーブルに登録できないようにするにはトランザクションを使うのかなと思いました
データベースはMySQLを使っていてトランザクション処理はInnoDBにする必要があるみたいなので
どちらのテーブル(あるいは両方)をInnoDBにする必要があるのか悩んで質問しました
536NAME IS NULL:2010/11/03(水) 17:45:45 ID:???
スレ違いだからさっさと消えてなくなれよ
537NAME IS NULL:2010/11/03(水) 17:48:01 ID:???
こんな過疎スレでスレ違いがどうのわめくやつって一体・・・
538NAME IS NULL:2010/11/03(水) 18:09:14 ID:3Da48fOF
過疎であることとスレ違いが許容されることの関係を解説希望
539NAME IS NULL:2010/11/03(水) 18:18:48 ID:???
過疎スレ自治お疲れ様です^^;
540NAME IS NULL:2010/11/03(水) 18:53:00 ID:???
>>532
ありがとうございます
どうやらこのスレでも過去似たような質問が何度かあったようで

MySQLだとGROUP_CONCATというのがあって簡単にできるらしいので
エクスポートして試してみます
541NAME IS NULL:2010/11/03(水) 18:57:01 ID:???
Accessならクロス集計で何とかならん?
542NAME IS NULL:2010/11/03(水) 21:52:23 ID:???
H2Databaseにもあってすげー助かった>GROUP_CONCAT
他DBにも採用されてるのかな。
543NAME IS NULL:2010/11/04(木) 03:15:57 ID:T5HL3QI9
NULLの扱いが難しすぎるんだけど、
なんかいい方法ないの?

(1) trim(' ') = trim('a') → false(null)
(2) trim(' ') = trim(' ') → false(null)
(3) null = trim(' ') → false(null)

少なくとも(2)(3)はtrueで評価してくれないと、
バグの温床になりかねん。
544NAME IS NULL:2010/11/04(木) 05:54:16 ID:???
null は = で比較できない。
545NAME IS NULL:2010/11/04(木) 06:03:54 ID:???
DBはなんだ。Oracleか?
546NAME IS NULL:2010/11/04(木) 06:16:04 ID:???
>>543
DBの種類も書かんといきなり関数書かれてもな...
トリム結果が空文字列ならNULL返すって前提か?

NULLと何かの比較が真になるようではNULLの意味がないんだがな
扱いが難しいのはまあしょうがない。ちゃんと理解して扱えとしか

1と2は空文字列とNULLを区別しないDBMSが悪い(たぶんORACLEなんだろうけど)
3は真でも偽でもない。falseとNULLは違うってことから理解しなおせ
(1と2も結果的にNULL=NULLの比較だから結果は不定だがな)
547NAME IS NULL:2010/11/04(木) 22:42:18 ID:???
3値論理だからな
ところで
TRUE:真,FALSE:偽だけどNULLを感じ文字で表すなら何が適当なのだろうか
不(定)?未(定義)?
548NAME IS NULL:2010/11/04(木) 23:02:28 ID:???
549NAME IS NULL:2010/11/04(木) 23:08:03 ID:???
仏教的には「空」だな。
まあ仏教は関係ないけど。
550NAME IS NULL:2010/11/04(木) 23:24:46 ID:???
「未知(unknown)」の場合と「適用不能(not applicable)」の場合があるから
漢字一字じゃ無理でしょ
551NAME IS NULL:2010/11/05(金) 00:16:42 ID:???
それを言ったら、それを"NULL"と表していること自体に無理があるわけで。
アルファベット4文字で表すのは可能だけど漢字1文字は無理、ってことはないだろう。
552NAME IS NULL:2010/11/05(金) 00:23:37 ID:???
T、F、Nの3値でいいでしょ。
553NAME IS NULL:2010/11/05(金) 01:13:31 ID:???
554NAME IS NULL:2010/11/05(金) 01:39:06 ID:???
もう禅の話ですか
555NAME IS NULL:2010/11/05(金) 01:49:22 ID:???
膳々
556NAME IS NULL:2010/11/05(金) 15:44:09 ID:nrM4M2fD
sqlite3ですの

id 1 name 伊藤 age 23
id 2 name 田中 age 24
id 3 name 山田 age 33
id 4 name 桜庭 age 43
id 5 name 中村 age 23
を「age」の数値が多い順にソートしたいんですが良い方法ありますか?
あと「伊藤」と「中村」は「age」が一緒なんですけど
その場合はどうなりますか?
557NAME IS NULL:2010/11/05(金) 16:31:59 ID:???
sqliteを俺は知らんけど、order by 使えないの?
558NAME IS NULL:2010/11/05(金) 18:16:54 ID:???
TRUE:真,FALSE:偽,NULL:ぽ
でいいよ
559NAME IS NULL:2010/11/05(金) 18:31:06 ID:ElB5Tk2d
sqlitemanager使ってるんですが 調子わるい

文字コードいじりやすいやつで他にいいソフトありますか?
560NAME IS NULL:2010/11/05(金) 18:50:06 ID:???
Python+wxあたりで簡単に自作できそうだけどな
561NAME IS NULL:2010/11/05(金) 20:14:04 ID:???
NULLは無だと思ってました
562NAME IS NULL:2010/11/05(金) 20:33:38 ID:???
検索したい文字列より検索キーワードが多いけどだいたいあってるからHITさせたいみたいなことは可能ですか?
例えば「にしむらひろゆき」という文字列にたいしてLIKEで'%ひろゆき%'はHITしますが、
「2ちゃんねる元管理人にしむらひろゆきさん」というキーワードで
この「にしむらひろゆき」にSQLだけでHITさせることは可能でしょうか?
563NAME IS NULL:2010/11/05(金) 20:55:34 ID:???
where '2ちゃんねる元管理人にしむらひろゆきさん' like '%' || col_name || '%'
でいけるDBMSならいける
564562:2010/11/05(金) 21:10:30 ID:???
>>563
ありがとうございます
試してみたところ無理だったのでMySQLではだめなようですね
結構無茶ぶりのつもりでしたができるDBMSもあるということに感動しました
565NAME IS NULL:2010/11/06(土) 08:11:30 ID:???
MySQLでもできたよ
||じゃなくconcatを使う。あんまMySQL詳しくないけど||は効かないんじゃね

wordというカラムに'ひろゆき', '管理人', 'aaaaaaa'ってのを入れて

select * from word_table where '2ちゃんねる元管理人にしむらひろゆきさん' like concat('%', word, '%');

で二行引っ掛かる。
566NAME IS NULL:2010/11/06(土) 08:54:50 ID:???
Olacleで、以下の<Table1>と<Table2>から<Table3>を作り出すSQLは
どのように記述できますでしょうか?ご教示願います。

<Table1>
製品コード     部品コード
XXXX A
YYYY B
ZZZZ C1

<Table2>
部品コード      部品
A A1
A A2
B B1
B B2

<Table3>
製品コード      部品
XXXX A1
XXXX A2
YYYY B1
YYYY B2
ZZZZ C1
567NAME IS NULL:2010/11/06(土) 08:57:35 ID:???
文字が詰まって見えるので再投稿します。
Olacleで、以下の<Table1>と<Table2>から<Table3>を作り出すSQLは
どのように記述できますでしょうか?ご教示願います。

<Table1>
製品コード   部品コード
XXXX      A
YYYY      B
ZZZZ      C1

<Table2>
部品コード   部品
A        A1
A        A2
B        B1
B        B2

<Table3>
製品コード   部品
XXXX      A1
XXXX      A2
YYYY      B1
YYYY      B2
ZZZZ      C1
568NAME IS NULL:2010/11/06(土) 08:59:18 ID:???
Left Join
569NAME IS NULL:2010/11/06(土) 09:32:44 ID:???
select T1.製品コード,
    coalesce(T2.部品, T1.部品コード) as 部品
from  Table1 as T1
    left outer join
    Table2 as T2
    on T1.部品コード = T2.部品コード
;
570NAME IS NULL:2010/11/06(土) 13:39:12 ID:???
>>569

実行できました! ありがとうございます。
571NAME IS NULL:2010/11/06(土) 14:29:42 ID:???
SQLite3 です。

a-1 b-2 a-2 b-10 a-10 b-9

a-1 a-2 a-10 b-2 b-9 b-10
になるようにソートする方法はありますか?
ハイフンの後ろは必ず数値なんですが、
a や b の部分の文字数は不定です。
572NAME IS NULL:2010/11/06(土) 17:09:36 ID:shC/G7aL
sqlite3です、PHPを使ってやりたいんですが、

データにある、ある項目が引用されたとき、
そのデータにあるcntというカラムにカウンターみたいなのを付けたいんですが
何か良い方法はありますか?
http://oku.edu.mie-u.ac.jp/~okumura/php/counter-sqlite.php
それっぽいのがあったんですけど 複数のcnt[カラム]ごとに取得したいんですよね
573NAME IS NULL:2010/11/06(土) 19:16:37 ID:???
「複数のcnt[カラム]ごと」のところが言ってることがいまいちわからないが・・・

検索履歴を保持したいなら検索履歴テーブルでも別に作って貯めていく方が普通じゃね。
データのあるテーブルにカラムを追加する実装はない。

検索履歴テーブルへのINSERTは、SELECTの直前での履歴INSERTの作り込みか、
あるいは(sqlite3で出来るかは知らないが)、トリガーを使う。
574NAME IS NULL:2010/11/06(土) 23:15:46 ID:???
>>571
調べたところInstr系もSplit系もないから標準じゃ無理かな。
素直にカラムを分けることを薦めるができないからここで聞いてるんだよね。

ttp://g.e-hentai.org/g/274568/4f041be089/
ここにある正規表現をつかってサブクエリ内で2つのカラムに分割すればいいのかな。
SQLite3でサブクエリ作れたかは知らん。
575NAME IS NULL:2010/11/06(土) 23:18:01 ID:???
>>572
こういうこと?

SELECT COUNT(col1), COUNT(cnt2) FROM Table GROUP BY col1,col2
576562:2010/11/06(土) 23:23:16 ID:???
>>565
遅レスですがありがとう!
これでだいぶ実装が楽になってがんがん先にすすめます
ほんとうれしいわー
577NAME IS NULL:2010/11/07(日) 01:06:22 ID:???
>>571
http://www.sqlite.org/lang.html
の「core functions」(http://www.sqlite.org/lang_corefunc.html)にある
trim(X),trim(X,Y),rtrim(X),rtrim(X,Y)
をorderby句でつかえばなんとかなりそう

もしくは
http://www.sqlite.org/c3ref/create_function.html
にあるように独自のソート関数をc言語で実装する方法もある
ただこの時の注意事項は
An application-defined function is permitted to call other SQLite interfaces.
However, such calls must not close the database connection nor finalize or reset the prepared statement in which the function is running.
578NAME IS NULL:2010/11/07(日) 14:39:01 ID:???
rtrim(x,y)なんてあるのか
579NAME IS NULL:2010/11/08(月) 01:37:13 ID:???
>>574
はい、カラムを分けずに実現したいです。。
URL が不明ですが、SQLite で正規表現が使えるんですか?

>>577
ltrim(ltrim(ltrim(ltrim(col,'a'),'b'),'c'), ... '-') とかでしょうか。
でもこれだと abab-1 などの時、最初の ab しか消えませんよね。
あと TEXT 型なので、単純にハイフンの右側でソートするだけでは
'10' < '2' なので上手くいきません。。

やはり無理がありますよね。ありがとうございました。
580NAME IS NULL:2010/11/08(月) 02:14:16 ID:???
リンク先をよく読んだわけじゃないから間違ってるかもしれんが
「ltrim(X,Y)」は「Y」にあらわれる文字の一部または全てを左端から除いた文字列を返すらしいし
「abs」を使えば文字列を数値化できるから(詳細はリンク先参照)
abs(ltrim(col, 'abc-'))
でいけるんじゃないか?
581NAME IS NULL:2010/11/08(月) 04:04:37 ID:???
>>580
trim の使い方を勘違いしてました。。
abs で数値化も勉強になります。
ハイフンの左側には数字も出現するので、最終的にこんな order by 句になりました。これで勝つる。
rtrim(col, '0123456789'), abs(ltrim(lower(col), 'abcdefghijklmnopqrstuvwxyz0123456789'))
582NAME IS NULL:2010/11/08(月) 06:51:16 ID:h0nca0n6
すいません、全フィールドに(2語の検索語でANDもしくはORで)検索をかけたい場合
どうかくのでしょうか?mysql でPHP で書いています。
(2語をANDで検索したい場合)
SELECT * FROM table WHERE name LIKE '%$word1%' AND name LIKE '%$word2%'
SELECT * FROM table WHERE address LIKE '%$word1%' AND address LIKE '%$word2%'
SELECT * FROM table WHERE tel LIKE '%$word1%' AND tel LIKE '%$word2%'
           ・
           ・

みたいに全フィールド分並べるとダブりがあるし
SELECT * FROM table WHERE * LIKE '%$word1%' AND * LIKE '%$word2%'
とやったら怒られました
583NAME IS NULL:2010/11/08(月) 06:59:36 ID:???
UNION
584NAME IS NULL:2010/11/08(月) 07:15:23 ID:h0nca0n6
おお、早朝から早速どうもです、ありがとうございます
UNIONで上手くいってるようです

やっぱ全部のフィールド分は書かないとダメなんですね
585NAME IS NULL:2010/11/08(月) 18:51:43 ID:???
WHERE (a AND b) OR (c AND d) OR ...
みたいな書き方はできないの?
586NAME IS NULL:2010/11/08(月) 19:44:49 ID:cV+BOk7+
UNIONのが早いからUNIONにする
587NAME IS NULL:2010/11/09(火) 00:39:27 ID:???
下のようなカラムがあるのですが、value1〜3に1回でも出てくる値を
重複なく取得したいのですが、うまくSQLで書けるものでしょうか。
key, value1, valu2, value3(value1〜3は任意の文字列)

たとえば、3個のレコード
1, AAA, BBB, CCC
2, DDD, AAA, CCC
3, EEE, FFF, AAA
があった場合、AAA, BBB, CCC, DDD, EEE, FFFを出力したいです。
588NAME IS NULL:2010/11/09(火) 00:45:50 ID:???
>>587
SELECT value1 FROM Table
UNION
SELECT value2 FROM Table
UNION
SELECT value3 FROM Table;
589NAME IS NULL:2010/11/09(火) 01:03:36 ID:???
>>588
ありがとうございます。
UNIONは個人的に馴染みがなく、忘れていました。
確かに、ほとんどUNIONの定義そのままですね・・
590NAME IS NULL:2010/11/09(火) 18:04:38 ID:is9svjYB
似たような質問なんですが
すべてのカラムに対してそれぞれではなく、複数まとめて検索したい場合は
どうするのでしょうか?

イメージ的には複数のフィールドを取り出してくっつけて1文にして
それにXXX and YYY で検索する感じです

実はすごく簡単なような気もするんですが
全部取り出してくっつけたものを、この検索のためのフィールドに入れておく
くらいしか思いつきません

name address   tel   ・・・・
------------------------------
itouYYY XXXZZZ 0123-4567
itouZZZ YYYYFF 1234-0123
hanaXXX LLLZZZ XXXX-XXXX

で、(itouYYY XXXZZZ 0123-4567 …)が欲しい
591NAME IS NULL:2010/11/09(火) 20:35:00 ID:hV+oLYCU
>>590
何も考えずに項目毎にandで結べばいいだろ

where 項目A = 'xxx'
and 項目B = 'yyy'
and 項目C = 'zzz'


それともこういう話か

(項目A,項目B,項目C) = ((値1,値2,値3),(値4,値5,値6))

そいうのができるDBもあるぞ





592NAME IS NULL:2010/11/09(火) 21:13:57 ID:is9svjYB
ええと、たとえば名前の苗字と住所の一部が分かってるときとかに検索したい時に
神奈川在住の千葉さんだとして

名前から「千葉」、住所から「神奈川」とやらなくても
複数のフィールドに「千葉、神奈川」がある人を見つけたいんです
全文検索みたいな感じでしょうか
この例だと、千葉と神奈川をひっくり返して試せばいいだけですが
本当は項目がもっと多いので
593NAME IS NULL:2010/11/09(火) 21:15:04 ID:???
SQLに向いてない。
594NAME IS NULL:2010/11/09(火) 23:02:37 ID:???
>>592
複数のフィールドを連結して、正規表現で検索とか。
時間はかかるだろうけどね。
595NAME IS NULL:2010/11/09(火) 23:24:35 ID:is9svjYB
うーん、してみると
取り出して1文にしてstrstrしちゃったほうが早いすかね?
596NAME IS NULL:2010/11/10(水) 22:01:00 ID:???
・SQL Server 2008

行 | 品名 | 個数
--+-----+----
1 | 商品1 |  2
2 | 商品2 |  1
3 | 商品3 |  1
4 | 商品4 |  5

上記のようなテーブルがあるんだけど、下記のように個数の累計を取得したいです

行 | 品名 | 個数 | 累計
--+-----+---- +-----
1 | 商品1 |  2  |  2
2 | 商品2 |  1  |  3
3 | 商品3 |  1  |  4
4 | 商品4 |  5  |  9

SUM使ってCASEでわけて合計すればよさげだけどうまく書けません
教えてください
597NAME IS NULL:2010/11/10(水) 22:12:15 ID:???
自分と同じか、小さい行の個数をSumすればいいな。
598NAME IS NULL:2010/11/10(水) 22:34:41 ID:tSI0e5gG
_>>597
やりたいことはそのとおりわかってるんだけど、どう書けばいいかわからないのです
考えてたのは
1.
SUM(CASE WHEN 行<=行 THEN 個数 )ELSE 0 END

2.
SELECT *
FROM
(
 SELECT *,
      累計=SUM(個数)
 FROM Table
 WHERE 行<=行
) X

難しいです
599NAME IS NULL:2010/11/10(水) 22:46:57 ID:???
select 行, 品名, 個数, (select sum(個数) from table where 行 <= t2.行) as 累計
from table t2

とかじゃダメ?
600596:2010/11/10(水) 23:09:51 ID:???
>>599
自分の行とテーブル全体の行を比べるにはそういう書き方があるんですね
勉強になります
いま実行環境がないのですが、明日確認できればまた御礼にきます
601NAME IS NULL:2010/11/11(木) 00:43:26 ID:???
間違ってたらお礼言わない気かよw
602596:2010/11/13(土) 07:14:10 ID:???
遅くなりましたがうまくできました
みなさんありがとうございます
603NAME IS NULL:2010/11/14(日) 00:33:12 ID:???
サーバにSQLiteファイルアップロード
ローカルでSQLiteファイル更新(INSERTでレコード追加)
としたとき、SQLファイルはリジュームアップロード可能でしょうか?
それとも一からアップロードし直すことになるのでしょうか?
604NAME IS NULL:2010/11/14(日) 08:42:02 ID:???
スレ違い。
605NAME IS NULL:2010/11/14(日) 20:17:14 ID:W9EfAQ77
案内くらいしてやってもいいじゃないか
SQLite 8
http://hibari.2ch.net/test/read.cgi/db/1250225486/
606NAME IS NULL:2010/11/14(日) 22:34:55 ID:???
ありがとうございます。移動します。
607NAME IS NULL:2010/11/15(月) 03:53:49 ID:???
MySQLServer5.1(WinXP)です。

下記のような3種類のテーブルがあります。
これを集計して、指定したユーザーの指定月のアクセス日時と売上げ金額を表にしたいと思っています。

こんな感じに。

+--+--------+----------+-------+-----+
| id | username| date   | access | sales |
+--+--------+----------+-------+-----+
| 1 | admin | 2010-11-13 |   2 | 5000 |
| 1 | admin | 2010-11-14 |   2 | 5000 |
| 1 | admin | 2010-11-15 |  1 | 20000 |
+--+--------+----------+-------+-----+


SELECT u.id AS id, u.username, DATE(a.created_at) AS date, COUNT(*) AS access, SUM(s.amount) AS sales
FROM sf_guard_user u INNER JOIN sales s ON u.username = s.user_id LEFT JOIN access_log a ON u.username = a.user_id
WHERE (u.username = 'admin' AND a.created_at > '2010-11-01 00:00:00' AND a.created_at < '2010-11-30 23:59:59') GROUP BY date ORDER BY a.created_at;
とやってみたのですがダメでした;;


■ユーザー情報テーブル
mysql> select id,username from user;
+--+---------+
| id | username |
+--+---------+
| 1 | admin   |
+--+---------+

■アクセスログテーブル
mysql> select * from access_log;
+--+-------+--------+------------------+
| id | user_id | ip     | created_at      |
+--+-------+--------+------------------+
| 1 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 |
| 2 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 |
| 3 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 |
| 4 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 |
| 5 | admin  | 127.0.0.1 | 2010-11-15 21:56:54 |
+--+-------+--------+------------------+

■売上げ金額テーブル
mysql> select * from sales;
+--+-------+------+------------------+
| id | user_id | amount| created_at      |
+--+-------+------+------------------+
| 1 | admin  |  5000 | 2010-11-13 21:56:54 |
| 2 | admin  |  5000 | 2010-11-14 21:56:54 |
| 3 | admin  |  5000 | 2010-11-15 21:56:54 |
| 4 | admin  |  5000 | 2010-11-15 21:56:54 |
+--+-------+------+------------------+
608NAME IS NULL:2010/11/15(月) 06:13:15 ID:???
GROUP BY u.id, u.username, DATE(a.created_at)
にすればいいだけじゃないの?
609NAME IS NULL:2010/11/15(月) 11:52:34 ID:???
u.id, DATE(a.created_at)
でいいとおもう
610NAME IS NULL:2010/11/15(月) 11:54:09 ID:???
ごめん追記。
アクセス、売り上げの無い日付があったときにどう表示するかでも変わってくるので
「ダメでした」の内容をお願いします。
611607:2010/11/15(月) 16:26:25 ID:S1UCx8kr
ダメだったときの結果は以下のような感じです。
書いてなかったですが、アクセス数や売上げの無い日もありえます。
無い場合はnullでも0でも構いません。
+---+--------+------------+-------+-------+
| id|username|  date  | access| sales |
+---+--------+------------+-------+-------+
| 1 | admin | 2010-11-13 | 10  | 50000 |
| 1 | admin | 2010-11-14 | 10  | 50000 |
| 1 | admin | 2010-11-15 | 5  | 25000 |
+---+--------+------------+-------+-------+
612NAME IS NULL:2010/11/15(月) 19:18:41 ID:???
アクセスログの結合条件に日時も加えないとダメだろう
LEFT JOIN
access_log a
ON u.username = a.user_id
AND s.created_at = a.created_at
613NAME IS NULL:2010/11/15(月) 19:28:52 ID:???
と思ったけどやっぱ別々に集計しなきゃダメだな
SELECT u.id,
    u.username,
    s.date,
    a.access,
    s.sales
FROM  sf_guard_user u
    INNER JOIN
    (SELECT user_id,
        DATE(created_at) AS date,
        SUM(amount) AS sales
     FROM  sales
     GROUP BY user_id, DATE(created_at)) s
    ON u.username = s.user_id
    LEFT JOIN
    (SELECT user_id,
        DATE(created_at) AS date,
        count(*) AS access
     FROM  access_log
     GROUP BY user_id, DATE(created_at)) a
    ON u.username = a.user_id
    AND s.date = a.date
WHERE  u.username = 'admin'
AND   s.date > '2010-11-01 00:00:00'
AND   s.date < '2010-12-01 00:00:00'
ORDER BY s.date
;
614NAME IS NULL:2010/11/15(月) 20:29:44 ID:???
ああ、ほんとだ。
別々に集計しないとだめね。
適当なレスしてすまんかった。

結合は全部left outerがいいとおもう。
売り上げないけどアクセスあった日、またその逆を出す為に。
615NAME IS NULL:2010/11/15(月) 20:31:02 ID:???
あ、日付テーブルのようなものがいるのでは。
616607:2010/11/15(月) 20:31:28 ID:S1UCx8kr
うわぁ。。。こんな複雑なSQL、自分じゃ思いつかないです><
でもエラーになっちゃいました。。。

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'SELEC
T u.id,
    u.username,
    s.date,
    a.access,
    s.sa' at line 1
617607:2010/11/15(月) 20:43:06 ID:S1UCx8kr
あ、全角スペースが原因だったみたいです。。
半角に直してもまだエラーでちゃいますけど。。

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '(SELE
CT user_id,
DATE(created_at) AS date,
SUM(amount) AS sales
FROM sales
GROUP' at line 8
618607:2010/11/15(月) 20:47:41 ID:S1UCx8kr
LEFT OUTER って、LEFT OUTER JOINのことだったんですね^^;
修正したらうまくいきました!!
感謝です。
619NAME IS NULL:2010/11/15(月) 20:47:46 ID:???
ダラダラと長いだけで複雑なわけじゃないから頑張って嫁としか
620NAME IS NULL:2010/11/15(月) 20:54:17 ID:???
くだ質で申し訳ない

SQLite3で、textの1カラムしかないレコードがずらずらと続いているテーブル
のn行目からm件のレコードを取得するにはどうSQLに書き下せばいいんでしょうか?

select * from table limit (n+m); で目的範囲の末までは取得できるのですが、で
きればDBの処理で最初のnレコードも省きたいです。
621NAME IS NULL:2010/11/15(月) 21:11:44 ID:???
つ offset

てかそんなテーブル、RDBMSというものの意味を全く分かってないな
order byをつけないと順序は保証されないよ
622NAME IS NULL:2010/11/15(月) 21:14:18 ID:???
ですよねー(泣

offsetはこいつですね↓。キーワード分からず袋小路してました。
ttp://www.dbonline.jp/sqlite/select/index10.html

ありがとうございました。
623NAME IS NULL:2010/11/15(月) 23:26:41 ID:???
使い道が無いわけでは無いと思うけどね。
キーワード一覧とか。
624NAME IS NULL:2010/11/15(月) 23:36:18 ID:???
いや、IDもタイムスタンプもないんじゃダメだろ・・。
625NAME IS NULL:2010/11/16(火) 02:01:44 ID:???
そうかねぇ。
select * from access_log where exists(
select * from ignore_ip_addresses where access_log.client_ip = ignore_ip_addresses
)
とか。無視リストにIDやタイムスタンプがあったらどうなるの?
626NAME IS NULL:2010/11/16(火) 02:05:42 ID:???
なんか既視感が、とおもったら、>>565がそんな感じにもなれる、けど、IDとタイムスタンプがあるとどうなるの?
627NAME IS NULL:2010/11/18(木) 00:27:52 ID:???
mysql 5.0 (windows 7)です
下記のようなテーブルで
amountの合計の最も多いidを取得するsql文がわかりません…

select id, sum(amount) as "total" from orders
group by id order by total desc limit 1;

とすれば一応取得できたのですが、別の方法はないでしょうか
初歩的な質問ですみません…

+------+------+--------+
| id | name | amount |
+------+------+--------+
| 1 | C1 | 3 |
| 1 | C2 | 10 |
| 2 | C2 | 5 |
| 2 | C3 | 10 |
| 3 | C3 | 2 |
+------+------+--------+
628NAME IS NULL:2010/11/18(木) 05:43:01 ID:???
>>627
動いてるならそれでいいと思うが、別の方法というなら
mysqlで動くかどうかわからんが

select id from orders group by id having sum(amount)=(
select max(total) from (select sum(amount) as total from orders group by id) t
)
みたいなSQLを書いてみた
629NAME IS NULL:2010/11/19(金) 00:17:58 ID:???
>>628
ありがとうございます。無事動きました
私もSQLをもう少し勉強します。
630NAME IS NULL:2010/11/19(金) 00:41:17 ID:???
SQLSERVER2005を使用しています。
次のようなストアドを作成しています。

procedure A
@No int
delete from TABLE where No = @No
insert into TABLE values (@No, a, b, c)

※TABLEのPKEYは@No

@Noに同一値が指定されるケースもあります。
ここでprocedureAがマルチで短時間に何回も実行される場合、タイミングによってはinsertでキー重複が発生します。

procedureの実行中はテーブルロックをかけたいのですが、何か良い方法はありますか?
631NAME IS NULL:2010/11/19(金) 00:55:02 ID:???
トランザクションかければいいだけじゃね?
632NAME IS NULL:2010/11/19(金) 02:42:05 ID:???
>>630
微妙にスレ違いな気もするけど
テーブルロックかけたければかければ良いんじゃね
やり方はMSDN読むなりググルなりすればわかるでしょ

つかまずトランザクションと分離レベルについて勉強したほうがいいんじゃないかと
633NAME IS NULL:2010/11/21(日) 05:33:51 ID:RG9/i762
その様子だと、分離レベルはデフォルトのREAD_COMMITTED?

だったら
delete from TABLE where No = @No
insert into TABLE values (@No, a, b, c)
にトランザクションかければOK
634NAME IS NULL:2010/11/26(金) 14:58:01 ID:???
mysql5.1.46

version_noというカラムがあり,そこには
例えば
95/98/2000/〜
2000/2002/〜
といった文字列が格納されています。
このカラムの文字列を見て
'95'から始まるときは1
'97'から始まるときは2
'98'から始まるときは3
'2000'から始まるときは4
'2002'から始まるときは5
'2003'から始まるときは6
'2007'から始まるときは7
'2010'から始まるときは8
という数値をverというカラムにセットしたくて

update datatbl
case left(version_no,locate('/',version_no) -1)
when '95'
set ver = 1
when '97'
set ver = 2
when '98'
set ver = 3
when '2000'
set ver = 4
when '2002'
set ver = 5
when '2003'
set ver = 6
when '2007'
set ver = 7
when '2010'
set ver = 8;
というのを作ったんですが,エラーになっています

select id,version_no
from datatbl
where left(version_no,locate('/',version_no) -1)
in ('95','98','97','2000');

は動くのですが、updateの時はどう書けばよろしいのでしょうか?
635NAME IS NULL:2010/11/26(金) 15:10:17 ID:???
宜しくお願いします。

・DBMS名とバージョン
Oracle10g

・テーブルデータ
SALES
+------------+------+
| 日時 | 数量 |
+------------+------+
| 2010/03/01 | 1 |
| 2010/03/02 | 1 |
| 2010/03/23 | 2 |
| 2010/03/24 | 1 |
| 2010/04/05 | 5 |
| 2010/04/05 | 2 |
+------------+------+

・欲しい結果
テーブルから週毎(月曜基準)に合算した数量を取得したい。
但しデータがない週も0で表示したい。

・説明
週毎に合算した数量は以下のSQLで取得できましたが、
データがない週も表示する方法がわかりません。

SELECT NEXT_DAY(TO_DATE(日時,'yyyy/mm/dd'),2)-7 AS 日時, SUM(数量)
FROM SALES
GROUP BY NEXT_DAY(TO_DATE(日時,'yyyy/mm/dd'),2)-7;

宜しくお願い致します。

636NAME IS NULL:2010/11/26(金) 15:20:31 ID:???
>>634
SET ver = CASE case left(version_no,locate('/',version_no) -1) WHEN '95' THEN 1 WHEN '97' THEN 2 ...
とすべきじゃないかな。

>>635
無い週を表示するには、別途カレンダーテーブルか、数列を生成するテーブル関数を用いて
結合させないと無理。
637NAME IS NULL:2010/11/26(金) 15:21:24 ID:???
すまんCACEが被った
SET ver = CASE left(version_no,locate('/',version_no) -1) WHEN '95' THEN 1 WHEN '97' THEN 2 ...
638NAME IS NULL:2010/11/26(金) 15:30:37 ID:???
>>636
ありがとうございます。

update vba
set ver =
case
when left(version_no,locate('/',version_no) -1) = '95'
then 1
when left(version_no,locate('/',version_no) -1) = '97'
then 2
when left(version_no,locate('/',version_no) -1) = '98'
then 3
when left(version_no,locate('/',version_no) -1) = '2000'
then 4
when left(version_no,locate('/',version_no) -1) = '2002'
then 5
when left(version_no,locate('/',version_no) -1) = '2003'
then 6
when left(version_no,locate('/',version_no) -1) = '2007'
then 7
when left(version_no,locate('/',version_no) -1) = '2010'
then 8
else
0 end;

で出来ました
639NAME IS NULL:2010/11/26(金) 15:34:05 ID:???
>>636
ありがとうございました。
PGMで制御する事にします。
640NAME IS NULL:2010/11/26(金) 18:29:22 ID:???
641NAME IS NULL:2010/11/26(金) 19:26:34 ID:???
>>640
失礼しました。
過去ログにて非推奨を確認しましたので、
SQL後のPRGで制御する事にします。
ありがとうございました。
642NAME IS NULL:2010/11/27(土) 04:03:03 ID:???
+---+------+----+
| id|parent|name|
+---+------+----+
| 1 | NULL |taro|
| 2 |  1 |jiro|
| 3 |  1 |sabu|
| 4 |  2 |siro|
| 5 |  3 |hana|
+---+------+----+

上記のようなユーザーID(id)とその親情報(parent)のテーブルで、
指定したIDの子と孫の一覧を取得するにはどうすればいいですか?
1の場合、jiro、sabu、siroを取得したいです。
子と孫の総数だけでもかまいません。
643NAME IS NULL:2010/11/27(土) 05:14:57 ID:???
すいません、hanaも孫でした。。。
644NAME IS NULL:2010/11/27(土) 06:37:04 ID:???
SELECT * FROM <table> WHERE parent=<id> -- 自分を親に持つ=子
UNION
SELECT * FROM <table> WHERE parent=(SELECT id FROM <table> WHERE parent=<id>) -- 子を親に持つ=孫
645NAME IS NULL:2010/11/27(土) 06:46:33 ID:???
>>642
孫までで良いなら、子の検索と孫の検索をunion allすればいいんじゃね
単純にnameだけ一覧するならたぶんこんなSQLで行けるかと

select name from テーブル where parent=1
union all
select name from テーブル where parent in (
select id from テーブル where parent=1)

孫の子も、その子も、その子の子も...っていうなら、
再帰SQL使える環境じゃないとちょっと厳しいかな
646645:2010/11/27(土) 06:53:38 ID:???
かぶったw 
悔しいから>>644のダメ出ししとこう
UNIONだと(別IDで)同一のnameがいた場合に件数が減るからunion allじゃないとダメ
孫の検索条件のparent=は、カッコ内のサブクエリが複数行返すとエラーになるからinじゃないとダメ
647645:2010/11/27(土) 06:59:58 ID:???
あ、>>644は*でselectしてるからUNIONの件は忘れてくれ

union allすべきとこでついついunionしちまうことが結構多いのは俺だけ?
648NAME IS NULL:2010/11/28(日) 11:28:17 ID:TZKM21JF
649NAME IS NULL:2010/11/30(火) 18:12:53 ID:OHRNMayz
・DBMS名とバージョン
mysql5
・テーブルデータ
TABLE名 A1234 A1235
・欲しい結果
INTEGER 1234を入力した時に
SELECT * FROM A1234 の結果が
INTEGER 1235を入力した時に
SELECT * FROM A1235 の結果が

返る関数


よろしくお願いします。

650NAME IS NULL:2010/11/30(火) 23:39:43 ID:lM4VOFvr
SQLite3で

1 | aaa
2 | bbb
3 | ccc
4 | ddd
5 | eee

というテーブルから「3 ccc」を削除した時に自動で

1 | aaa
2 | bbb
3 | ddd
4 | eee

みたいに修正する方法ってありますか?
他のDBMSでの方法でも構わないので宜しくお願いします。
651NAME IS NULL:2010/12/01(水) 03:12:58 ID:???
数値nが連番かつ制約が無いと仮定して
UPDATE table SET n=n-1 WHERE n>3;
652NAME IS NULL:2010/12/01(水) 04:34:16 ID:Ax/gL4gh
・DBMS名とバージョン
mysql5
・テーブルデータ
TABLE名 A1234 A1235
・欲しい結果
INTEGER 1234を入力した時に
SELECT * FROM A1234 の結果が
INTEGER 1235を入力した時に
SELECT * FROM A1235 の結果が

返るストアドプロシージャです。

用意された関数ではなくテストアドプロシージャです。
よろしくお願いします。
653NAME IS NULL:2010/12/01(水) 04:43:07 ID:???
>>652
普通に分岐じゃだめなのかな。
654NAME IS NULL:2010/12/01(水) 04:44:03 ID:???
>>650
>>651をdeleteのトリガでやればいいとおもう。
655NAME IS NULL:2010/12/01(水) 19:33:34 ID:0WLtPE6T
DB設計はこのスレじゃダメですか?

PHP+MySQLなんですが、できるだけDBで処理しようと思っています。

お買い上げに応じて、n%分を顧客にポイントを付与しています。
これにはキャンペーンが存在して、水曜と日曜はポイント5倍、
7の付く日(7日、17日、27日)もポイント5倍、1日はポイント10倍などあります。
1日が水曜日の場合は、倍率の大きい、ポイント10倍が適用されます。
また、たとえば、クリスマス期間12月01日から12月26日まではポイント「さらに」1.5倍、三が日は一律10倍などもあります。

こんな感じで、キャンペーンの曜日や期間、パーセンテージを自由に設定できるようにしたいです。

「今日はポイント何%?」というのがすぐに取得できるような形が理想です。
よろしくお願いします。
656655:2010/12/01(水) 19:43:16 ID:0WLtPE6T
現状、
・日別キャンペーンテーブル
・曜日別キャンペーンテーブル
・期間キャンペーンテーブル
とバラバラに作って、PHPで処理しています。

1か月分のパーセンテージ一覧を作るのに、1日ごとにSQLを複数実行して
かなり重いので、その辺も簡略化できる設計だと助かります。
657655:2010/12/01(水) 20:21:55 ID:0WLtPE6T
自己レスだけど、こうゆう場合は
カレンダーテーブル(日付、計算済み%をカラムに持つ)を作ってあげて、
各種キャンペーンテーブルを更新するたびに1か月分とかカレンダーテーブルを更新する設計がいいんだろうか?
それだと、売り上げの度に%を取得するのが1回のSQLで済む。
ただし、時間帯別のキャンペーンが作れない(作りにくい)のと、設定忘れなどで、昔の期間にキャンペーンを設定するのが面倒な点が変わらない。。。
658NAME IS NULL:2010/12/01(水) 20:43:49 ID:???
ビュー作れ
659655:2010/12/01(水) 20:46:18 ID:0WLtPE6T
どのようなビューでしょう??
660NAME IS NULL:2010/12/01(水) 21:01:28 ID:???
曜日があるからビューはかなりムリゲーだったわ・・。

1,2,3-31の日付だけ持つダミーテーブルを作って指定月の一ヶ月の一覧を取得するSQLをまず作る。
(SQLは多少メンドクサイが)単純な計算なのでこのまま使っても重いとは思えないが、
もし重ければ>>657の通り、月初なりキャンペーンテーブル更新時なりに別テーブルにinsert 〜 select すりゃおk
661NAME IS NULL:2010/12/01(水) 22:05:00 ID:???
キャンペーンごとのテーブルが必要な理由が分からない
カレンダーだけ作ってバッチ更新でいいだろ
662NAME IS NULL:2010/12/01(水) 22:07:18 ID:???
テーブル設計はスレ違いです。
663NAME IS NULL:2010/12/01(水) 22:10:19 ID:???
>>661
そのバッチは何テーブルを見て更新するつもりだ?
664NAME IS NULL:2010/12/01(水) 22:12:45 ID:???
665NAME IS NULL:2010/12/01(水) 22:28:26 ID:???
>>663
そんな変なキャンペーンルールなんかバッチ側にもてばいい
666NAME IS NULL:2010/12/01(水) 22:48:24 ID:???
>>665
例えばドトールのような不定期なキャンペーンを展開してるシステムとかどうするんだよ間抜け
毎月バッチリリースすんのかよw
667NAME IS NULL:2010/12/01(水) 22:55:45 ID:???
水曜日のパーセンテージ変えようぜってやったら指定日以降の水曜日だけ変わってほしいよねきっと。
今曜日キャンペーンテーブルに期間もたせてるの?ないなら持たせないといけないんだよねぇ。

カレンダー的なメンテナンス画面作るのが楽だと思うなぁ。
668655:2010/12/02(木) 00:26:41 ID:u5kOJKQ0
曜日キャンペーンに期間は必要ですねぇ。
いまはまだ付けてないです。
参考にさせていただきます。

それでは、スレ違いだったようなので、別スレにて再度、投稿してきます。
669NAME IS NULL:2010/12/02(木) 02:30:47 ID:???
MySql 5.1 です。
select句の subquery で、カラムを2つ返したいのですが、
これは不可能なのでしょうか?
何か良い方法はないでしょうか?

同じ問い合わせを、2回書くのは なしということでお願いします。
こんな感じで実現できたらベストです。

select
a.name ,
b.date ,
(
select
c.foo_id,
c.bar_id
from
c
where
a.cond = c.cond
and b.date > c.date
order by c.date desc
limit 1
)
from
a, b
where
a.id = b.id
670NAME IS NULL:2010/12/02(木) 04:00:05 ID:???
select
a.name ,
b.date ,
max(c.date)
from
a join b using (id)
left join c on (a.cond = c.cond and b.date > c.date)
group by a.id, a.name, b.date

かなぁ
671NAME IS NULL:2010/12/02(木) 04:00:46 ID:???
あああごめんぜんぜんちがうね!
672NAME IS NULL:2010/12/02(木) 04:14:59 ID:???
MySQLで動くかどうかわからん(他のDBMSでも試していないけど)

SELECT a.name,b.date,c.foo_id,c.bar_id
FROM a JOIN b ON a.id=b.id
JOIN c ON a.cond=c.cond
AND c.date = (SELECT max(date) FROM c WHERE a.cond=c.cond AND b.date > c.date);
673NAME IS NULL:2010/12/02(木) 15:41:00 ID:6RsQNc/l
【質問テンプレ】
・DBMS名とバージョン :SQLyog trial -MySQL GUI v8.71

・欲しい結果 :正常な文字

・説明:DBの編集をしていたのですが、DB内に「・ト」「・・ツ」「・B」と言った化けた文字が出てしまい、
まともに何が書いてあるか分かりません。ここに貼ると形が変わってしまいますが、黒塗りの「?」のような文字だったり、♀だったりします。
おそらくlatin1の文字だと思うのですが、
このように化けてしまった文字を編集する方法はありますでしょうか?数値の欄なので、これらの文字は
何かしらの数字を表していると思います。
674NAME IS NULL:2010/12/02(木) 16:36:56 ID:O5ao1X4S
>>653

実際はAXXXXなので1万テーブルあるんですよ。
それを指定したいので、分岐だと厳しいです。



・DBMS名とバージョン
mysql5
・テーブルデータ
TABLE名 A1234 A1235
・欲しい結果
INTEGER 1234を入力した時に
SELECT * FROM A1234 の結果が
INTEGER 1235を入力した時に
SELECT * FROM A1235 の結果が

返るストアドプロシージャです。

675NAME IS NULL:2010/12/02(木) 17:13:49 ID:???
>>674
ああ、そうならそうといえばいいのに。
クエリ作ってプリペア、実行でできるみたいよ。

参考URL http://forums.mysql.com/read.php?98,126506,126598#msg-126598
676NAME IS NULL:2010/12/02(木) 17:15:53 ID:???
>>673
スレ違い。
そのツールの問題だよね。
677673:2010/12/02(木) 17:27:36 ID:???
失礼いたしました。
678NAME IS NULL:2010/12/02(木) 22:51:37 ID:O5ao1X4S
>>675

おおー
欲しかったのはこれです。
ありがとうございます。
679NAME IS NULL:2010/12/04(土) 13:11:35 ID:USyUL0Zn
mysql 5です。
ストアドプロシージャ aaaのなかで変数@bbbを定義すると
@bbbが同じデータベース内でselectで呼び出せてしまうんですが
これって同時にaaaの呼び出しが別のところからかかると
結果が相互干渉してしまうって事でしょうか?
680NAME IS NULL:2010/12/04(土) 13:24:45 ID:???
知らん。スレ違い。
681NAME IS NULL:2010/12/04(土) 14:15:13 ID:???
682NAME IS NULL:2010/12/04(土) 22:24:44 ID:???
・DBMS名とバージョン
SQLiteまたはMySQL
・テーブルデータ
なし
・欲しい結果
クエリを解析して、結果に表示されるはずのカラムの一覧を取得したい
・説明
データが無いときでもカラムの一覧を取得したい。
データがあれば先頭にカラム名を出したりすることは可能だけど、
データが無いときはカラム名を取得することが出来ないので。
683NAME IS NULL:2010/12/04(土) 22:47:03 ID:???
> データがあれば先頭にカラム名を出したりすることは可能
どうやって?
684NAME IS NULL:2010/12/04(土) 22:52:06 ID:???
普通にINFORMATION_SCHEMAでも使え。
685NAME IS NULL:2010/12/04(土) 22:53:20 ID:???
csvに出したり
結果リストの連想配列のキーだったり
686NAME IS NULL:2010/12/04(土) 22:54:18 ID:???
それはSQLで出してるわけじゃない。
687NAME IS NULL:2010/12/04(土) 22:56:42 ID:???
>>684
スキーマからじゃなくてクエリから取りたい

>>686
そうなんだよ。それをどうにかして取得したい。
688NAME IS NULL:2010/12/04(土) 22:58:10 ID:???
無理。
689NAME IS NULL:2010/12/04(土) 23:04:09 ID:???
>>687
取れないことをわかってて取りたいって質問するのはなんなんだ?
690NAME IS NULL:2010/12/04(土) 23:07:13 ID:???
スレ違いだな。
691NAME IS NULL:2010/12/04(土) 23:09:31 ID:???
ここにいる連中には聞いても無駄ってことだな
692NAME IS NULL:2010/12/04(土) 23:10:22 ID:???
はい。無駄です。
693NAME IS NULL:2010/12/05(日) 00:02:47 ID:???
SQLの話じゃないね。
1行だけ取得するクエリ作っとけば?
694NAME IS NULL:2010/12/05(日) 09:56:40 ID:MMVSExqC
データがないと判った時点で

desc テーブル名で
情報を拾うというのは駄目なん?
695NAME IS NULL:2010/12/05(日) 11:06:07 ID:???
ダミーテーブル作ってOUTER JOINするとか

create table table1 (a number, b number, c number);
insert into table1 values (0,0,0);
insert into table1 values (1,1,1);
insert into table1 values (1,2,2);
create table dummy1 (x number);
insert into dummy1 values (0);
select t1.* from (select * from table1 where a = 0) t1 right outer join dummy1 on 1 = 1;
select t1.* from (select * from table1 where a = 1) t1 right outer join dummy1 on 1 = 1;
select t1.* from (select * from table1 where a = 2) t1 right outer join dummy1 on 1 = 1;
696NAME IS NULL:2010/12/07(火) 00:55:47 ID:???
初歩的な質問ですみません。どうしても動かないので腹が立って質問します。
取引先テーブルから会社名の最後に株式会社とつく会社を抜き出すときはこれでいいんですよね。どうしても動きません。
使ってるソフトはhsqldbです

SELECT 会社名
FROM 取引先テーブル
WHERE 会社名 LIKE '%株式会社'
697669:2010/12/07(火) 01:32:20 ID:???
>>672

遅くなりましたが、大体そんな感じで出来ました。
アリガdです。
698NAME IS NULL:2010/12/07(火) 02:17:14 ID:???
>>696
エラーメッセージを貼らないとか腹が立ちます。
699NAME IS NULL:2010/12/07(火) 06:55:47 ID:HbkP7Lwq
0-hitかも
700NAME IS NULL:2010/12/07(火) 07:26:09 ID:???
文字コードが合ってるか、とか。
701NAME IS NULL:2010/12/07(火) 07:49:55 ID:???
>>696
正解とはいえませんが、これでどうなるか確かめてください。

SELECT 会社名
FROM 取引テーブル
WHERE 会社名 LIKE '%株式会社%' AND 会社名 NOT LIKE '株式会社%'
702NAME IS NULL:2010/12/07(火) 08:09:27 ID:???
最後にセミコロン
703NAME IS NULL:2010/12/07(火) 18:55:14 ID:???
>>698
エラーは出ませんでしたが、結果も出ませんでした。上に「会社名」とだけ出て、抽出されるはずの株式会社で終わる会社名は出ませんでした。
今日学校で聞いた話では「3番はなんか動かないのでいいや」とのことでした。

>>701
おお、出ました。ありがとうございます。また分からないことがあったときはよろしくお願いします。
704NAME IS NULL:2010/12/07(火) 19:22:09 ID:???
>>701
アプリ上で「株式会社A」→「A株式会社」にしてるってこと?
705NAME IS NULL:2010/12/07(火) 21:00:53 ID:???
「株式会社」の後ろに改行コード等が紛れているんじゃね?
706NAME IS NULL:2010/12/07(火) 21:01:33 ID:???
>>704
いや、株式会社の後にゴミが入っているのではないか。
正解でないとしたのは、
「日米起業株式会社東京支店」のようなケースがあるから。
707NAME IS NULL:2010/12/07(火) 21:03:30 ID:???
試しに
WHERE trim(会社名) LIKE '%株式会社'
とかやってみたらどうかな。
708NAME IS NULL:2010/12/08(水) 00:13:06 ID:???
>>705-706
なるほど。勉強になりました。
709NAME IS NULL:2010/12/10(金) 21:34:38 ID:???
スレがないので、ここで質問します。postgreSOLのデータベース定義で、

ENCODING = 'UTF8'
LC_COLLATE = 'Japanese, Japan'
LC_CTYPE = 'Japanese, Japan'

としてますが、pgAdminIII の各ペインに表示される日本語部分が、

”□□□□□□□□□□□□□□”

のようになり、これらの四角形をカーソル反転させて他のアプリに貼り付けると

”全地公団コード”

などと正常に表示されます。原因と解決策が分かりましたら、ご教授を。。。。
710NAME IS NULL:2010/12/10(金) 22:31:38 ID:???
>>709
聞くならこっちかな
PostgreSQL Part.7
http://hibari.2ch.net/test/read.cgi/db/1256300618/

pgAdmin3の[ファイル(F)] -> [オプション] でユーザ言語をJa_JPにしてみるとか、
俺は初期値で問題ないけどな。

それで直らなかったら、スレ移動してからの方がよさげ。
711NAME IS NULL:2010/12/12(日) 23:17:54 ID:???
Oracleのソートだと数字→英字になっていまいますが
これをSQLで逆にソートする方法はありますか。
712NAME IS NULL:2010/12/13(月) 01:39:23 ID:???
なんとなくこんなくだらないこと考えた

select *
from TableName
order by regexp_replace(regexp_replace(COL_NAME, '[A-Za-z]', 'A'), '[0-9]', 'z'), COL_NAME
;
713NAME IS NULL:2010/12/13(月) 01:42:10 ID:???
数字毎、英字毎をどうやってソートするかで結構変わるな
714NAME IS NULL:2010/12/15(水) 00:44:01 ID:???
H2DBとHibernate使ってます
HtmlのTextAreaからのテキスト入力をそのまま挿入すると
インジェクトされると思うのですが、良い対策方について意見ください。

現在考えているのは、
DBへのInsertの前にテキストだけAES暗号化、
主キーでDBから出した後に複合化することです。
715NAME IS NULL:2010/12/15(水) 04:26:02 ID:???
そのまま挿入してもインジェクションは起こらないよ。
そのままクエリ作成に利用したらインジェクションが起こる。
716NAME IS NULL:2010/12/15(水) 04:48:20 ID:???
クエリ作成するさいの話じゃないの?
717NAME IS NULL:2010/12/15(水) 05:13:45 ID:???
SQLのサニタイジングを楽にやりたいとか?
718NAME IS NULL:2010/12/15(水) 07:15:55 ID:???
>>715
すみません。インジェクトとかインジェクションと
いうのはどういうことですか?
この機会に教えてください。
719NAME IS NULL:2010/12/15(水) 07:24:32 ID:???
スレ違い
720NAME IS NULL:2010/12/15(水) 07:28:08 ID:???
暗号化しようが、入れたモノをそのまま出したら、XSSの餌食。
721NAME IS NULL:2010/12/15(水) 07:47:25 ID:???
select * from 商品一覧 where 商品名 = 'フォームの入力値';
となっていた場合、入力値に、'; select * from 顧客情報; // とすると
select * from 商品一覧 where 商品名 = ''; select * from 顧客情報; //
となり、商品取得に加えて、顧客情報の一覧が取得できる(だけでなく、任意のSQLを発行できる。)

詳しくはWeb制作板、、とかなのかな。適当にぐぐればいろいろでてくるよ。
722NAME IS NULL:2010/12/15(水) 07:48:37 ID:???
ああ、
select * from 商品一覧 where 商品名 = ''; select * from 顧客情報; //';
こうね。

//じゃなくて--の気もするけど、深く気にしないでw
723NAME IS NULL:2010/12/15(水) 11:41:15 ID:???
それはホスト言語でSQLや入力値等をどのように扱ってるかによる
まったくのスレ違いなのでさっさとお引き取り下さい
724714:2010/12/15(水) 17:39:28 ID:???
>>720
htmlの無害化はレイヤー分けるでしょ。

>>718
挿れちゃうぞー☆

>>722
最後の// or -- は何を表してるの?

' " ; % の他にもORとかUNIONとかキリがないから暗号化。
ただ偶然攻撃文になる可能性もある。
725NAME IS NULL:2010/12/15(水) 17:50:33 ID:???
>>724
ごみが残るからコメントにしただけ
726NAME IS NULL:2010/12/15(水) 18:00:25 ID:???
なるほどね。
727NAME IS NULL:2010/12/16(木) 03:00:36 ID:???
バインド変数が使えるような構成にすれば、
それでいいと思うけど。暗号化???
728NAME IS NULL:2010/12/16(木) 05:38:09 ID:???
せめて暗号化じゃなくてBase64にしとけ
729NAME IS NULL:2010/12/16(木) 21:39:31 ID:???
>>727
そもそも、Hibernateがそういう仕組みを提供していると思う。
730NAME IS NULL:2010/12/17(金) 02:19:10 ID:nrWKTwgD
・DBMS名とバージョン
 MySQL 5.1
・テーブルデータ
 記録ID(通し番号)、ユーザID、日時、金額、購入品目ID
・欲しい結果
 購入品目ID、日時(最新の1件)、金額(〃)  //ただしユーザID=A

・説明
 ユーザID=Aの、購入品目IDごとに、最新の日時と金額を表示させたいです。
 (購入品目IDが1〜10まであったら、10行の結果が返ってくるような)
 どこに副問合せを使っていいか分からず詰まりました。どなたかお願いします。
731NAME IS NULL:2010/12/17(金) 03:45:49 ID:???
select 購入品目ID, 日時, 金額 from テーブル a
where not exists(select * from テーブル b where a.ユーザID = b.ユーザID and a.購入品目ID = b.購入品目ID and a.日時 < b.日時)
and ユーザID = A

こんなんでできないかな。間違えてたらごめんね。
732NAME IS NULL:2010/12/17(金) 04:26:57 ID:???
>>731
レスありがとうございます。
書いて頂いたSQL、意味は何となく分かりました。
しかし、今回はテーブルa内で問合せが完結するので、(テーブルa内の最新のものを表示する)
テーブルbと書いて頂いた所はどのようにすべきでしょうか?
私の知識不足で度々申し訳ありませんが、よろしければご教示お願いします。
733NAME IS NULL:2010/12/17(金) 04:45:32 ID:???
>>732
ん、同じテーブルに対して問い合わせをするよ
テーブルの各行について「自分のテーブルの中にそれよりも新しいレコードがないような」レコードを抽出する

相関サブクエリというキーワードで検索するといいかも。
734NAME IS NULL:2010/12/17(金) 05:42:45 ID:???
>>733
ありがとうございます、できました。
テーブルに相関名をつけて比較している、と理解しました。
勉強になりました。真夜中にありがとうございました。
735NAME IS NULL:2010/12/17(金) 10:34:22 ID:???
ためしてないけど、havingじゃだめなのか?

select ユーザID,購入品目ID,日時,sum(金額) from テーブル
group by ユーザID,購入品目ID,日時
having 日時=max(日時)

こんな感じでいけそうな気がする
最新の日時が同じデータあったら2行だせってならもうひと工夫いるけど
736NAME IS NULL:2010/12/17(金) 10:56:55 ID:???
group byに日時入ってんのにmax(日時)って意味ないでしょ。
737NAME IS NULL:2010/12/17(金) 11:39:53 ID:???
>>736
じゃあこうか

select ユーザID,購入品目ID,日時,sum(金額) from テーブル a
group by ユーザID,購入品目ID,日時
having 日時=(
select max(日時) from テーブル where ユーザID=a.ユーザID and 購入品目ID=a.購入品目ID)

結局相関サブクエリ必要なのかorz
738NAME IS NULL:2010/12/17(金) 13:20:13 ID:???
>>735のときから気になってんだけど、なんで金額のsum出してるの?
739NAME IS NULL:2010/12/17(金) 13:37:48 ID:???
>>738
group by を使ったから。
740NAME IS NULL:2010/12/17(金) 13:42:07 ID:???
同一日時のデータがあったときにどうするか不明だからとりあえず合計しといた

not existsと相関サブクエリが遅そうな気がしたから
その二つを使わないで出来ないかと思っただけなんだ
741NAME IS NULL:2010/12/17(金) 14:20:51 ID:???
なるほど、同一商品を同一日時に複数購入した場合、かぁ。
742NAME IS NULL:2010/12/19(日) 12:35:44 ID:???
>>741
group by を使ったときに集約関数を使わずに
,金額 という具合に参照できるの?
743NAME IS NULL:2010/12/19(日) 16:26:04 ID:???
できないよ
744NAME IS NULL:2010/12/19(日) 19:47:17 ID:???
MySQL以外では出来ない
745NAME IS NULL:2010/12/19(日) 20:46:30 ID:???
>>744
あー、やっぱりそうなのか。でも随分と危なっかしい
仕様だな。
746NAME IS NULL:2010/12/19(日) 21:05:13 ID:???
GROUP BY してるのに,金額としたらどう表示されんのよ。
747NAME IS NULL:2010/12/19(日) 23:34:46 ID:???
>>746
出てきた順、ORDER BYと組み合わせることで、>>4だと
SELECT * FROM (SELECT * FROM table_a ORDER BY `date` DESC)AS A GROUP BY id ;
で済ませることが出来る。
PostgreSQLのDISTINCT ONと似た感じなんだが、
暗黙過ぎてあまり使う気にはなれないけどね。
748NAME IS NULL:2010/12/19(日) 23:36:13 ID:???
補足、つーか抜けていた。
>>747は「MySQLの場合だと」という例ね。
749NAME IS NULL:2010/12/20(月) 06:41:36 ID:???
なるほどねぇ。
糞仕様だねぇw
750NAME IS NULL:2010/12/20(月) 22:40:05 ID:???
MySQL以外のデータベースってないの?
751NAME IS NULL:2010/12/20(月) 22:58:56 ID:???
ないよ
752NAME IS NULL:2010/12/20(月) 23:07:38 ID:???
唯我独尊
753NAME IS NULL:2010/12/21(火) 15:49:03 ID:iIvJtzy4
>>4のような状況で、
各IDごとにランダムで2件抽出して、そのDATEを
現在の日時に更新するにはどうすればよいでしょうか?

MySQL 5.0.77です
754NAME IS NULL:2010/12/21(火) 18:12:45 ID:???
まずランダムとかムリだろ
755NAME IS NULL:2010/12/21(火) 19:14:57 ID:???
order by を指定しなければ順番は保証されないからランダムではある
おそらくデータ更新しない限りは順番は変わらないだろうが
756NAME IS NULL:2010/12/21(火) 22:25:49 ID:???
いや、RANDあるんだけど、、、なんで無理なんだ?
757NAME IS NULL:2010/12/21(火) 22:26:54 ID:???
758NAME IS NULL:2010/12/22(水) 14:02:32 ID:reTSwFFm
MySQLで、複数の行のそれぞれ狙った項目だけを一度に更新する方法はありますか?

例えばhoge( key, value1, value2 )というテーブルに対して、やりたいこととしては

INSERT INTO hoge( key, value1, value2 )VALUES
(1, 10, 今の値),
(2, 今の値, 20)
ON DUPLICATE KEY UPDATE
value1 = VALUES(value1),
value2 = VALUES(value2)

こんなイメージです。変えたいトコだけ変えて、他は現状維持してくれっていう。
759NAME IS NULL:2010/12/22(水) 21:19:45 ID:???
「変えたいトコだけ」の条件判断の方法が明確なら普通にUPDATEすればいいだろ
760NAME IS NULL:2010/12/22(水) 22:34:08 ID:???
専用のアプリ作ってループでWHERE文発行すればいい気がする
761NAME IS NULL:2010/12/28(火) 22:14:51 ID:???
今sql習っているがnullとかinsertとかいやらしすぎるだろ
762NAME IS NULL:2010/12/28(火) 22:15:35 ID:???
ヘルス2回も行ってしまったわ
763NAME IS NULL:2010/12/29(水) 04:46:39 ID:???
>>761と同類の人が作ったであろうコピペを昔みたと思うけど、ちょっと探す気が起きない
764NAME IS NULL:2011/01/01(土) 12:54:46 ID:???
ANALYSISテーブル( ANALYSIS_ID, .......)
PLANテーブル( PLAN_ID, ANALYSIS_ID not null, ........)

というイメージなんですが、意図は
PLANテーブルには必ず一つ以上のANALYSISレコードを保持する。
ANALYSISテーブルの各レコードは複数のPLANテーブルで参照される。
です。

多:多の結合になると思うんですが、中間テーブルにすると
PLAN.ANALYSIS not null の満たし方がわかりません。
こういう場合、通常どう設計するものなのでしょうか?
配列型フィールドとか思い浮かんでしまうんですが・・
765NAME IS NULL:2011/01/01(土) 13:03:57 ID:???
スレ違い

DB設計を語るスレ 3
http://hibari.2ch.net/test/read.cgi/db/1269585561/
766NAME IS NULL:2011/01/05(水) 14:26:08 ID:???
ユニークキーってどうやって生成しますか?

自分はシーケンスで生成させているのですが、
一度割り振られた番号はカラムが削除されても再利用されないので
いずれ枯渇するかLong型に収まらない数値になると思います。

SQLだけでキーを生成するべきではないのでしょうか
767NAME IS NULL:2011/01/05(水) 17:37:31 ID:???
>>766
long型シーケンスを使い切って0に戻ったらどうなるのか?
PostgreSQLの作りそのものは0に戻るはずだが、ちゃんと戻るのか?
そもそも使い切ったシステムはあるのか? そのときどうなったのか?

という話題をかれこれ10年近く前に石井氏がMLだったか講習だったで
していたような気がする。
当時はまだ使い切ったようなシステムが存在しない。だったかな。

俺がかかわるようなシステムでシーケンスの枯渇は気にすることないな。
というのが当時の結論。今もそうだが。
枯渇が気になるのなら(年+シーケンス)とかにして、年に1度シーケンスは
リセットさせればいいんじゃね。
768NAME IS NULL:2011/01/05(水) 20:21:01 ID:???
postgresのobjectid(int)だったらこれまでも何回か使い切ったな。
longは使い切れるもんなのかな?事前発行サイズを大きくとってそれを
どんどん捨ててしまうシステムだったらもしかしたら?という感じだな
769NAME IS NULL:2011/01/06(木) 11:03:56 ID:???
> 枯渇が気になるのなら(年+シーケンス)とかにして
Longのままなら結局使える幅が減る→文字列型にする→パフォーマンス悪いんですけどどうしましょう

何度か見かけた流れだな。
770NAME IS NULL:2011/01/10(月) 12:42:24 ID:???
年とシーケンスを別カラムにして、複合キーに


…ってのも誰でも思いつくよな…
771NAME IS NULL:2011/01/13(木) 00:40:13 ID:???
シーケンス使わないで
複合ユニークキー生成サーバー作るとか?
772NAME IS NULL:2011/01/13(木) 06:59:45 ID:Af2KeuAx
わざわざユニークキー生成する必要ないだろ
項目自体に一意性のセットが存在しないなら

おそらくそんなデータは更新かけることも無いだろうから

不安なら登録日時を項目として付け加えとけばいい
773NAME IS NULL:2011/01/13(木) 08:55:46 ID:febmxaew
sqlite3を使用しています。
並び変えたデータの100番目以降を消したいのですが方法が見つかりません。
どなたか分かる方がいましたらよろしくお願いします。
774NAME IS NULL:2011/01/13(木) 18:46:23 ID:???
こんな感じ?
delete from TableName where KEY_COLUMN in (select KEY_COLUMN from TableName order by ORDER_COLUMN limit -1 offset 100);
775NAME IS NULL:2011/01/13(木) 21:03:39 ID:febmxaew
>774
ありがとうございます!うまくいきました。
自分が女の子だったら惚れるところでした。
776NAME IS NULL:2011/01/14(金) 04:48:44 ID:???
男でも774はこばまないよ。
777NAME IS NULL:2011/01/14(金) 16:41:55 ID:8a2gtYfg
【質問テンプレ】

・DBMS名とバージョン
Mysql 4.0.27

・テーブルデータ
a_tbl
ID | DATE     | DATA
--+----------+-----
1 | 20081111 | あああ
2 | 20071111 | いいい

b_tbl
ID | DATE     | DATA
--+----------+-----
1 | 20081110 | えええ
2 | 20081109 | おおお

c_tbl
ID | DATE     | DATA
--+----------+-----
1 | 20081108 | ききき
2 | 20071109 | くくく


・欲しい結果

ID | DATE     | DATA
--+----------+-----
a1 | 20081111 | あああ
b1 | 20081110 | えええ
b2 | 20081109 | おおお
c1 | 20081108 | ききき


・説明
上記のような別々の3つのテーブルからDATEの新しい順にソートして、
かつ各テーブルの行データを出力したいのですが、
どのようにすればよいでしょうか?
778NAME IS NULL:2011/01/14(金) 17:55:44 ID:???
>>777
a1とかb1とか言うのはa_tblのID=1とかb_tblのID=1とかって言う意味か?
a2とかc2はなぜ出力されないんだ?
779NAME IS NULL:2011/01/14(金) 17:59:20 ID:8a2gtYfg
>>778
>a1とかb1とか言うのはa_tblのID=1とかb_tblのID=1とかって言う意味か?

その通りです。

>a2とかc2はなぜ出力されないんだ?

すいません、勝手に脳内LIMITしておりました。
全て出力されれば

ID | DATE     | DATA
--+----------+-----
a1 | 20081111 | あああ
b1 | 20081110 | えええ
b2 | 20081109 | おおお
c1 | 20081108 | ききき
a2 | 20071111 | いいい
c2 | 20071109 | くくく

となります。
780NAME IS NULL:2011/01/14(金) 18:48:11 ID:???
4.1以上なら
select * from (
  select ID,DATE,DATA from a_tbl
  union all
  select ID,DATE,DATA from b_tbl
  union all
  select ID,DATE,DATA from c_tbl
)
order by DATE;
でいいと思うけど、サブクエリが使えない4.0じゃどうすっかねぇ・・・
781NAME IS NULL:2011/01/14(金) 19:03:59 ID:8a2gtYfg
ご教授いただいたコードで一応試してみたところ、
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near :
というエラーが出てしまいました。
782NAME IS NULL:2011/01/14(金) 20:44:48 ID:???
サブクエリが使えないんだから一旦テンポラリテーブルにだして、そこから…
でないと駄目なんじゃ?
783780:2011/01/14(金) 20:57:42 ID:???
ふと思ったけどorder byの評価順はunionより後なんだっけ?
select ID,DATE,DATA from a_tbl
union all
select ID,DATE,DATA from b_tbl
union all
select ID,DATE,DATA from c_tbl
order by DATE;
でいけるような気がしてきた。
試してないけど。
784NAME IS NULL:2011/01/14(金) 21:15:23 ID:???
MySQLの特殊構文でいけるらしい(4.0でも同様)。
http://dev.mysql.com/doc/refman/4.1/ja/union.html
785780:2011/01/14(金) 22:07:09 ID:???
やっぱ正しくはorder byのほうが後だよな
http://www.geocities.jp/oraclesqlpuzzle/1-6.html
http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000875.html (の、最初の注:)

括弧が必要とか、これだからMySQLは・・・
786NAME IS NULL:2011/01/14(金) 22:55:37 ID:???
MySQL 5.1 + InnoDBで、

Entries: id (PRIMARY), title, ..., x_date, ...
Tags: id (PRIMARY), name, ...
E_T: entry_id, tag_id (複合PRIMARY KEY)

こんな感じの交差テーブルがあるとき、

SELECT <Entriesのカラムだけ全部>
FROM Entries
INNER JOIN E_T ON Entries.id = E_T.entry_id
WHERE E_T.tag_id = 12345
ORDER BY Entries.x_date DESC
LIMIT 50 OFFSET 1000;

これと同じ結果を出すのに最適な方法ってどんなんですかね?
クエリの改善、インデックスの張り方、あるいはテーブル構成自体の変更なども含めて。
787NAME IS NULL:2011/01/15(土) 02:41:26 ID:???
>>785
正しくはというならSQL標準を引用すべきだし、最後の1文は蛇足。
788NAME IS NULL:2011/01/15(土) 10:40:01 ID:???
Oracle「俺の出番のようだな」
789NAME IS NULL:2011/01/15(土) 14:09:15 ID:???
>>788
お前じゃねえ、座ってろ
790NAME IS NULL:2011/01/15(土) 14:22:35 ID:???
「MySQLがやられたようだな…」
「ククク…奴は四天王の中でも最弱…」
791NAME IS NULL:2011/01/15(土) 14:42:11 ID:???
残りの三天王って誰?
792NAME IS NULL:2011/01/15(土) 15:14:25 ID:???
OSSなら
PostgreSQL、Firebird、SQLite

現実的にはMySQLとPostgreSQLの2強だよね。
793NAME IS NULL:2011/01/15(土) 23:55:05 ID:???
アプリに組み込まれたSQLiteもかなり使われていると思うけどな。
FirefoxやGoogleChromeもSQLiteだし。おかげでvacuumやreindexを
たまにやらないと重くなるが。
794NAME IS NULL:2011/01/16(日) 01:09:45 ID:???
先生助けてっ! Firebirdちゃんが息をしてないのっっ!!


FireBirdちゃんが使われてるシーンってマジで無いよね
何に採用されてるんだろ
795NAME IS NULL:2011/01/16(日) 06:52:08 ID:???
count(*) でとった値にmaxってムリポそうなんですが、
他になにかいい方法ってナイスかね?
796NAME IS NULL:2011/01/16(日) 06:52:53 ID:???
mysqlです
797NAME IS NULL:2011/01/16(日) 06:55:08 ID:???
count(*)で取った値がmaxじゃなかったらと思うと背筋が凍るわ。
798NAME IS NULL:2011/01/16(日) 09:12:34 ID:???
こういうことじゃないの?
select max(cnt) from (select hoge, count(*) as cnt from fuga group by hoge);
799NAME IS NULL:2011/01/16(日) 09:20:43 ID:???
>>786
とりあえず Entries に (id, x_date) のインデックス張ってみれば?

あとは、それぞれのテーブルの件数、条件にヒットする件数、
現在のSQLの実行計画なんかもないと誰も何も答えてくれないと思う。
800NAME IS NULL:2011/01/16(日) 11:32:43 ID:???
>>786
最近のプランナやオプチマイザが優秀だから、適当に組み替えると思うが、
(全て)JOINする前にtag_id=12345だけ抜き出した方が速いだろうから、
SELECT Entries.* FROM (SELECT * FROM E_T WHERE tag_id = 12345) AS Tet
JOIN Entries ON Tet.entry_id = Entries.id
ORDER BY ...(略
とかね。

DBに因ってはINもかなり速くなって、上にかいたように下手に気を遣うより、素直に
SELECT * FROM Entries WHERE id IN (SELECT entry_id FROM E_T WHERE tag_id = 12345)
ORDER BY....(略
と書いた方が最適解を見つけたりして、一昔前は遅いSQLの見本なんだがなw

あと、E_Tはtag_id単体で効くインデックスと、Entriesもid単体で効くインデクスは要る。
801NAME IS NULL:2011/01/16(日) 14:50:02 ID:???
NHKホワイトボックスで、SQLインジェクションってやっていた。
なんかびっくりしたんだが、一般ユーザがネット販売を利用するとき、メールアドレスにSQL言語を書き込むと、言語が動作して、過去のネットで購入した他人のリストが表示されて個人情報が抜かれてしまうとか。

これって、めちゃ基本的な話で、そもそもMySQLとかORACLEのSQL言語を扱うサーバーアプリ側で、入力データのチェックをしていたらよかったんじゃないの?
おれもこの世界やってたの、もう10年以上前だからよく憶えてないけど
[a-z0-9]+@[a-z0-9]+.ne.jp
とかって、適当に書いたけどなんかあったよね。perlとかでも。なんて言ったっけ。
なんとかマッチングだっけかな。
ホワイトボックスでは、WAFを入れてみたいなこと言ってたけど、SQLサーバーアプリ側がバージョンアップして入力制限すべきじゃないの?
そんなんじゃだめなのかな。
802NAME IS NULL:2011/01/16(日) 14:54:34 ID:???
あ、これってサーバーアプリを組む側がわざわざ入力制限プログラムをコーディングして作らなくてもメール入力フォームとかを組むと自動的にデフォルトで入るように、という意味
803NAME IS NULL:2011/01/16(日) 15:13:29 ID:???
メールアドレスとは限らないだろタコ
それにいまどきSQLインジェクションされてないWebアプリなんか作られてねーから
804NAME IS NULL:2011/01/16(日) 15:16:56 ID:???
スレ違い
よそでやれ
805NAME IS NULL:2011/01/16(日) 16:37:57 ID:???
>>801
メールアドレスってもっとゆるいから、正しくメールアドレスにマッチさせるものを書いた場合に
それだけではSQLインジェクションを防げないかと。
806NAME IS NULL:2011/01/16(日) 16:43:43 ID:???
変な奴だな。そんなわけないだろ。それって、正しいメールアドレスを書いてもSQLインジェクションでおかしな動作をするメアドがあるってことになるぞ。ありえねえ
807NAME IS NULL:2011/01/16(日) 16:59:44 ID:???
この話はここまでにしような。はい終わり
808NAME IS NULL:2011/01/16(日) 18:39:48 ID:???
つい最近まで自分とこで保守してるwebシステムに、
SQLインジェクションでログインできるものがあったな〜…
809NAME IS NULL:2011/01/16(日) 19:51:13 ID:???
スレ違いだってのに>>806のようなよく知らない人ほどレスしたがる。
ほかで勉強してきてください。
810NAME IS NULL:2011/01/18(火) 11:22:57 ID:???
MySQL5.1を使っています。

datetime型のテーブルに

元データ 16/Jan/2011:06:26:54

のフォーマットで入力したいのですが、どのようにすればよいのでしょうか。
色々調べましたが、わかりません。

是非、アドバイスください。おねがいします!
811NAME IS NULL:2011/01/18(火) 15:37:06 ID:???
アプリでやるほうがいいかも。SQLだけなら力技だけど。MySQL限定
SET @dttm = '16/Jan/2011:06:26:54';
SET @mon = 'Jan,Feb,Mar,Apr,May,Jun,Aug,Sep,Oct,Nov,Dec';
SET @dt = SUBSTRING_INDEX(@dttm, ':', 1);
SET @tm = SUBSTRING_INDEX(@dttm, ':', -3);
SET @y = SUBSTRING_INDEX(@dt, '/', -1);
SET @m = FIND_IN_SET(SUBSTRING_INDEX(SUBSTRING_INDEX(@dt, '/', 2), '/', -1), @mon);
SET @d = SUBSTRING_INDEX(@dt, '/', 1);
SELECT CONCAT(@y, '-', @m, '-', @d, ' ', @tm);
-- INSERT INTO foo SET bar = CONCAT(@y, '-', @m, '-', @d, ' ', @tm);
812NAME IS NULL:2011/01/19(水) 11:04:14 ID:???
>> 811

ご連絡遅くなりました。アドバイスありがとうございます!
やはり、アプリでおこなった方が無難と確信しました。sedとawkでフォーマットを

YYYY-MM-DD HH:MM:SS

とすることに致しました。上記のような方法もあるということをご教授いただき勉強になりました。
ありがとうございました!
813NAME IS NULL:2011/01/23(日) 09:23:17 ID:???
order byの使い方の確認させて

グループ番号で先ずソートして抜き出して、
さらに同一のグループ番号内の更新日時でソートする場合は、これでいい?

SELECT * FROM テーブル ORDER BYグループ番号、更新日時

1 2010-09-03 16:53:37
1 2010-09-03 17:02:57
0 2010-09-03 17:03:18
0 2010-09-03 17:03:26
0 2010-09-03 17:03:30
1 2010-09-10 11:18:19
0 2010-09-10 11:18:40

頭の[0,1]はグループ番号なんだけど、mysqlの5.0.88で、
こんな感じでバラバラで表示されるんだけど、oreder by間違ってる?
814NAME IS NULL:2011/01/23(日) 10:20:22 ID:???
SELECT * FROM テーブル ORDER BYグループ番号、更新日時
ならこうだろ
0 2010-09-03 17:03:18
0 2010-09-03 17:03:26
0 2010-09-03 17:03:30
0 2010-09-10 11:18:40
1 2010-09-03 16:53:37
1 2010-09-03 17:02:57
1 2010-09-10 11:18:19

1 2010-09-03 16:53:37
1 2010-09-03 17:02:57
0 2010-09-03 17:03:18
0 2010-09-03 17:03:26
0 2010-09-03 17:03:30
1 2010-09-10 11:18:19
0 2010-09-10 11:18:40
にしたければこうだろ
SELECT * FROM テーブル ORDER BY更新日時
815NAME IS NULL:2011/01/24(月) 21:18:49 ID:3dHm5YQ9
こんなレコードが格納されているとします。
ID,NO
100,1
102,2
101,3
200,1
201,2
202,3
この場合、IDを100番台、200番台でグルーピングして、各グループ毎にNO順にSELECTで出力しようとした場合、どのような条件にすればよいでしょうか?
IDはこの例では3桁ですが、実際には6桁程あり、出来ればWHERE句で数字を入れて指定するような事はせずに並び替えが出来ると嬉しいです。
要は、レコードが増えてグループが増えたりしても、条件を変えずに並び替えが出来るようなものが良いのですが、可能でしょうか?
宜しくご教示願います。
816815:2011/01/24(月) 21:20:43 ID:???
すみません、補足です。
>815は出力結果の並び順と思って頂ければよいです。
実際にはレコードの順番は滅茶苦茶だったりします。
IDで並べ替えてから、NOで並べ替えるという事が出来ればきっと実現出来ると思うのですがやり方がわからなくて・・・orz
817NAME IS NULL:2011/01/24(月) 21:41:41 ID:???
IDを100で割った値(切り捨て)、NOでソート。
818NAME IS NULL:2011/01/24(月) 21:49:51 ID:???
order by floor(ID/100), NO
819815:2011/01/24(月) 22:26:31 ID:???
おぉ、なるほど!お二方、どうも有難う御座います!
820NAME IS NULL:2011/01/25(火) 12:25:17 ID:92np3pBK
eventId / eventName / userId の3つのカラムがあるイベント登録用テーブル(tableE)があります。
これに対して、
reportId / reportTxt / userId / eventId の形のイベントの感想用テーブル(tableR)を作ってます。

この時 tableE.eventId==tableR.eventIdとしたいです。(※)

この条件で、tableRへのinsertクエリを書くとしたらどうすべきでしょうか。
プログラム(php)からはeventIdがパラメータ(getメソッド)で送られてくるので
単純にその値をセットしてのinsertは出来るんですが、getメソッドのためユーザーが
いくらでもeventIdを変更できてしまいます
sql文だけで、(※)の条件を実現することは出来ますか?
サブクエリ?を使うのかなと思ったもののよくわかりません
821NAME IS NULL:2011/01/25(火) 13:28:46 ID:???
なんていうか、つっこみどころ満載だな

eventIdは誰が発番するんだ?
tableEとtableRのどの行(どの条件)がeventIdが等しくならないとだめなんだ?

SQLの問題じゃなくて、まず仕様をちゃんと明確にしろよ
822820:2011/01/25(火) 13:55:40 ID:92np3pBK
>>821
ありがとうございます

>eventIdは誰が発番するんだ?
tableEのeventIdは主キーでオートインクリメントです、書き忘れました、すみません。

>tableEとtableRのどの行(どの条件)がeventIdが等しくならないとだめなんだ?
「この時 tableE.eventId==tableR.eventIdとしたいです。(※)」ってことです

下記のクエリで、イベント(eventIdは100)の感想を登録できるんですが
INSERT INTO tableR (reportId,reportTxt,userId,reportId) VALUES (0, '面白かった',10,5);

これだとURLの &eventId=5 の部分をユーザが50とか500とか勝手に書き換えた上で
そのままインサートできてしまいます。
感想レポート記入画面で、パラメータのeventId(とuserId)を条件にtableEにチェックのクエリを
実行すれば良いのはもちろんですが、そうではなく感想レポートの登録クエリ時に
チェックしたい(insert文の一部として)と思っています
そんなことは出来るんでしょうか?
823NAME IS NULL:2011/01/25(火) 16:37:44 ID:???
FOREIGN KEY
824NAME IS NULL:2011/01/25(火) 19:12:36 ID:???
だからこの時ってのはどの時なんだよ
eventIdが5じゃないとダメな理由は?
tableEに存在しないeventIdはダメっていうなら>>823
でも5も50も500もtableEに存在してるなら、5はよくて50や500がダメな理由はなんだ?
825NAME IS NULL:2011/01/25(火) 19:44:09 ID:???
なんでそんな怒ってるんだよw

>>820=>>822
tableE に存在しさえすればユーザが勝手に eventId を指定してきても良い
ってことなら >>823 の通り tableR の eventId を外部キーにすればいい。

そうじゃないならそのデータはクライアントから受け取るべきじゃない。
サーバ側で保持すべき。
826825:2011/01/25(火) 19:45:20 ID:???
あ、「そのデータ」ってのは eventId のことね。
827NAME IS NULL:2011/01/25(火) 19:46:14 ID:???
>「この時 tableE.eventId==tableR.eventIdとしたいです。(※)」ってことです
がわけわかめなんだよね。

「この時 tableE.eventId=tableR.eventIdでなければ(=存在しないtableE.eventIdであれば)エラーにしたい(INSERTしたくない)」
なら意味がわかる。

>感想レポート記入画面で、パラメータのeventId(とuserId)を条件にtableEにチェックのクエリを
>実行すれば良いのはもちろんですが、そうではなく感想レポートの登録クエリ時に
>チェックしたい(insert文の一部として)と思っています
>そんなことは出来るんでしょうか?
からすると823でいいんじゃないかと思うけど、結局のところGETなら何が来るかわからないので、SQLとは別なんだけど
投稿する前にセッションとかにeventIdを保存しておいてGETでは渡さないという工夫も必要かも。
828NAME IS NULL:2011/01/25(火) 20:08:25 ID:???
なんとなく基本的なやつ貼っとく

安全なWebアプリ開発40箇条の鉄則
ttp://java-house.jp/~takagi/paper/idg-jwd2003-takagi-dist.pdf
829NAME IS NULL:2011/01/27(木) 09:33:36 ID:???
どこかのプロジェクトで、SQLで四則演算してはいけない という
コーディングルールがあったんだけど、その理由を失念してしまいました。
なにか、該当するような事象ってあるんですかね?計算結果がおかしくなるとか.
830NAME IS NULL:2011/01/27(木) 14:16:13 ID:xnnaktpA
MySQL 5.1を使っているのですが、
リストにabc,def,ghiのように単語が登録されているとき、
"hogehogeabchogehogehogeghihogejklhogehoge"という文から、
abc,ghiという単語がこの文に含まれているというような検索をしたいのですが、書き方がわかりません。
それ以前に、データベースでこのような検索は可能ですか?
831NAME IS NULL:2011/01/27(木) 18:10:00 ID:???
>>829
桁数とか丸め誤差がアプリケーションと違っちゃうのが嫌だったとか

>>830
where COL_NAME like '%abc%' and COL_NAME like '%ghi%'
とか?
832NAME IS NULL:2011/01/28(金) 01:13:12 ID:sGatbyEv
>>831
リストには数百個あるので、それだと結構大変かもしれないです。

具体的には、文の中でリストにある単語のどれが出たかを出力するものを制作しています。
単語ごとに区切ってデータベースにアクセスすればできそうですが、制約上単語ごとに区切れないもので・・・。
833NAME IS NULL:2011/01/28(金) 01:20:31 ID:???
単語が複数見つかった場合はどうすんだろ。
834NAME IS NULL:2011/01/28(金) 03:08:55 ID:???
リストというテーブルの単語という項目に単語が含まれてるとして

select 単語 from リスト
where 対象の文 like '%' + 単語 + '%'

こんな感じってことじゃ?
(+で文字列連結できる前提な)
MySQLで動くかどうかしらんが
835NAME IS NULL:2011/01/28(金) 03:51:46 ID:uBEDX4Y3
文って単数なの、
複数なの(テーブルにひとつの項目として保存されてるの)?
836NAME IS NULL:2011/01/28(金) 06:55:13 ID:???
Prologの回答だと、
http://nojiriko.asia/prolog/sql10_830.html

findallという述語がSELECTに似ているから、ここの住人は
解ると思う。
837NAME IS NULL:2011/01/28(金) 07:03:57 ID:???
上の回答は単語数100などは想定していない。
このままコードで単語数が10数個を越えたら、
組み合わせの処理でスタックオーバーフローに
なって失敗する。
length(_単語ならび,Len) を止めて、単語の
最大数(現在のLen)を限定して指定する必要が
あります。
838NAME IS NULL:2011/01/28(金) 11:04:32 ID:???
スレ違いかつ要件を満たしていないことを自信満々に言われてもどうしたらいいのか
839NAME IS NULL:2011/01/28(金) 11:10:44 ID:???
スルーすればいいよ。
840NAME IS NULL:2011/01/28(金) 11:36:31 ID:???
スレ違いは覚悟の上なんだが、ここで指摘したかったのは
リストからどのように検索対象を取り出すかということ。
この質問はその部分があいまい。全部の可能性を考えると
こんなアルゴリズムになりますよというのが >>836
あとから>>832を読んで、数百個あるので、というところで
マイッタw
841NAME IS NULL:2011/01/29(土) 10:06:10 ID:Kh+BN3Cq
>>833
単語が重複した場合が数えません。

>>835
文は特にデータベースに保存しません。
単語数のみをデータベースに保存していきます。

やっぱりデータベースで全てやるのは難しいみたいですね・・・。
Perl等で単語をデータベースから1個ずつ引っ張って、文の中に含まれるかを検索するほうが無難かもしれませんね。

ありがとうございました。
842NAME IS NULL:2011/01/29(土) 10:21:46 ID:wMofn+ab
>>841

それだったら>>834ちょこっと変えればいけるんじゃないの
文の結合はoracleだったら||でやればいいし
あとはGROUP BY 単語 をかませれば単語毎のカウントもできるだろ
843NAME IS NULL:2011/01/29(土) 11:24:53 ID:wMofn+ab
やっぱSQLじゃ無理そうだな
同じ一文だとカウントされそうもないや
全部一件になるな
844NAME IS NULL:2011/01/29(土) 17:58:38 ID:???
>>834のcountでなにが悪いのかがわからんや
845NAME IS NULL:2011/01/29(土) 18:13:29 ID:wMofn+ab
>>844
多分検索対象の文を一字づつ削った文
文の文字数分の行を用意しないとだめ
846NAME IS NULL:2011/02/01(火) 21:16:33 ID:???
・DBMS名とバージョン
 Microsoft Access2000

・テーブルデータ
【ITEM_COUNT】
item_id | year | month | count
---------------------------
00001  | 2010 |   1 |  150
00001  | 2010 |   1 |  400
00001  | 2010 |   2 |   20
  (中略)
00001  | 2010 |  11 |  120
00001  | 2010 |  11 |   50
00001  | 2010 |  11 |  200
00001  | 2010 |  12 |   30
00001  | 2011 |   1 |  500
00001  | 2011 |   1 |  100
00002  | 2010 |   1 |   10
00002  | 2010 |   2 |   30
00002  | 2010 |   2 |  100
  (後略)
※同じid, year, monthのデータが複数存在します。


・欲しい結果
item_id | 1月 | 2月 | … | 11月 | 12月 | 13月
--------------------------------------------
00001  | 550 |  20 | … | 370 |  30 | 610
00002  |  10 | 130 | … | (後略)

※2010/1〜2011/1の13ヶ月間を1月〜13月として(2011/1を13月として)それぞれ集計を求めたい


・説明
現状は、
------------------------------------
SELECT
 year, item_id
FROM
 ITEM_COUNT
WHERE
 year=2010
GROUP BY
 item_id, year
PIVOT
 Format(month,"#0月") In ("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
------------------------------------
上のクエリを「集計1」、WHERE句を"year=2011"に変更したものを「集計2」とし、
次のクエリで結果を求めています。
------------------------------------
SELECT
 集計1.item_id, 集計1.[1月], 集計1.[2月], … , 集計1.[12月],集計2.[1月] AS 13月
FROM
 集計1 LEFT JOIN 集計2 ON 集計1.[item_id] = 集計2.[item_id]
------------------------------------

しかしこれだと2011/1にのみデータがあるitem_idが集計から外れてしまいます。
これを回避するにはどのように直したら良いでしょうか。
847NAME IS NULL:2011/02/01(火) 21:36:38 ID:???
2010/01から2011/01までに存在するitem_idの一覧を求めるクエリに
集計1と集計2をleft outer joinすりゃいいんじゃね?
848846:2011/02/01(火) 22:24:47 ID:???
>>847
レスありがとうございます。
なんとなくイメージが掴めたのでやってみます。
849NAME IS NULL:2011/02/02(水) 13:52:31 ID:???
k - Nearest Neighborがsqlで出来ると聞いたのですが
どんな書き方するのでしょうか
850NAME IS NULL:2011/02/03(木) 22:08:20 ID:???
SQL以外の言語でなら、どう書けばいいのか知ってるってこと?
そのアルゴリズムと、それが前提とするデータ構造を、RDB&SQLに移すだけなら、できるだろ。
それが効率がいいのかどうかは別の問題だが。

どんな書き方をするかというより、RDBと親和性の高いデータ構造を前提にした
効率のよいアルゴリズムがあるのかって話なんだろう。
851NAME IS NULL:2011/02/03(木) 23:03:29 ID:???
ほとんど見かけないのですが
SQLの計算量の良い資料ってあるんでしょうか
基本的な関係代数の
 和、差、交わり、直積、制限、射影、結合、商
ぐらいは知りたいです
852NAME IS NULL:2011/02/04(金) 02:14:27 ID:???
それが演算の話か結合の話か
演算の場合の計算量はめったに必要にならないと思うけど、それが必要?
結合の場合はプラン見たら大体分かるだろ
853NAME IS NULL:2011/02/04(金) 08:35:16 ID:???
>>852が関係代数を知らないことはわかりました
854NAME IS NULL:2011/02/04(金) 11:53:06 ID:???
ああ、関係代数って明記してんのか。
じゃあ何でわかんないんだ?って話じゃね?
855NAME IS NULL:2011/02/04(金) 19:55:24 ID:w30Vjyrb
はじめまして。
sql教えて欲しいです。

商品CD │ グループCD
────────────
01    A
02    A
03    B
04    A

このようなデータの中から02という商品CDが所属するグループの全ての商品CDを
抽出したいのですが、どのようなSQLがよろしいかと。宜しくお願いします。

856NAME IS NULL:2011/02/04(金) 20:04:49 ID:???
select 商品CD
from TableName
where グループCD = (select グループCD from TableName where 商品CD = 02);
857NAME IS NULL:2011/02/04(金) 21:29:31 ID:???
商品CDが主キーじゃなかったりしたらあれだから in 使う方がいいんじゃね
858NAME IS NULL:2011/02/04(金) 23:42:10 ID:???
2つの項目でユニークなマスターに、
元データの追加があったときだけInsertする方法を教えてください。

例えば、都道府県と市町村と日時だけのマスターテーブルがあります。

顧客データが更新された時、マスターにない都道府県と市町村のデータがあったら、
マスターに日時データをインサートして、
その市町村からの初めての登録日マスターみたないなテーブルを作りたいのですが、
よく分かりません。

教えて下さい。
859NAME IS NULL:2011/02/05(土) 02:14:30 ID:???
トリガでいいんじゃないのかな。
860NAME IS NULL:2011/02/05(土) 02:54:34 ID:???
>>858
顧客データを都道府県、市町村でGROUP BYして登録日の最小をとるのではダメ?
861859:2011/02/05(土) 06:35:55 ID:???
顧客データの更新時を考えるとちょっとそれ面倒だなぁとおもって、トリガを薦めてみたよ。
862NAME IS NULL:2011/02/05(土) 19:21:13 ID:???
mergeが使えるならそれで行けるかも

だめなら素直にselectしてデータあるか判断してからinsertすれば?
ホストアプリでやるかストアドやトリガでやるかはお好きに

863860:2011/02/06(日) 09:05:35 ID:???
>861, 862
ちょと勘違いしてるっぽいネ。

顧客データを都度検索すれば「その市町村からの初めての登録日」は取得できるから、「都道府県と市町村と日時だけのマスターテーブル」を作らないって手もあるよということ。
参照の頻度や検索コストにもよるけど。
864860:2011/02/06(日) 09:07:48 ID:???
顧客データの登録頻度が高くて、市町村登録日のリアルタイム性がそこまで必要ないのであれば、トリガより定期処理で更新するほうがよかったり、いろいろだね
865NAME IS NULL:2011/02/06(日) 11:39:24 ID:???
>>863
元々の質問者>>858の書いた通りに解釈すると
最初の出現日付ということになるから、その後
元データが削除されるとどうなるか、ですね。
866861:2011/02/07(月) 00:42:41 ID:???
>>863
そりゃあ、顧客情報の市町村情報を変更した日を別途持ってるならそれでいいとおもうよ。
けど、普通持たなくない?顧客情報の初期登録日時と最終更新日時くらいなら持ってる場合も多いだろうけど。
867NAME IS NULL:2011/02/07(月) 17:11:10 ID:Hb9WsdcY
はじめまして。ど素人なので教えを請いたいです。

・MySQL使用

・テーブルデータ
test_table

id|memo
--------
1| 1st
--------
1| win
--------
1| 1
--------
2| 1
--------
2| 2nd
--------

これをこっちからidやmemoの値を入力して、テーブルのその部分だけ表示させた
いのです。
例えば
・idの欄に1、memoの欄にwinを入力し、実行ボタンを押す
 ↓
id|memo
--------
1| win
--------
が表示される

・memoの欄に1を入力し、idは空欄
 ↓
id|memo
--------
1| 1
--------
2| 1
--------
が表示される


といったように、片方だけの入力でも両方の入力でもそれに対応したものが表示
されるものが作りたいのです。
どうかよろしくおねがいします。
868NAME IS NULL:2011/02/07(月) 19:36:00 ID:W2mKkHfb
869NAME IS NULL:2011/02/07(月) 20:04:54 ID:???
>>867
SELECT * FROM test_table
WHERE (id = 入力値1 OR LENGTH(入力値1) = 0)
AND (memo = 入力値2 OR LENGTH(入力値2) = 0)
870NAME IS NULL:2011/02/07(月) 23:32:17 ID:???
SELECT *
FROM test_table
WHERE
id = COALESCE(入力値1, id)
AND memo = COALESCE(入力値2, memo)
とか
871NAME IS NULL:2011/02/08(火) 10:46:05 ID:???
目指してる 未来が違うwwww byシャープ
http://twitter.com/kokoro_blog/status/6665171376275456 
872NAME IS NULL:2011/02/08(火) 17:39:34 ID:???
・DBバージョン
MySQL5.0.77

id | code | name
--+-----+------
1 | 10  | aaa
2 | 20  | bbb
3 | 20  | ccc
4 | 30  | ddd
5 | 30  | eee
6 | 30  | fff
7 | 40  | ggg
8 | 40  | hhh

・欲しい結果
(code)グループ単位でn件を取得する

・説明
code毎に抽出する行数の上限を指定したいです
postgresでは
http://blogs.wankuma.com/kacchan6/archive/2007/06/07/79946.aspx
oracleでは
http://www.ne.jp/asahi/hishidama/home/tech/oracle/rownum.html#TopN_partition_by
のようなことをmysqlで書きたいです
よろしくお願いします

873NAME IS NULL:2011/02/08(火) 20:01:27 ID:???
・DBバージョン
MySQL5.0.77

id|_regDate_|
--+----------+
1 |2010-10-10|
2 |2010-10-10|
3 |2010-10-10|
4 |2010-10-11|
5 |2010-10-11|
6 |2010-10-11|
7 |2010-10-11|
8 |2010-10-12|
9 |2010-10-12|
10|2010-10-12|
11|2010-10-12|

・欲しい結果
何件レコードがあったかを日別に出力したい。

例として
_regDate__|件数
----------+-
2010-10-10|3
2010-10-11|4
2010-10-12|4

こうなってるとうれしいです。

・説明
自前でクリックカウンターを作っております。
ほかにカラムとしてユーザーエージェントやリモートホストのアドレスを設置してありまして
日別に集計して見れるようにしたいと思ったのですが、PHPでループを書いて出力するより
SQLの問い合わせ段階で、上記のように整形できないかなと思いました。

よろしくお願いいたします。
874NAME IS NULL:2011/02/08(火) 21:49:08 ID:???
count, group by あたりでググレよ。
日付順にもしたいだろうから order by もいるかな。

ちなみに、2010-10-11|0 も欲しいとか言うなよ。
875873:2011/02/09(水) 00:29:44 ID:???
ヒントありがとうございます。
なるほど。GOURPってイマイチ、何に使うのかピンと来なかったのですが
納得しました。

SELECT DATE_FORMAT( RegDate, '%Y年%m月%d日' ) , count( RegDate )
FROM accessLog
GROUP BY RegDate

>ちなみに、2010-10-11|0 も欲しいとか言うなよ。
欲しいですが…なんとかします。

本当にありがとうございましたー。
876NAME IS NULL:2011/02/09(水) 01:58:47 ID:???
postgresqlのgenerate_seriesかなんかみたいなやつのmysql版はないのかな
877NAME IS NULL:2011/02/09(水) 11:49:03 ID:nceEl1Ww
「PGDATAのデフォルト」を知りたい人がいるのですが、
次のページを推薦しようかと思うのですが、
的はずれでしょうか。それともそれなりに役立ちますか?
私は素人です・・・(>_<)

http://www50.tok2.com/home/oppama/pg2.html

878877:2011/02/09(水) 14:51:45 ID:???
自己解決しました。
879NAME IS NULL:2011/02/11(金) 13:53:41 ID:???
・DBMS名とバージョン
oracle9i / 10g
・テーブルデータ
部署ID 大分類 中分類 小分類 予算
-------+------+-------+------+---
01 01 01 01 2500
01 02 01 01 1000
01 02 02 02 100
02 01 01 01 100
02 01 02 02 0
02 02 02 02 1000
02 03 01 01 0
03 01 01 01 500

・欲しい結果
上のテーブルの時、
(大分類=01and予算>50) and (大分類=02and予算<2000)
の部署IDを取得したい。
・説明
とりたい結果は01,02ですが上のSQLを
そのまま書くと当然結果はnullですし、
括弧の間のandをorにすると03も取得されてしまいます。
なにか良い方法はないでしょうか?
880NAME IS NULL:2011/02/11(金) 14:00:44 ID:???
まず条件を日本語で説明してみろよ。
881879:2011/02/11(金) 14:24:55 ID:???
大分類が01で予算が50以上、かつ、大分類が02で予算が2000以下、
という両方の条件を満たすレコードを持つ部署IDを取得したい、ということです。

解りずらかったらすみません。
882NAME IS NULL:2011/02/11(金) 14:36:17 ID:???
WHERE (大分類=01 AND 予算>50) AND (大分類=02 AND 予算<2000)
でいけんじゃないの
883NAME IS NULL:2011/02/11(金) 14:45:44 ID:gp61lhlu
相関副問合せでNOT EXISTS使え
条件はそれぞれの逆条件でorで結びつけろ
884NAME IS NULL:2011/02/11(金) 14:55:08 ID:???
>>881
> 大分類が01で予算が50以上、かつ、大分類が02で予算が2000以下、
> という両方の条件を満たすレコード

ひとつのレコードには大分類はひとつしかないんだから、

大分類が 01 で かつ 大分類が 02 のレコード

なんてあるわけないだろ。

どうせ、(大分類 01 で予算 50 以上) と (大分類 02 で予算 2000 以下) の両方の
レコードをもつ部署 ID が得たいんだろうな。

どうすればいいかは、すぐには思いつかないけど…。
885NAME IS NULL:2011/02/11(金) 14:59:52 ID:???
副問い合わせかintersect使え
886879:2011/02/11(金) 15:03:36 ID:???
>>882
そのSQLだと結果が得られません。
>>883
ありがとうございます、調べて実践してみます。
>>884
その通りです。
テーブル設計から変えるべきでしょうか?
887NAME IS NULL:2011/02/11(金) 15:04:44 ID:gp61lhlu
WHERE (大分類 01 で予算 50 以上)
EXISTS(SELECT * FROM table b
WHERE a.部署ID = b.部署ID
and (大分類 02 で予算 2000 以下)
)

だな
888NAME IS NULL:2011/02/11(金) 15:05:23 ID:???
Oracleならintersectでいいんじゃね?

select 部署ID from TableName where 大分類=01 AND 予算>50
intersect
select 部署ID from TableName where 大分類=02 AND 予算<2000
;
889NAME IS NULL:2011/02/11(金) 15:23:16 ID:???
>>879
パターン1
条件のどれかに合う行の部署ID, 大分類のペアを重複無しで
出してから部署IDでGROUP BY、個々のグループに含まれる
行数で絞り込む。
例のように条件が2個であれば、各グループに2行含まれて
いれば両方の条件にマッチすることになる。

SELECT 部署ID
FROM (
SELECT DISTINCT 部署ID, 大分類
FROM T
WHERE
(大分類=01 AND 予算>50) OR
(大分類=02 AND 予算<2000)
)
GROUP BY 部署ID
HAVING COUNT(*) = 2

パターン2
条件1にあう部署ID、条件2に合う部署ID...をそれぞれ
求めてから、全ての論理積を取る。
分かりやすくするため下の例ではINTERSECTを使って
いるが、JOINを使ってもEXISTS述語を使っても似たよう
なことは出来る。

SELECT DISTINCT 部署ID
FROM T
WHERE 大分類=01 AND 予算>50
INTERSECT
SELECT DISTINCT 部署ID
FROM T
WHERE 大分類=02 AND 予算<2000
890NAME IS NULL:2011/02/11(金) 15:39:13 ID:???
一番素直なやり方はinをandで結べば良いだけなんじゃ?
select ....
where
部署ID in (select 部署ID from table where 大分類=01and予算>50 )
and
部署ID in (select 部署ID from table where 大分類=02and予算<2000)
891NAME IS NULL:2011/02/11(金) 18:07:46 ID:???
一番素直なのはexistsだとおもうけど、どれでもいいと思うよ。
あと、>>884が「どうせ」という言葉を出してるところに驚いた。
892NAME IS NULL:2011/02/11(金) 19:12:49 ID:???
existsだと相関サブクエリ必要じゃね?
まあたしかにどれでも良いんだけど
893879:2011/02/11(金) 19:12:52 ID:???
>>885
>>887
>>888
>>889
>>890
>>891

皆さんありがとうございます。
ご教授いただいた方法の中からプログラムに最適な方法を選択しようと思います。
894NAME IS NULL:2011/02/11(金) 21:09:15 ID:???
INTERSECT が有効な場面を初めて見た。
895NAME IS NULL:2011/02/13(日) 20:43:39 ID:4kN5gBix
MYSQLで動的ホームページを作っています。
fileテーブルにそれぞれのページのデータを保存していて
accessテーブルにアクセスログを保存しています。

fileテーブルにはAIのページIDカラムがあり
accessテーブルにはアクセスされたページのIDカラムがあります

ページ一覧ページで各ページのアクセス数を表示したいです。
SELECT * FROM fileの結果と、SELECT count(*) FROM access WHERE id='アクセスされてページのID'の結果を結合させるSQL文を教えてください。

いまはPHPで
$query="SELECT * FROM file ORDER BY id DESC LIMIT";
$result=mysql_query($query);

while ($row = mysql_fetch_array($result)) {
$query2="SELECT count(*) AS id FROM access WHERE id = {$row['id']}";
$result2=mysql_query($query2);
$row2= mysql_fetch_array($result2);
}

という書き方をしていますが、クエリを一回で済ませたいです。
よろしくお願いします。
896NAME IS NULL:2011/02/13(日) 20:50:57 ID:???
select T1.*,
    T2.cnt
from file T1
   inner join
   (select id,
       count(*) as cnt
   from access
   group by id) T2
   on T1.id = T2.id
;
897NAME IS NULL:2011/02/13(日) 20:50:58 ID:???
まずは、inner join とかでググレ。
898NAME IS NULL:2011/02/13(日) 21:15:08 ID:???
joinいらんだろ?

select t1.*,(select count(*) from access where id=t1.id) as cnt from file t1

でできないのか?
899NAME IS NULL:2011/02/13(日) 21:17:25 ID:4kN5gBix
>>896
願いどおりの結果になりました。
ありがとうございました。
900NAME IS NULL:2011/02/13(日) 21:18:02 ID:???
>>898
joinしてるやん
901NAME IS NULL:2011/02/13(日) 21:20:26 ID:4kN5gBix
>>898
こっちでも出来ました。

しかし自分には違いがわからない。
902NAME IS NULL:2011/02/13(日) 21:22:31 ID:???
結果は同じなんだが、サブクエリもjoinなのか?
903NAME IS NULL:2011/02/13(日) 21:25:12 ID:???
id=t1.id ←ここが結合条件
904NAME IS NULL:2011/02/14(月) 00:12:11 ID:???
相関サブクエリをJOINというのは珍しいような。全部JOINになるな
905NAME IS NULL:2011/02/14(月) 00:29:56 ID:???
相関でもいいけどそれはスカラサブクエリって呼ぼうぜ。
JOINとは呼ばんけどやってることは広義の外部結合だわな。
906NAME IS NULL:2011/02/14(月) 00:59:41 ID:???
ああ、確かに。相関じゃないなすまん。
907NAME IS NULL:2011/02/14(月) 23:42:44 ID:???
相関サブクエリー(サブクエリが外部クエリの現在評価中の行に依存する)だし
同時にスカラーサブクエリー(結果が必ず一行一列)だよ。
この二つは直交する概念だから、組み合わせもごく普通にあり得る。
908NAME IS NULL:2011/02/14(月) 23:47:12 ID:???
つーかMySQLのJOINって>>896みたいな変態チックなやつなのか
909NAME IS NULL:2011/02/15(火) 03:39:43 ID:???
きわめて一般的な形に見えるけど、どのあたりが変態チックにみえたんだろ
910NAME IS NULL:2011/02/15(火) 23:51:15 ID:???
言えない
AS句がなかったからサブクエリをそのままだと脊髄反射で読み替えてしまっただなんて
言えない
911NAME IS NULL:2011/02/16(水) 00:00:52 ID:???
ASを句とは言わない。
912NAME IS NULL:2011/02/17(木) 16:46:06 ID:???
データベースのファイルを読み込んでもどんなテーブルが作成されているのか
分からなければ、SELECT文で命令しようもないと思うのですが、
テーブル一覧を表示させるための方法をネットで調べると、
データベースソフトの種類によって、どれもまちまちなんですね?
SQLで統一された構文があるかどうか探してみたのですが、よく分からなかったです。
913NAME IS NULL:2011/02/17(木) 17:43:28 ID:???
>912
思いつくキーワードと共にSHOWでググルヨロシネ。
914NAME IS NULL:2011/02/17(木) 19:02:53 ID:???
SHOW TIME;
915NAME IS NULL:2011/02/17(木) 20:46:18 ID:???
>>913
そんな話じゃないだろうに。
916NAME IS NULL:2011/02/17(木) 20:47:39 ID:???
って、それだけじゃよくないな。

>>912
統一された構文はないよ
917NAME IS NULL:2011/02/19(土) 09:29:43 ID:???
>>912
各RDBMSによって異なるので、統一的なものはありません。

Oracle準拠のSQLの実装に熱心なPostgreSQLやMySQLでも、
さすがにありません。
918NAME IS NULL:2011/02/19(土) 09:30:54 ID:???
>>914
hocus‐pocus
919NAME IS NULL:2011/02/19(土) 09:52:42 ID:???
>>916
SQLの設計思想の問題、といえばいいのだろうか。
920NAME IS NULL:2011/02/19(土) 09:58:02 ID:???
SQL標準にないのに真似したら訴えられそうだからとか
相手優れていることを認めたことになるとかいう消極的理由っぽ
921NAME IS NULL:2011/02/19(土) 10:06:12 ID:???
RDBMSごとにその中では統一されてるんだよね。
922NAME IS NULL:2011/02/19(土) 11:06:55 ID:???
>>912
INFORMATION_SCHEMA
923NAME IS NULL:2011/02/19(土) 11:17:44 ID:hGdu7TlU
初歩的ですみません、相関副問合せでinの仕組みを教えてください。

in句の使いかたとして、
select * from テーブル where フィールド1 in (値1,値2,値3)
みたいな使い方は素直に読めるのですが、


社員テーブル syain
id | name | busyoid |
------------------
1  | yamada |100 |
2  | satou |100 |
3  | suzuki |200 |

部所テーブル busyo
busyoid | busyomei |
------------------
100 | soumu |
200 | eigyo |

の2つのテーブルで、総務所属の人のみ抽出するとき、

select * from syain where 'soumu' in (select busyomei from busyo where busyo.busyoid = syain.busyoid)

で答えが出るとき、where 'soumu' in(select文)のin句の使い方はどう理解すれば良いのでしょうか。
924NAME IS NULL:2011/02/19(土) 11:22:21 ID:???
>>912
SQLレベルではバラバラだが、ODBCやJDBCなどでは規定があってドライバ側で
差異を吸収するようにされている。
CSEやEQなどODBC/JDBCを使ったツールならDBMSの種類によらずスキーマ
情報の表示が可能だし、自プログラムでならばそれらドライバマネージャの
APIを使う。
925NAME IS NULL:2011/02/19(土) 11:24:31 ID:???
>>923
(1)syainからレコードをひとつ取り出す
(2)そのレコードに対してサブクエリを実行して条件判定する
の繰り返しだと思えばいい
実際にそう動いているかは別としても、結果はそうなる
926NAME IS NULL:2011/02/19(土) 11:25:18 ID:???
> select busyomei from busyo where busyo.busyoid = syain.busyoid

によって、部署名の一覧が出るだろ? で↓のようになると。

> 'soumu' in ('soumu', 'soumu', 'eigyo')

一致する id=1、id=2の行が抽出されるってわけ。
927NAME IS NULL:2011/02/19(土) 11:25:23 ID:???
>>923
二重のFORループと考えれば良い
928NAME IS NULL:2011/02/19(土) 11:29:38 ID:???
てかクソみたいなSQLだな
それ作った奴殴っておけよ
929NAME IS NULL:2011/02/19(土) 12:30:28 ID:???
相関副問い合わせじゃなくていいし。
mysql> select * from syain where busyoid in (select busyoid from busyo where busyomei = 'soumu');
+------+--------+---------+
| id | name | busyoid |
+------+--------+---------+
| 1 | yamada | 100 |
| 2 | satou | 100 |
+------+--------+---------+
2 rows in set (0.00 sec)
930NAME IS NULL:2011/02/19(土) 12:40:29 ID:???
>>926
> 'soumu' in ('soumu')

しかでないのでは。
931930:2011/02/19(土) 12:43:35 ID:???
まちがえた。
> 'soumu' in ('soumu')
> 'soumu' in ('soumu')
> 'soumu' in ('eigyo')

がそれぞれでるのでは。
932NAME IS NULL:2011/02/19(土) 12:57:48 ID:???
where 'soumu' in ('soumu') は where trueと同じで3行表示される。
where 'soumu' in ('eigyo') は where falseと同じ。
933923:2011/02/20(日) 00:23:22.90 ID:f2cCeKTH
レス、ありがとうございます!
where true又はwhere falseで出力するしないを判断する記述なんですね。
目からウロコです。やっと理解できました。
ウラ技っぽいinの使い方ですね。
ありがとうございました!m(__)m
934NAME IS NULL:2011/02/20(日) 01:09:50.62 ID:???
>>929
select syain.* from syain join busyo using (busyoid) where busyomei = 'soumu';
のほうが素直な気もするけれど、どうなんだろね
935NAME IS NULL:2011/02/20(日) 02:43:07.06 ID:???
>>934
それが自然だし多分早い。
936NAME IS NULL:2011/02/20(日) 10:44:03.36 ID:???
>>934-935
俺もそう思うけど、SQL 始めたばかり頃は2重ループを作ればいいと
>>929 みたいに考えてた。

要するに、join をちゃんと理解してなかっただけだが。
937912:2011/02/20(日) 11:55:48.13 ID:???
>>912です。みなさん、いろいろご回答、どうもありがとうございました。
たいへん参考になりました。
938NAME IS NULL:2011/02/20(日) 17:19:41.11 ID:???
USINGなんて句があるのか
ポスグレのCOPYぐらいでしか見たことがない
知らんかったー
939NAME IS NULL:2011/02/20(日) 18:52:13.92 ID:???
カラム名が同じならちょっとだけすっきりしていいよ
940NAME IS NULL:2011/02/27(日) 00:23:41.31 ID:Lx8QjMnN
既存のテーブルのcreate文を確認する方法ってありますか?
ご存知でしたら教えていただきたいです。
941NAME IS NULL:2011/02/27(日) 00:51:43.34 ID:???
Oracle対応本が多いですが、MySQLとどのように違うのでしょうか?
Web系ではMySQLの方が多いと思うのですが、データウェアハウスとか事務系はOracleが多いのでしょうか?
942NAME IS NULL:2011/02/27(日) 01:50:33.55 ID:???
>>940
SQLで一般化された方法はない
つかってるDBMSのスレで聞いてみたら
943NAME IS NULL:2011/02/27(日) 09:45:34.25 ID:???
>>941
方言その他
944NAME IS NULL:2011/02/27(日) 10:39:18.44 ID:???
なんとなく新しめなシェア資料
ttp://www.itmedia.co.jp/enterprise/articles/1005/12/news011.html
ちょっとサンプル数が少ない気もするけど
945NAME IS NULL:2011/02/27(日) 11:08:48.21 ID:???
>>942
ありがとうございます。専門スレで聞いてみます
946NAME IS NULL:2011/02/27(日) 19:33:10.12 ID:???
>>941
DBへの考え方が根本から違う。
けれどSQL一般で言えばどちらも方言を含有した英語程度に共通。
947NAME IS NULL:2011/02/28(月) 10:48:57.63 ID:???
用途はやっぱMySQLはWeb、Oracleは事務でしょうか?
948NAME IS NULL:2011/02/28(月) 17:18:48.47 ID:???
お金がある人はOracle、無い人はMySQL
949NAME IS NULL:2011/02/28(月) 17:52:06.92 ID:???
変人さんはPostgreSQL
950NAME IS NULL:2011/02/28(月) 18:57:26.03 ID:???
PostgreSQLのシェアがMySQLより低いのが相変わらず謎。
なんでMySQLなの?
951NAME IS NULL:2011/02/28(月) 19:45:08.70 ID:???
簡単だからでしょ
952NAME IS NULL:2011/02/28(月) 19:50:32.19 ID:???
管理が?
953NAME IS NULL:2011/02/28(月) 21:38:49.06 ID:???
MySQLは早くから(当初から?)Windowsに対応していたしね。
ちなみにPostgreSQL本家のみなさんは、名前が長く発音しにくいのが問題では?
と、一時期名称変更を検討したらしいw
ただ、日本のシェアはこれでも他所と比べて高いらしく、
石井氏が名前の所為じゃないと反論していました。
954NAME IS NULL:2011/02/28(月) 21:42:56.81 ID:???
本屋に行ってDBの勉強しようと探したら、MySQLの本はあってもPostgreの本なんて見つからん
(大きな本屋に行けばそれなりにあるけどさ
955NAME IS NULL:2011/02/28(月) 21:47:24.63 ID:???
いらねーだろそんなもん。
956NAME IS NULL:2011/02/28(月) 21:57:39.08 ID:???
PostgreSQL は Postgres + SQL でダブってる S をひとつにしちゃった名前
なんだけど、ここが敗因だという説にはひとつの説得力があるような気もする。

知らない人には当然 Postgre + SQL にしか見えないし
そう見えちゃうと何て読むのか分かんない。
957NAME IS NULL:2011/02/28(月) 22:01:28.96 ID:???
そういえばSQLite も読み方がわからなくて使う気にならない
958NAME IS NULL:2011/02/28(月) 22:21:40.83 ID:???
そろそろ次スレだけどテンプレ追加は >>222 でいいのかな?

それと >>2http://oraclesqlpuzzle.hp.infoseek.co.jp/
の後継サイトは http://www.geocities.jp/oraclesqlpuzzle/ でいいの?
959NAME IS NULL:2011/02/28(月) 22:24:08.78 ID:???
DBの研究開発界隈には何故か画家の名前が時々ある。
PostgreSQLの名前もIngresから来たものだし。
960NAME IS NULL:2011/02/28(月) 22:28:21.30 ID:???
961NAME IS NULL:2011/03/01(火) 00:21:00.42 ID:???
なぜか昔、PostageSQLに空目して、しばらくポステージだと思ってたのは内緒
962NAME IS NULL:2011/03/01(火) 00:26:23.55 ID:???
"PostageSQL" - Google 検索
約 5,120 件 (0.06 秒)
963NAME IS NULL:2011/03/01(火) 02:45:53.56 ID:???
>>953
日本人からすると、マイSQLなんて名前だと、業務に使うには力不足なのかと思ってしまうんじゃないかな。
PostgreSQLがMySQLに比して日本語に強かったのもあるだろうけど。

マイドキュメントとかマイピクチャとかマイにはうんざりしてるんですよ。
964NAME IS NULL:2011/03/01(火) 03:05:49.93 ID:???
>>222より>>224の方がいいと思うが
それならお前が立てろと言われてもあれなんで全面的に>>958にまかした
965958:2011/03/01(火) 06:22:03.74 ID:???
立てれんかった・・・

>>222は、間をとってこんな感じでどう?

(問)
年月(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ならこれを適当に改変すれば動きますが
 どのみちお奨めしません。
966NAME IS NULL:2011/03/01(火) 13:14:30.96 ID:???
generate_seriesって賛否が分かれるのか。。。
967NAME IS NULL:2011/03/02(水) 15:49:08.57 ID:Jy55ShzU
教えてください。
■DBMS名とバージョン
Firebird 1.03
■テーブルデータ (注文データベースのようなものです)
・Main 主情報テーブルMIDがキー
MID HACCHUBI
1 2011/03/01
・DETAIL 明細テーブルDIDがキー MID,IIDが参照キー
DID MID IID KOSU
1  1  1  100
2  1  2  30
・ITEM 商品テーブルIIDがキー
IID NAMAE ZAIKO OPOINT BIKO
1  HOGE  20  10   0
2  HUGA  50  5    1
■欲しい結果
2011/1/1から1/31の注文のあった各アイテムの個数(DETAIL.KOSU)の平均値が10以上の場合、
該当するアイテムの注文ライン(ITEM.OPOINT)に、その平均値を入れて更新。平均値が10未満の場合、
ITEM.OPOINTに0を入れる。ただしアイテムの備考(ITEM.BIKO)が1の場合は、ITEM.OPOINTには
空欄(NULL)にする。
■説明
といいますか、上記の欲しい結果が全てなのですが、どう書いていいのかちょっと見当がつきません。
在庫の仕入れをする個数(ITEM.OPOINT)の設定をコンピュータにさせようとしているのですが・・・。
丸投げで申し訳ありませんが、どなたかお願いします。
968NAME IS NULL:2011/03/02(水) 19:08:41.80 ID:???
GROUP BY,HAVING,AVG・・・
969NAME IS NULL:2011/03/02(水) 19:29:07.30 ID:???
こんな感じかなぁ。テストしてないしFirebirdで通るかよく解らん。
概念としてはこんな感じ。

UPDATE ITEM
SET
OPOINT = (
 SELECT
  CASE
   WHEN AVG(DETAIL.KOSU) >= 10 THEN AVG(DETAIL.KOSU)
   WHEN ITEM.BIKO = 1 THEN NULL
   ELSE 0
 FROM Main, DETAIL
WHERE
  Main.MID = DETAIL.MID
 AND
  Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND
  DETAIL.IID = ITEM.IID
)
WHERE EXISTS (
 SELECT * FROM Main, DETAIL
 WHERE
  Main.MID = DETAIL.MID
 AND
  Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND
  DETAIL.IID = ITEM.IID
)
970NAME IS NULL:2011/03/02(水) 19:30:11.53 ID:???
説明でよく解らん点は以下の二点。

> 注文のあった各アイテムの個数

とあるけれども、最低一個でも注文があったアイテムの行だけ更新の
対象にするのかな。それとも全く注文がなかったアイテムは平均値0
として考えるのかな。後者なのなら上記のクエリのWHERE EXISTS以下
は削除する。

> ただしアイテムの備考(ITEM.BIKO)が1の場合は

平均値が10未満でBIKOが1の場合はNULLを入れる。これは疑いがない。
でも平均値が10以上でBIKOが1の場合はどうなんだろう?
もしこの場合もNULLを入れるのであれば、CASE文の二つのWHENの順序
を入れ替える。
971NAME IS NULL:2011/03/02(水) 20:40:49.41 ID:???
1文でできなくはないけど邪魔くさいなぁ
俺なら
1 平均値でOPOINTを更新
2 OPOINTが10未満を0に更新
3 BIKOが1ならNULLに更新
の3ステップでやるが
972967:2011/03/02(水) 22:22:06.44 ID:???
>>969,970
ありがとうございます。中途半端な説明ですみません。
・最低一個でも注文のあったアイテムのみ更新
・BIKOが1であれば、平均値に関わらずNULLを入れる。
です。
■平均値を求める際、GROUP BY が必要と思っていたのですが不要なのでしょうか。
>>971
ありがとうございます。1 平均値でOPOINTを更新 なのですが
これは、SET OPINT = 平均値のSELECT文 WHERE EXIST 期間のSELECT文 で該当するアイテムの
OPOINTが更新されるのでしょうか?
つまり、(書き方が間違っているのでご指導ください)
UPDATE ITEM SET OPINT = (
SELECT AVG(DETAIL.KOSU) FROM Main, DETAIL
WHERE Main.MID = DETAIL.MID AND Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND DETAIL.IID = ITEM.IID
GROUP BY ITEM.IID
) WHERE EXISTS (
SELECT * FROM MAIN, DETAIL
WHERE Main.MID = DETAIL.MID AND Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND DETAIL.IID = ITEM.IID
GROUP BY ITEM.IID;
あぁ全然ダメです。グループ化するITEM.IIDが表示項目にないから通らないと
思います。どうしたらよいでしょう。
■副照会(?)を用いた更新のやり方
■平均値の出し方(使い方)
(単純に平均値を表示するなら
SELECT ITEM.IID, AVG(DETAIL.KOSU) FROM MAIN, ITEM, DETAIL
WHERE .... GROUP BY ITEM.IID でいけると思うのですが)
973NAME IS NULL:2011/03/02(水) 22:56:59.02 ID:???
>>972
ちと訂正。>>969の"ELSE 0"のあとにENDを忘れていた。
あとGROUP BYはいらないよ。
SELECT AVG(T.a) FROM T WHERE T.b = "B1" なんて
クエリはGROUP BYが無くても通るよね。それと同じ。

あとSELECT AVG(T.a) FROM T GROUP BY T.b も正しい。
GROUP BYでT.bが指定されたからといって、必ず選択リストに
T.bを含める必要があるかというと、それは無いわけで。
974NAME IS NULL:2011/03/02(水) 23:51:04.54 ID:???
>>972
group byは表示する項目じゃ無くても通ると思うけど、fromにITEMはないから
ITEM.IIDではなくDETAIL.IIDでgroup byする必要がある
where条件でDETAIL.IIDが搾られてるから、あっても無くても同じ結果になるが

existsのサブクエリは集約関数つかってないのでgroup byなんてそもそも不要

975NAME IS NULL:2011/03/02(水) 23:58:08.00 ID:???
>>974
文法的にはそのGROUP BYも必要ない。
あっても通るし結果も同じだけど。
976967.972:2011/03/03(木) 11:52:28.41 ID:???
GROUP BY の項目が表示項目でないと通らないと思ってました。
さて、GROUP BY をつけないと、全部の平均値になってしますのですが
どこがいけないのでしょうか。
SELECT AVG(DETAIL.KOSU) FROM Main, DETAIL, ITEM
WHERE (Main.MID = DETAIL.MID)
AND (Main.HACCHUBI BETWEEN '01/01/2011' AND '01/31/2011')
AND (ITEM.IID = DETAIL.IID)
--GROUP BY DETAIL.IID
;
GROUP BY有りだと期待通り、各アイテムごとの個数の平均値を抽出できるのですが
GROUP BY無しだと、アイテム全部の個数の平均値(例"12"の1レコードのみとなって
しまいます。
■書き方が間違っていますでしょうか。
■GROUP BY無しをUPDATE ITEM SET OPOINT = (SELECT AVG(...とすると
全てに全体の平均値が入ってしまうと思うのですが・・・。
(WHERE EXISTS句も同様の間違いで動作しない可能性もありますが)
977NAME IS NULL:2011/03/03(木) 14:00:33.15 ID:???
>>976
969や972のクエリを見てもらえれば分かるけど、内側のクエリの
FROM句にITEMテーブルは指定されていないよね(指定しちゃダメだよ)。
ITEMテーブルは外側のUPDATE文の中で指定されている。

このようにサブクエリの中から外側のクエリのテーブルを参照する
のを「相関サブクエリ」というので、調べてみると良いと思う。
この例だと、内側のクエリのITEM.IIDには「UPDATE文が現在処理
しているITEMテーブルの行のIID」が入る。なので内側のクエリ全体
では、「UPDATE文が現在処理しているITEMテーブルの行のIIDに
対応するアイテムの発注量の平均」を計算することになる。

>>976のクエリの場合だと、GROUP BY無しだと全体の平均値が
「ただ一つ」だけ出てくるよね。これも正解。というかこの例では
内側のクエリの答えは必ず一行一列でなければならない。
SELECT文の選択リストやUPDATE文の更新値としてサブクエリを
書くときは、そのサブクエリは結果として必ず一行一列を返す必要
がある(スカラーサブクエリ)という規則があって、クエリを書くとき
も結果がただ1行であることを保証しなくちゃいけない。
なので内側のクエリにはGROUP BYは付けるべきじゃない。むしろ
実装によってはGROUP BY付けるとエラーで弾かれるかも。

いずれにしても相関サブクエリにする事で内側のクエリは「UPDATE
文が現在処理しているITEMテーブルの行のIIDに対応するアイテムの
発注量の平均」を返すので、問題はない。
978NAME IS NULL:2011/03/03(木) 14:04:30.38 ID:???
>>976
心配だったらこんなクエリを実行してみたらどうだろう。
SELECT
 ITEM.*,
 (SELECT AVG(DETAIL.KOSU)
 FROM Main, DETAIL
 WHERE
  Main.MID = DETAIL.MID
 AND
  Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND
  DETAIL.IID = ITEM.IID
 ) AS NEW_OPOINT
FROM ITEM
WHERE EXISTS (
 SELECT * FROM Main, DETAIL
 WHERE
  Main.MID = DETAIL.MID
 AND
  Main.HACCHUBI BETWEEN '01/01/2011' and '31/01/2011'
 AND
  DETAIL.IID = ITEM.IID
)
979NAME IS NULL:2011/03/03(木) 20:04:10.37 ID:???
980踏んだ人は次スレよろ
980NAME IS NULL:2011/03/03(木) 20:50:42.07 ID:???
だが断る!
981NAME IS NULL:2011/03/04(金) 00:16:52.40 ID:???
こういうときは>>979がたてとけばいいんだけど、よくあるチキンレースですかね
982NAME IS NULL:2011/03/04(金) 03:28:32.89 ID:???
>>4の手法って何か呼び方があるのでしょうか?
あと、↓のような相関サブクエリで求める方法もよく見かけるのですが、
どちらの方が効率が良いのでしょう?

select A.ID,
    A.DATE,
    A.DATA
from TableName A
where A.DATE =
 (
  select max(B.DATE)
  from TableName B
  where A.ID = B.ID
 )

983NAME IS NULL:2011/03/04(金) 06:15:56.15 ID:???
>>982
データの偏りによってでが、サブクエリの呼び出しが一回で済む>>4の方が効率がよい。
ただ、WHERE句にもう一つ条件が付いて抽出される行が限定される場合で、>>982
サブクエリでインデックス検索が効く場合は>>982の方が速い時もある。
984NAME IS NULL:2011/03/04(金) 10:15:34.45 ID:???
982の方法は考え方が古そう・・・
985NAME IS NULL:2011/03/04(金) 15:16:19.82 ID:???
>>984
どう古いのかな
986NAME IS NULL:2011/03/04(金) 15:20:52.04 ID:???
古いってか、joinが一般的になる前から通用する方法だから
オーソドックスだと思うが
987NAME IS NULL:2011/03/04(金) 15:30:55.41 ID:???
joinが>>4の"inner join"句の事を言っているのであれば、
これが無くても>>4相当のことは相関サブクエリ無しで
出来るけど。
988976:2011/03/04(金) 15:39:25.12 ID:???
>>977,978
丁寧な解説ありがとうございます。
自分にとって新しい用語がたくさん出てきて勉強になります。
内容についての理解はまだ半分くらいですw
FROMにITEMを入れたのは、単純に平均値を出すSQLを書こうと思ったからですが
よくよく考えてみれば平均値を出すだけならITEM自体が不要ですね。
本当にありがとうございました。精進します。
989NAME IS NULL:2011/03/04(金) 16:46:14.77 ID:???
>>985
詳しいソースは覚えていないが,
ISOとANSIの関係でSQL92/99ではFROM内にJOINを使う方を推奨していた.
OracleがWHERE句に書いていたので982の書き方が広まったのだと思う.
990NAME IS NULL:2011/03/04(金) 17:02:05.82 ID:???
>>987
cross joinでしょうか?
それって>>4相当なんでしょうか。
991NAME IS NULL:2011/03/04(金) 18:00:07.28 ID:???
>>990
cross joinも何も、
SELECT ... FROM T1 INNER JOIN T2 ON T1.a = T2.a
SELECT ... FROM T1, T2 WHERE T1.a = T2.a

上の二つは等価な結果を返すわけだから、INNER JOIN句を使えなく
たって相関サブクエリを使わずに書ける。

>>989
手元にDateの教科書とRamakrishnanの教科書という、共に米国で
よく使われる教科書(のそこそこ新しい版)があるのだけれども、面白い
ことに共にSQLの例でJOIN句の類は殆ど使われていないんだよね。
こういう教科書では結合演算は直積と制限の合成演算という理解から
入るから、JOIN句の類は単なるシンタックスシュガーなんでしょう。

JOINを使った場合と使わなかった場合で実行プランが大きく変わって
くる事って実際にあるのかなぁ。使った方がオプティマイザには優し
そうな気はしますが。
992NAME IS NULL:2011/03/04(金) 18:20:57.87 ID:???
その教科書にはOUTER JOINはどう書いてあるの?
993NAME IS NULL:2011/03/04(金) 19:00:30.07 ID:???
>>992
そこが「殆ど」に対する例外で、Date本では三値論理について説明した
章の中で「余談」と称して外部結合を紹介。外部結合とこの演算を関係
モデルに導入したCoddを散々Disってから、最後に申し訳程度にSQLに
おけるNullのサポートの一部としてOUTER JOINを紹介している。
ちなみに「SQL概論」は第4章だけど、この三値論理の章は第18章w
そんぐらい後回し、というかDate先生はNullがお嫌いらしい。

Ramakrishnan本でもSQLでのNullのサポートに関する節の中で軽く
OUTER JOINについて触れて終了。ここ以外にJOIN句は出てこない。
994NAME IS NULL:2011/03/04(金) 19:09:28.16 ID:???
質問です。

・DBMS名とバージョン
  MySQL5.5.9

・テーブルデータ(商品データみたいなもの)

ID CREATED
--+---------------------
1 サムネイルA 商品名A
2 サムネイルB 商品名B
3 NONE 商品名C
4 NONE 商品名D
5 NONE 商品名E

・欲しい結果
3,4,5行目の2列目にある『NONE』をテキストデータから変更したい。

・説明
テキストデータ上には
http://〜〜
http://〜〜
とアドレスがいっぱい並べて保存してあって、そのデータをデータベースの『NONE』と変更したいです。
何か方法があれば教えてほしいです。
995NAME IS NULL:2011/03/04(金) 19:34:24.53 ID:???
>>994
その説明ではデータというのが何を指すか、
どういう鍵で取ってくるのかさっぱりわからない。
テーブルも列の数と列名が不整合だし・・・。
もう一度書きなおして。
996NAME IS NULL:2011/03/04(金) 19:44:26.26 ID:???
>>991 自分はSQL初心者だけども、これ、気になってた。
上のほうは、JOINした結果に対してSELECT
下は直積した結果に対してSELECTするのだから、
普通に考えると効率的には明らかに上のがいいと思う

下から上への変換ってWHERE句の中身まで解析しなければ機械的には出来無いよね?
一般的な実装はどうなのだろう

なんかスレ終わりかけで尻切れトンボな感じになってしまってあれだけど
997NAME IS NULL:2011/03/04(金) 19:54:48.12 ID:???
>>991
> SELECT ... FROM T1, T2 WHERE T1.a = T2.a
ってcross joinって呼ぶのかと思ってました。
それはともかく、どっちかというと>>4というより>>982と同じ感じになりそうなのですが。
998NAME IS NULL:2011/03/04(金) 20:22:32.95 ID:???
>>996
SQLという言語の基本的な事柄なのだけれども、SQLは宣言型言語なので、
どういうデータを得たいのかという問題は記述するけど、どうやって結果
を得るのか方法については記述しないんだよね。そこはRDBMSの実装が
勝手に判断して最適な評価プランを選択するというスタンスになっている。
もちろん今日のまともな実装なら下のクエリについても直積はとらない。
推測のとおりWHERE句の中身も解析して上のクエリと大差ない評価プラン
を大抵は選択する。

>>997
CROSS JOIN句ってのもあるじゃないですか。それを言っているのかと。
ともあれサブクエリが相関かそうでないかは評価プランの選択にかなり
大きな影響を与える。
単純にFROM INNER JOIN - ON をFROM - WHEREに書き換えた程度では
オプティマイザは大抵は殆ど変わらない評価プランを選択すると思いますが、
相関サブクエリにした場合は全く異なるプランを選択する可能性も大かと。
999NAME IS NULL:2011/03/04(金) 21:54:20.55 ID:???
>>994
自己解決しました。>>995さん説明下手ですみませんでした。
1000NAME IS NULL:2011/03/04(金) 23:18:06.54 ID:QTGnVt6O
null po
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。