1 :
NAME IS NULL :
2007/10/27(土) 21:09:21 ID:OP1e5oAp
3 :
NAME IS NULL :2007/10/28(日) 12:24:13 ID:HNaUJLCG
sqlite3です。 zip( pubcode INT ,zip5 CHAR(5) ,zip7 CHAR(7) ,pref_k TEXT ,city_k TEXT ,town_k TEXT ,pref_j TEXT ,city_j TEXT ,town_j TEXT ); で SELECT zip7,pref_j,city_j,town_j FROM zip WHERE 0=0 AND city_j = 'hoge' LIMIT 5 みたいな事をしているのですが、 WHERE 0=0の意味が分かりません。 「WHERE句の条件の所で0=0という妙なものが入っていますが、 コレはコーディングを簡略化するための小技です。 SQL文を動的に作成する場合、条件検索が複雑になってくるとWHERE句が 長くなってきますが、SQL文を文法的に正しくするため、 条件を動的に増やすたびに、その直前にWHEREを付けるかANDを付けるかを判断する必要が有ります。 ここでは、WHERE 0=0というダミーの条件を頭につける事で、後は機械的にANDでつなげば良いようにしています」 という説明が有るのですが、いまいち理解出来ません。 何か具体例はないでしょうか?
>>3 スレ違いなんだが、最後の文句
> 後は機械的にANDでつなげば良いようにしています
がすべてじゃね。
とりあえずPHPで書くと、
$where = "WHERE 0=0 ";
if ($pref) $where += "AND pref_j=$pref ";
if ($city) $where += "AND city_j=$city ";
if ($town) $where += "AND town_j=$town ";
$sql = "SELECT * FROM zip $where LIMIT 5";
ってことだろう。
俺なら配列に入れておいて" AND " でJOINするけどな。
うげっ、堂でもいいが if ($pref) $where += "AND pref_j='$pref' "; if ($city) $where += "AND city_j='$city' "; if ($town) $where += "AND town_j='$town' "; ' 'でくくるの忘れてt。
>>4 ,5
アルバイトで返事が遅れました。
すいません、SQLに初めて触るので不理解です。
えっと、SELECT文にはWHERE句を入れなければならないけれども、
この場合WHERE hogeで固定すると、引数に応じた柔軟なSQL文を発行するのが
めんどくさい。
そこで、WHERE 0=0として引数に応じてANDで追加したら、コーディングが
楽になると言う理解でよろしいでしょうか?
ちなみに WHERE 0=0ってどういう意味なんでしょうか?
今までの場合だと、
WHERE zip7とかWHERE 100といった直接指定しか習っていないので、
0=0の意味が良く分からないです。
>>6 0=0は常に真となるダミーの条件。
つけてもつけなくてもSQLの意味としては全く同じ。
なんで必要かが分からないうちはつけなくていい。
プログラムでSQLを自動生成するようになれば
おのずと分かるようになるよ。
なんで TRUE じゃないのか俺にもわからん
where TRUE って書くとそんなカラムはねーって言われるからだな。
MySQLへphpmyadminを介してインポートするために、 直接連絡の取れない会社に「テキストでのsqlダンプ」をくださいといったのですが、 秀丸で開くとバイナリっぽい感じがするデータが来ました。 TAPE <文字化け> microsoft SQL serverと1行目にあるのですが、 これはテキストでのsqlダンプなのでしょうか? 完全なテキストデータでは、microsoft SQL serverはエクスポートできないのでしょうか?
11 :
NAME IS NULL :2007/10/29(月) 20:22:15 ID:BxcL5p6/
a, b, c ------- 1, 0101, 100 1, 0101, 200 2, 0102, 300 2, 0103, 400 というようなテーブルがあって、 a, count(b), sum(c) ------------------- 1, 1, 300 2, 2, 700 というようなのを取得するにはどうすればいいのでしょうか。 まず group by a をするのは思いついたのですが、b の扱いに悩んでいます。 postgres なんですが、サブクエリを使って二段階で処理すれば いけるのかなとは思っているのですが、できれば一発で処理したいです。
>>11 SELECT a,count(DISTINCT b),sum(c) FROM Table GROUP BY a;
>>12 ありがとうございます。
DISTINCTって、集約関数の引数の欄にも書けるんですね。驚きました。
>>10 スレ違い。「BCP でエクスポートしてね」って頼め。
詳しくは、SQL Server の専用スレで。
質問ですが、SQLに於ける、 ボイスコット正規形がちんぷんかんぷんで解りません・・・・。 ので、解説お願い致します。 なるべくイメージが攫み易いように比喩など使って戴けると幸いです。 あと、調べた限りですと、 非キー項目から主キー項目を特定する事が出来てしまう(主キーが非キー項目に関数従属している)らしいのですが どうして、このように特定できてはいけないのでしょうか?
16 :
NAME IS NULL :2007/10/30(火) 14:00:25 ID:sO7Hyn8f
質問です。 レコードが4つあり、idがユニークで 1 2 4 6 という値が入っています。 このテーブルにインサートしたいのですが、SELECT MAX(id) の結果に 1を足した値をインサートする方法だと、いつかはオーバーフローします。 3でインサートしたいのですが、3を得るためによいSQL文はありませんでしょうか?
17 :
NAME IS NULL :2007/10/30(火) 15:05:25 ID:LF/fw7ef
accessでInStrを使ってる処理を、Postgres+VBに移植しようとしているのですが、 InStrとLike/ILikeでは何か違いがあるのでしょうか。 とりあえずキーワードの前後に%をつければいいという事はわかりましたが、 ヒットする件数に微妙な違いが出るときがあるようです。 その違う例を発見できれば、何かわかりそうなのですが、 access側とpostgres+VB側それぞれ付き合わせるにしても件数が大きくて困っています。
>>16 それが自然キーではない、つまりシステム内部で採番しシステム内部で使用するキーならば、
余計なことを考えずにより大きな型、32bitや64bitの整数を使う。
Max+1ではなくidentity属性やsequenceを使うのが基本。
それが自然キーならば、例えば1-9999の番号を繰り返し使うなどルールがある場合は、
例えば使わなくなった番号を管理するテーブルを別に持ちまずそれから番号を取得するなど、
いくつか方法がある。
採番の範囲が広いほどそれなりの工夫をしなければパフォーマンスを落とすことになりやすい。
>>16 すでに1行以上データがあることが前提だが、最小の空き番は以下でとれる。
SELECT min(id)+1 FROM Table AS T1 WHERE NOT EXISTS (SELECT * FROM Table WHERE id=T1.id+1);
だけど、
>>18 に同意。
20 :
NAME IS NULL :2007/10/31(水) 17:46:13 ID:WwEAVoHF
aspなのですが、 オブジェクトが閉じている場合は、操作は許可されません。 というエラーです。 rsが閉じているかどうやって調べればよいのでしょうか?
22 :
NAME IS NULL :2007/10/31(水) 17:51:23 ID:WwEAVoHF
すれ違いかを教えることしかできないのか。残念。
自己った。
>>21 そのスレにはもっと痛い奴が何年も住み着いてるからきーつけな>WwEAVoHF
25 :
NAME IS NULL :2007/11/02(金) 16:01:42 ID:B26ewXs/
質問です。 2つのテーブル tbl1 と tbl2 があり、SELECTする際にこの2つを結合させるものとします。 このとき取得できるフィールド名に、別名をつけたいと考えています。 tbl1.foo → tbl1_foo tbl1.bar → tbl1_bar tbl2.foo → tbl2_foo tbl2.bar → tbl2_bar というように、ユニークな別名をつけるにはどうすれば良いでしょうか。 もちろん、1つずつASを使うのが確実ではあるのですが、文字列操作関数で一括置換できないかなと。 プログラム側の都合上、同じフィールド名だと片方しか取得できないもので…。
更新系SQLの書き方について質問させてください。 以下のようなデータがあるとします。 ----------------- id name ----------------- 1 win xp 2 max os x 3 win 95 nameの先頭が"win"になっているものをwindowsに置き換えたいと考えており、 期待している結果は以下の通りです。 ----------------- id name ----------------- 1 windows xp 2 max os x 3 windows 95 このような更新を行うSQLはどのようにかけばよろしいのでしょうか? mysqlを使ってます。 よろしくお願い致します。
update TableName set name = 'windows' where name like 'win%'
>>26 UPDATE Table SET name=replace(name,'win ','windows ') WHERE name LIKE 'win %';
一応誤爆(windows -> windowsdows)回避のためwinの後ろにスペースを入れてある。
まぁ、これだと、nameが'win win os'となっていた場合、'windows windows os'ってなってしまう。
MySQLで可能かどうか不明だが、
UPDATE Table SET name='windows' || substring(name FROM 'win #"%#"' FOR '#') WHERE name LIKE 'win %';
POSIX正規表現が使えるならもそっと楽かな。
UPDATE Table SET name=regexp_replace(name,'^win ','windows ') where name LIKE 'win %';
29 :
28 :2007/11/03(土) 08:33:59 ID:???
もうちょっと楽っぽいのを思いついた。 UPDATE Table SET name='windows '||substring(name,5) WHERE name LIKE 'win %';
MySQL4.0です。 テーブルのnameフィールドが一部は 「山田 太郎」や「山田 太郎」となっており、 一部は 「山田太郎」 となっています。 スペースを無くす方向で統一したいのですが、下記SQL文で合っているでしょうか。 念のためバックアップしますが、それでも失敗したくないので。。。お願いします。 UPDATE table SET name=replace( name, ' ', '' ) UPDATE table SET name=replace( name, ' ', '' )
SQLってStructured Query Languageの略じゃないとWikipediaに書いてあるんですが マジですか?ISOのサイトにそう描いてある文書ないでしょうか。
>>31 『Database Language SQL』
としか書いてねぇよ。
Oracle9iでのSELECTについて教えてください。 現在のテーブル内情報: GROUP_ID│REG_DATE │TEL_NO │STATUS -────┼─────┼──────┼───── A001 │2007/10/01│03-9999-0001│ENABLED A001 │2007/09/20│03-9999-0002│DISABLED A001 │2007/10/03│03-9999-0002│ENABLED A001 │2007/10/03│03-9999-0003│ENABLED A001 │2007/08/01│03-9999-0003│DISABLED A001 │2007/10/31│03-9999-0004│DISABLED A001 │2007/10/31│03-9999-0005│DISABLED このうちTEL_NOが重複しないように、 GROUP_ID│REG_DATE │TEL_NO │STATUS -────┼─────┼──────┼───── A001 │2007/10/01│03-9999-0001│ENABLED A001 │2007/10/03│03-9999-0002│ENABLED A001 │2007/10/03│03-9999-0003│ENABLED A001 │2007/10/31│03-9999-0004│DISABLED A001 │2007/10/31│03-9999-0005│DISABLED こうなるように、 ・STATUS=ENABLEDで重複無しの場合はそのまま抽出。 ・STATUS=DISABLEDで重複無しの場合はそのまま抽出。 ・STATUS=DISABLEDとENABLEDの双方が設定されて重複 登録されているデータについては、 STATUS=ENABLEDのもののみを重複無しで取得したい。 という条件でselectしたいのですが、 どのように記述すれば良いでしょうか? よろしくお願いします。
>>35 ENABLED同士、DISABLED同士で重複している場合は
どういう条件で重複を排除するのか?
なんとなく
select A.GROUP_ID, A.REG_DATE, A.TEL_NO, A.STATUS
from TableName A
inner join
(select TEL_NO, max(REG_DATE) as MAX_REG_DATE
from TableName
group by TEL_NO
) B
on A.TEL_NO = B.TEL_NO
and A.REG_DATE = B.MAX_REG_DATE
;
でいいような気がするが。
37 :
35 :2007/11/06(火) 02:07:29 ID:???
>>36 ご教示ありがとうございます。
今、徹夜中で頭がもうろうとしているので、
明日、あらためて試させていただきたいと思います。
重ね重ねありがとうございます。
38 :
35 :2007/11/06(火) 10:18:59 ID:???
>>36 さっそく試してみたところ、望んでいた結果が得られ
見事うまくいきました(号泣)
本当にありがとうございました。
JOINの使い方をよく理解してないので、
これからJOINを勉強してみます。
39 :
NAME IS NULL :2007/11/06(火) 10:19:04 ID:XhrkB73v
1つのファイルにmysqlとPostgreSQLから同時にアクセス データベースに接続指定を書き込んだファイルを用意する形で、ファイルは同一サーバー上ですが、セキュリテリの面から直接プログラムファイルに書き込まず、別ディレクトリに設置し読み込ませます。 0SはLinuxです。 その読み込みファイル1枚に、MySQlとPostgleに同時接続させるような設定を書いた場合、同時にDBを操作できるのでしょうか。
>>39 日本語でOK
つか、何をしたいのか全く読み取れんよ。
> 1つのファイルにmysqlとPostgreSQLから同時にアクセス
1つのファイルに2つのRDBMSからアクセスするの?
> その読み込みファイル1枚に、MySQlとPostgleに同時接続させるような
1つのスクリプト or PGから2つのRDBMSに接続するの?
後者だとして、明示的に別なConnectionとかで扱えば、
個別のDataSourceとして扱うと思うがな。
それとも2つのRDBMSを1つの物として扱いたいって事か?
ひょっとして、connection.ini ってなファイルに pgsql:server=localhost/dbname=hoge... musql:server=loclahost/dbanme=hoge... って書いておいて、それを読み込んで接続したいってことかな? そりゃ、ホスト言語の仕様次第だろ。単純な読み込みならまず問題ないと思うが。 んで、スレ違いだな。
musqlはtypo....rz
43 :
NAME IS NULL :2007/11/07(水) 00:24:57 ID:jxOaFgZr
>>0 SはLinuxです
をよく見ると数字のゼロなのがウケル。
からかってんのか??
下のような表から date | customer | paper | pen | cable ------------------------------------ 2007/11/01 | Mr.AAA | 100 | 200 | 400 2007/11/01 | Mr.BBB | 150 | 300 | 350 2007/11/01 | Mr.CCC | 500 | 250 | 600 paper,pen,cableなどの列名を先頭に持ってきて 列com_name,priceを追加して、 下のような表を作ることはSQLまたは、PL/SQLでできるのでしょうか? com_name | date | customer | price ---------------------------------- paper | 2007/11/01 | Mr.AAA | 100 paper | 2007/11/01 | Mr.BBB | 150 paper | 2007/11/01 | Mr.CCC| 500 pen | 2007/11/01 | Mr.AAA | 200 pen | 2007/11/01 | Mr.BBB | 300 pen | 2007/11/01 | Mr.CCC| 250 cable | 2007/11/01 | Mr.AAA | 400 cable | 2007/11/01 | Mr.BBB | 350 cable | 2007/11/01 | Mr.CCC| 600 カーソル使って中は何とかなるけど、 肝心の両端がどうにもならんのです。 SQL PL/SQLやり始めて1月程度。 この辺が限界です。 どなたかお力を・・・
カラム名をシステムカタログから取得して、 PL/SQLでSQL組み立てれば可能かな。(カラム決め打ちじゃない場合) Oracleスレで聞いた方がいいんじゃね。
47 :
NAME IS NULL :2007/11/08(木) 21:07:22 ID:nXrq+1YJ
下記のテーブルAとテーブルBからテーブルAの重複行を 元に取得したい結果を抽出したいのですがご教授お願いします。 テーブルA ID1 |ID2 |ID3 |MONEY ----------------------- 010101|020202|030101|1000 010101|020202|030201|2000 010101|020202|030301|3000 010101|020202|030502|4000 010101|030202|040601|5000 010101|030202|040701|6000 テーブルB ID1 |ID2 |ID3 |NAME ----------------------- 010101|020202|030101|A 010101|020202|030201|B 010101|020202|030301|C 010101|020202|030502|D 010101|030202|040601|E 010101|030202|040701|F テーブルAの重複行を得る。 ID1 |ID2 |ID3_1|ID3_2|COUNT ----------------------------- 010101|020202|03 |01 |3 010101|030202|04 |01 |2 ID3_1 は SUBSTR(ID3,1,2) ID3_2 は SUBSTR(ID3,5,2) 取得したい結果 ID1 |ID2 |ID3 |NAME|MONEY ------------------------------ 010101|020202|030303|A |1000 010101|020202|030403|B |2000 010101|020202|030301|C |3000 010101|030202|040601|E |5000 010101|030202|040701|F |6000
48 :
47 :2007/11/08(木) 21:08:04 ID:nXrq+1YJ
>>47 の続き
SELECT A.ID1,A.ID2,A.ID3,B.NAME,A.MONEY
FROM テーブルA A,テーブルB B
WHERE
(A.ID1
,A.ID2
,SUBSTR(A.ID3,1,2)
,SUBSTR(A.ID3,5,2)
) IN
(SELECT
A2.ID1
,A2.ID2
,SUBSTR(A2.ID3,1,2)
,SUBSTR(A2.ID3,5,2)
FROM テーブルA A2
WHERE
A2.ID1
AND A2.ID2
AND SUBSTR(A2.ID3,1,2)
AND SUBSTR(A2.ID3,5,2)
GROUP BY
A2.ID1
,A2.ID2
,SUBSTR(A2.ID3,1,2)
,SUBSTR(A2.ID3,5,2)
HAVING COUNT(*) > 1
)
上記のようなSQLを作成したのですが
テーブルBと結合した際に重複行以外も取得してしまいます。
長文で申し訳ありませんでしたがどなたかご教授ください。
重複行を取りたいってのはわかった。 でも、それとテーブルBをどう結合するのかが 理解できん。 まず日本語できちんと説明してみれ
50 :
47 :2007/11/08(木) 22:03:41 ID:nXrq+1YJ
>>49 テーブルBの使用用途としては名称取得の為に使います。
取得したい結果はテーブルAの重複行の結果を元に名称が違うものだけを
抽出するというものです。
グループ化した後にグループ化された結果のデータの詳細を
表示するのですが、その際にテーブルAの重複行として取得した結果以外
のものが取得されてしまうのです。
日本語が下手で分かりにくいと思いますがすいません。
わかりにく・・・ 箇条書きでいいから条件羅列してみれ
取得したい結果 ID1 |ID2 |ID3 |NAME|MONEY ------------------------------ 010101|020202|030303|A |1000 このID3=030303ってデータはどこからくるの? テーブルAにもBにも存在しないんだけど。
>>47 「取得したい結果」は、
ID1 |ID2 |ID3 |NAME|MONEY
------------------------------
010101|020202|030101|A |1000
010101|020202|030201|B |2000
010101|020202|030301|C |3000
010101|030202|040601|E |5000
010101|030202|040701|F |6000
の間違いじゃないのか?(1行目と2行目のID3)
そうだとしたら、ほぼ
>>48 のまま
select A.ID1, A.ID2, A.ID3, B.NAME, A.MONEY
from テーブルA A, テーブルB B
where (A.ID1, A.ID2, substr(A.ID3, 1, 2), substr(A.ID3, 5, 2))
in
(select A2.ID1, A2.ID2, substr(A2.ID3, 1, 2), substr(A2.ID3, 5, 2)
from テーブルA A2
group by A2.ID1, A2.ID2, substr(A2.ID3, 1, 2), substr(A2.ID3, 5, 2)
having count(*) > 1
)
and A.ID1 = B.ID1
and A.ID2 = B.ID2
and A.ID3 = B.ID3
で良さそうなもんだけど。
54 :
47 :2007/11/08(木) 22:44:46 ID:nXrq+1YJ
本当に日本語が下手ですいません。 ・テーブルAのID3の1,2桁目と5,6桁でグループ化をする。 ・グループ化したID3を元に重複している名称を抽出する。 ・名称を抽出した際にグループ化した結果以外が抽出されてしまう。 取得したい結果 は間違ってました。すいません。 以下が本当の取得したい結果です。 ID1 |ID2 |ID3 |NAME|MONEY ------------------------------ 010101|020202|030101|A |1000 010101|020202|030201|B |2000 010101|020202|030301|C |3000 010101|030202|040601|E |5000 010101|030202|040701|F |6000
>・テーブルAのID3の1,2桁目と5,6桁でグループ化をする。
ID3_1|ID3_2|COUNT
03 |01 |3
03 |02 |1
04 |01 |2
>・グループ化したID3を元に重複している名称を抽出する。
上の結果からCOUNTが2以上(重複がある行)を抽出。
ID3_1|ID3_2|COUNT
03 |01 |3
04 |01 |2
テーブルAのID3の1,2桁目と5,6桁が上の結果のID3_1|ID3_2と一致する行を抽出。
ID1 |ID2 |ID3 |MONEY
-----------------------
010101|020202|030101|1000
010101|020202|030201|2000
010101|020202|030301|3000
010101|030202|040601|5000
010101|030202|040701|6000
テーブルBと合わせる。
ID1 |ID2 |ID3 |NAME|MONEY
------------------------------
010101|020202|030101|A |1000
010101|020202|030201|B |2000
010101|020202|030301|C |3000
010101|030202|040601|E |5000
010101|030202|040701|F |6000
って事?
>>47
56 :
NAME IS NULL :2007/11/12(月) 00:31:35 ID:tKheOgZe
MySql5.0を使用してます。 CREATE TABLE test_tbl ( id int(11) NOT NULL auto_increment, name varchar(255) default NULL, mydate date NOT NULL, PRIMARY KEY (id), ); こんなテーブルがあり 毎日定時にSELECT文を実行して mydateから30日後,60日後,90日・・・・と mydate から本日が30日間隔のidを永遠に抽出したいんですが、どういう風に記述すればよいでしょうか?
試してないが、 select * from test_tbl where mydate<sysdate() and (sysdate()-mydate)%30=0
58 :
NAME IS NULL :2007/11/12(月) 18:49:35 ID:3CGhHvj/
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の書き方を教えてください。
60 :
NAME IS NULL :2007/11/12(月) 20:08:04 ID:3CGhHvj/
>>59 サブクエリーでMaxとった後に、同じテーブルを当てるのですね。
やってみたら上手くいきました。
有難う御座いました。
SQLについて質問させください。 以下の二つのテーブルがあるとします。 (1)user_tbl +---------+-----------+ | user_id | user_name | +---------+-----------+ | 1 | tarou | | 2 | jirou | | 3 | saburou | +---------+-----------+ (2)question_tbl mysql> select * from question_tbl; +-------------+---------+--------+ | question_id | user_id | answer | +-------------+---------+--------+ | 1 | 1 | yes | | 2 | 1 | yes | | 3 | 1 | yes | | 4 | 1 | no | | 5 | 1 | no | +-------------+---------+--------+ 5 rows in set (0.00 sec) この二つのテーブルから以下の結果を導き出したいです。 +----------+-----------+--------+-----+ | _user_id | user_name | yes | no | +----------+-----------+--------+-----+ | 1 | tarou | 3 | 2 | | 2 | jirou | 0 | 0 | | 3 | saburou | 0 | 0 | +----------+-----------+--------+-----+ このような結果を作るSQLはどのようになりますでしょうか? よろしくお願い致します。
>>61 ヒント:sum(case when answer = 'yes' then 1 else 0 end) as yes
63 :
>>61 :2007/11/13(火) 07:54:51 ID:???
Oracleを勉強していて、わからないところがあるので質問させてください。 以下のようなテーブルがあったとします。 GROUP_ID│USER_NO│SALARY -────┼────┼──── A001 │ 17040│200000 A001 │ 18302│190000 A002 │ 28321│200000 A002 │ 23434│200000 A003 │ 56787│210000 A003 │ 98908│200000 A003 │ 67589│210000 このテーブルから GROUP_ID毎のSALARYの最大値を取得したいのですが、 あわせてSALARYが最大値であるUSER_NOも取得したいのです。 結果のイメージとしては GROUP_ID│USER_NO│SALARY -────┼────┼──── A001 │ 17040│200000 A002 │ 28321│200000 A003 │ 67589│210000 となります。 select GROUP_ID, MAX(SALARY) from TABLE group by GROUP_ID ここから先どのように記述してよいのかわかりません。 教えていただけないでしょうか? よろしくお願いします。 ちなみにSALARYが重複した場合はUSER_NOが大きい方を表示するようにしたいです。
select 10 as a, 20 as b, (a + b) as c のようなことをしたいのですが、できますでしょうか? mysqlをつかっております。
>>65 GROUP_ID と SALARY がわかってるんだから、
元のテーブルと JOIN すれば OK。
>>66 MySQLじゃなくてもできないよ。
SELECT *,(a+b)AS c FROM (SELECT 10 AS a,20 AS b ...) AS T1
のようにすれば桶。
>>65 こうやるんだよ。
select
b.gid,
max(b.uid),
b.salary
from
(select gid, max(salary) as salary from TABLE group by gid) as a
left join
TABLE as b
on a.salary=b.salary
group by gid;
71 :
>>66 :2007/11/14(水) 01:47:20 ID:???
74 :
65 :2007/11/14(水) 11:28:45 ID:???
>>67 ,70
ありがとうございます!
>>70 さんのSQLはうまく動きませんでしたが、
参考にして作ることができました!
Oracle10gの質問です。 TBL1 ID(PK) ---- 001 002 003 TBL2 ※IDはPKでない ID NAME --------- 001 NAME1 002 NAME2 002 NAME3 テーブル1と2を結合して ID NAME ---------- 001 NAME1 002 NAME2 003 NULL といった具合にTBL1の件数は維持して NAMEには一致したIDの先頭(でなくてもいい)のものを 引っ張ってきたいです。 外部結合だと SELECT * FROM TBL1, TBL2 WHERE TBL1.ID = TBL2.ID(*) ID NAME ---------- 001 NAME1 002 NAME2 002 NAME3 003 NULL といった具合にID:002がダブってしまいます。 (002は1件でNAME2かNAME3のうち1つだけ表示したい) 何かよい解決策はないでしょうか。
>>76 Group By した結果と JOIN すればOK。
って、ちょっと前に似たような例があったような・・・
>>77 回答ありがとうございます。
こんな感じでしょうか。
今は手元に環境がないので動作確認できませんが
MAXに違和感を感じます。
SELECT *
FROM
TBL1,
(
SELECT MAX(NAME)
FROM
TBL2
GROUP BY
NAME
)TBL2
WHERE
TBL1.ID = TBL2.ID(+)
>って、ちょっと前に似たような例があったような・・・
すみません。このスレでしょうか。
教えていただけるとありがたいです。
(パっと見どれだかわからない)
たぶん前スレの最後のやつかな?
前スレがもう見られないです。 ログ持ってる方、貼っていただけるとありがたいです。
81 :
65 :2007/11/15(木) 16:45:32 ID:???
すいません、もう一度質問させてください。 前のテーブルに付け足したテーブルがあるとします。 GROUP_ID│USER_NO│SALARY │USER_NAME -────┼────┼────┼────── A001 │ 17040│ 200000│ 田中 A001 │ 18302│ 190000│ 田所 A002 │ 28321│ 200000│ 田端 A002 │ 23434│ 200000│ 田原 A003 │ 56787│ 210000│ 田井 A003 │ 98908│ 200000│ 田木 A003 │ 67589│ 210000│ 田守 取得条件は前の質問と同じで結果は以下になります。 GROUP_ID│USER_NO│SALARY │USER_NAME -────┼────┼────┼────── A001 │ 17040│ 200000│ 田中 A002 │ 28321│ 200000│ 田端 A003 │ 67589│ 210000│ 田守 自分で作ったSQLは select T4.* from T4, (select T3.GROUP_ID, MAX(T3.USER_NO) as USER_NO, select T4.* from T4, (select T2.GROUP_ID, max(T2.USER_NO) from (select GROUP_ID, max(SALARY) as SALARY from TABLE group by GROUP_ID) as T1, TABLE as T2 on T1.SALARY = T2SALARY group by T2.GROUP_ID) T3 where T4.GROUP_ID = T3.GROUP_ID and T4.USER_NO = T3.USER_NO select T4. * from TABLE T4, (select T2.GROUP_ID, max(T2.USER_NO) as USER_NO, T2.SALALY from (select GROUP_ID, max(SALALY) as SALALY from TABLE group by GROUP_ID) T1, TABLE T2 where T1.SALALY = T2.SALALY and T1.GROUP_ID = T2.GROUP_ID group by T2.GROUP_ID, T2.SALALY) T3 where T3.GROUP_ID = T4.GROUP_ID and T3.USER_NO = T4.USER_NO です。もうちょっとスマートにかけないものかなと思って質問しました。 よろしくお願いします。
Hi! Nice site!
Hi! Nice site!
>>76 select A.ID, B.MAX_NAME
from TBL1 A
left outer join
(select ID, max(NAME) as MAX_NAME
from TBL2
group by ID
) B
on A.ID = B.ID
>>81 >>35-36
>>81 SELECT * FROM
(SELECT max(user_no) AS user_no FROM Table AS T1
WHERE SALARY=(SELECT max(salary) FROM Table WHERE group_id=T1.group_id)
GROUP BY group_id) AS T2
LEFT JOIN Table USING(user_no);
スマートかどうかは...?
86 :
sage :2007/11/15(木) 20:16:36 ID:f/zLBRc9
質問します^^; かなり初歩的なことかと思いますが。。。 IFIXなるものを現在会社で使ってまして制御系(FA)なのですが まったく経験がなく、データベースなるものもあまり判っていませんorz もし、詳しく判りやすいサイトや、板誘導などがありましたら、お願いします 板汚し板違いスイマセン
で、何を知りたいんだ?それをはっきり書けよ
88 :
NAME IS NULL :2007/11/15(木) 22:41:17 ID:NMabm+GO
LEFT OUTER JOIN で右側の列に検索条件指定したら、INNER JOIN と いっしょですか?
89 :
86 :2007/11/15(木) 23:38:43 ID:???
>>86 です
サゲミスッテマスタorz
タグの種類でPGがあって、その中に「ADDOUT」や「SETMAN」などがあるのですが
それらの説明、使い方、このときはこの文法?みたいのがわかればと思いまして。。。
まったく持って初歩的な事でスイマセン
すいません。ソートについてお聞きしたいのですが、 id typeid name --------------------------------- 1 1 aaaa 2 1 bbbb 3 2 cccc 4 2 dddd 5 2 eeee 6 3 ffff というテーブルがあった場合、typeidが多い("大きい"ではない)順番にソートする方法はあるでしょうか? 上のテーブルでいえば、 id typeid name --------------------------------- 3 2 cccc 4 2 dddd 5 2 eeee 1 1 aaaa 2 1 bbbb 6 3 ffff となって欲しいのです。 今まではtypeidでgroup byしてcount(*)の数値を元に手作業?でどろどろとソートしていたのですが、 実は1回のselectで簡単に出来るんじゃないかと思って、色々頑張って見ましたがorzでした。 よろしくお願いします。
select B.cnt ,A.id ,A.typeid ,A.name from table A, ( select count(*) as cnt ,typeid from table group by typeid ) b where A.typeid = A.typeid order by B.cnt ,A.id
うおー!すごすぎる!早すぎる!久しぶりに感動した! 本当にありがとう。次会ったらメシおごるノシ
MySQL 4.1.20 table uriage kaisha int(4), kyaku int(9), torihikiYMD date, oder_number int(5) kingaku int(9) taishaku int(1) というのがあって客毎に金額を集計するなら select kyaku,sum(kingaku) from uriage group by kyaku; になると思うのですが、そこにtaishakuが1なら減算 9なら加算するというのをどうやったら付け加えられますか 教えてください。
sum(decode(taisyaku,1,kingaku * -1,9,kingaku))
sum(kingaku*(taishaku-5)/4)
101 :
98 :2007/11/19(月) 22:17:57 ID:???
>>100 何で4で割るのかしばし考えましたが、なるほどですね。
>>99 すいません、本見ましたけど、decodeって複号化する奴では?
decode関数はOracleだけだな。 一応case文に書き換え可能。 sum(case taisyaku when 1 then kingaku * -1 when 9 then kingaku end)
>>102 あ〜、固有のやつでしたか。ありがとです。
MySQL5.0なんですが、 WHERE field LIKE 'hoge%' と WHERE field REGEXP '^hoge' って全く同じ条件になる、と考えてよいでしょうか?
115 :
NAME IS NULL :2007/11/27(火) 21:59:57 ID:JprxOidq
ストアドプロシジャー内でINSERT分に日時を利用したいのですが、構文教えてください
>>115 ストアドプロシジャはDBMSによって構文が全く違うので
DBMS名を示さなければその質問は無意味。
SQLに限って言っても、日付・時刻に関する構文は
DBMSによって違う。
あと、やりたいことをもっと具体的に言ったほうがいいかと。
118 :
NAME IS NULL :2007/11/28(水) 14:21:20 ID:dhNS0GoF
CREATE TABLE DEPENDENT( DEPEND_ID INTEGER, DEPEND_NAME VARCHAR(50), DEPEND_AGE INTEGER, DEPEND_RELATION VARCHAR(20), EMP_ID INTEGER, DEPT_ID INTEGER, PRIMARY KEY (DEPEND_ID, EMP_ID, DEPT_ID), FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE(EMP_ID), FOREIGN KEY (DEPT_ID) REFERENCES DEPARTMENT(DEPT_ID) ) こいつを実行すると、Unique Primary not foundと言ってくるんですが、 何がまずいのでしょうか?
select qid, quest from quest_tbl; 上のSQL文ですべての質問を取り出す際、ユーザがこの質問に答えているか、調べたいのですが下のSQL文を併せて調べるよう連結させるにはどうすればいいでしょうか? select COUNT(user_tbl) FROM answer_tbl where qid=$qid and title IS NOT NULL;
>>116 丁寧にお手数多謝です。
SQLServer2005です。GETDATE関数でおkですね。
もっと自分で調べてから質問するようにします。ご指摘ありがとうございます。
A_ID │A_NAME│ ----------------------- A001 │ A1 │ A002 │ A2 │ A003 │ A3 │ A004 │ A4 │ B_ID │A_ID │ B_NAME ----------------------------- B001 │ A001│山田 B002 │ A001│山田 B003 │ A001│山田 B004 │ A002│高橋 B005 │ A002│島田 B006 │ A002│中村 B007 │ A003│中村 B008 │ A004│山田 C_ID │B_NANE │COUNT ------------------------------- C001 │ 山田 │ 3 C002 │ 田中 │ 1 C003 │ 高橋 │ 1 このような3つのテーブルを結合して、C_ID = C001 を抽出した際に A_ID │A_NAME│B_NAME| C_ID --------------------------------- A001 │ A1 │山田 │C001 A004 │ A4 │山田 │C001 と、A_IDが重複しないようなSQLの結合が上手く行かなくて悩んでおります。 こんな遅い時間で恐縮ですが、どなたかお教え願えないでしょうか。 日が昇ったら、これを講師に提出しなくてはならなくて・・・。 よろしくお願い致します。
追記で申し訳ないです。 使用しているプラットホームはpostgresqlでした。
>>122 上から TableA,TableB TableCとして
SELECT * FROM
(SELECT c_id,b_name FROM TableC WHERE c_id='C001') AS T1
JOIN (SELECT a_id,b_name FROM TableB GROUP BY a_id,b_name) AS T2 USING(b_name)
JOIN TableA USING(a_id);
いつも書き込んだ後に気づく...orz SELECT * FROM TableC JOIN (SELECT a_id,b_name FROM TableB GROUP BY a_id,b_name) AS T2 USING(b_name) JOIN TableA USING(a_id) WHERE c_id='C001'; でいいか。(このままだとTableC.countまででるけど)
PostgreSQL 8.2 使ってますけど、副問い合わせで 1 件も存在しない時に 0 を返すように したいんですがうまい書き方はないでしょうか? UPDATE HOGE SET HAGE=(SELECT HAGE FROM FOO WHERE ID=?), ...
>>126 SELECT Hoge SET hage=COALESCE((SELECT hage FROM Foo WHERE id=?),0);
またやった...orz UPDATE Hoge SET hage=COALESCE((SELECT hage FROM Foo WHERE id=?),0);
130 :
119 :2007/11/29(木) 12:21:06 ID:???
>>120 あっ!
たまたま同じ質問してる人がいたなんて!!
すごい奇遇です!!
131 :
122 :2007/11/29(木) 15:43:22 ID:???
>>125 遅レスで申し訳ないです。
おかげで、何とか合格しましたですよ。本当に有難うございました。
まだまだSQLが使いこなせてないので、ちょっとSQLの本買って冬休みは
勉強します。
133 :
NAME IS NULL :2007/11/30(金) 00:08:38 ID:IiAQc5hj
・DBとバージョン MySQL4.0.24 です ・テーブルデータ p_id,p_name(ペット用テーブル:pet) ----------------- 1,シロ 2,ぽち 3,タマ s_id,s_name(社員用テーブル:syain) ----------------- 1,山田 2,小林 3,三木 t_id[auto_increment],p_id,s_id(担当者テーブル:tanto) ----------------- 1,1,1 2,2,2 3,1,3 ・欲しい結果 一覧表示 ================= シロ | 三木 ぽち | 小林 タマ | (空欄) ・説明 シロの担当はは山田から後に三木に変更になっています タマの担当者はまだ決まっていません 今はphpを使っていて SELECT * FROM pet (ペットをすべて取得してループ開始) SELECT * FROM tanto WHERE p_id ORDER BY t_id DESC LIMIT 1 SELECT * FROM syain WHERE s_id LIMIT 1 (ループ終わり) としているのですが一回で出来るのでしょうか? 以前ペット用テーブルは p_id,p_name,s_id となっていて LEFT OUTER JOIN を使っていましたが 担当者の変更履歴が分かるようにと言われて考えてみたのですが、 そもそもやり方(構造?)がおかしいでしょうか? よろしくお願いいたします
担当者テーブルを p_id で Group By し、t_id の Max を取る。 その Max(t_id) と t_id を結合し、p_id で ペット用テーブルと Left Outer Join
担当者テーブルは頻繁にアクセスされるだろうし、履歴と一緒にするのはどうかと思う。 担当者テーブルは担当者テーブルとして、現状のペットと社員の関係だけ保存し、 別にログのテーブル用意して、担当代わるときに書き込めばいいんじゃないか? あとダミーとして社員(空欄)をs_id 0 で登録しておくとLEFT JOINで目的の 一覧表示がすぐ出せていいかと思うが、どうかね?
136 :
133 :2007/11/30(金) 07:51:32 ID:???
>>134 ,135
5時間くらい格闘してみたのですが、なかなか々々で今日は休みます
担当者ありがなしになった時などダミーが必要とか
ものすごく参考になりました
データベースは個人的にアクセスを使っていただけな僕が
前任者のを引き継いだような感じで、悪戦苦闘なのですが
うまくいかないことがある反面、ものすごく面白いなと感じていますので
もうちょっとがんばってみます
レスありがとうございました!
けっこうムズいね mysql> select p.p_name, s.s_name -> from pet p -> left outer join tanto t -> on p.p_id = t.p_id -> and t.t_id = -> ( -> select max(t_id) -> from tanto t2 -> where t2.p_id = t.p_id -> ) -> left outer join syain s -> on t.s_id = s.s_id -> order by p.p_id; +--------+--------+ | p_name | s_name | +--------+--------+ | シロ | 三木 | | ぽち | 小林 | | タマ | NULL | +--------+--------+ 3 rows in set (0.00 sec)
mysql4.0ってサブクエリ使えたっけ?
4.1からだな
140 :
133 :2007/11/30(金) 22:08:39 ID:???
>>137 >けっこうムズいね
うーん、やっぱり僕のテーブルの作り方がマズいのかなあ…
わざわざ書いてもらって本当にありがとうございました
>>138-139 昨日いろいろやっていてどうにも納得できなかった部分が釈然としました
本を2冊買って、ネットの情報も元にしていたのですが、
サブクエリが使えないバージョンだったのですね、、、
ちょっと構成を見直すことと、サブクエリを使った例文が
結構ありますので、前任者に連絡をとってみてMySQLを
4.1以降にすることをやってみたいと思います
皆様ありがとうございました
141 :
NAME IS NULL :2007/12/02(日) 22:23:46 ID:SHn+jsyg
すいません、初心者です。本やWebを探したのですが理解できなかったので教えて 下さい。 以下のSQL文のaとbの結果がイマイチ理解できません。 aをGROUP BYしたあとbをGROUP BYして、異なった値があれば付け足して 表示しているのでしょうか? SELECT a , b FROM c GROUP BY a , b;
日本語がわからない
143 :
初心者 :2007/12/03(月) 03:30:55 ID:ukVIXvlY
はじめまして。初心者です。 突然ですが質問があります。 SQL SERVER 2005 で、自動的(1時間ごとに)にバックアップをとり、48時 間分のファイルを保存しておきたい時はどのようにしたらいいのですか。 基本的にフルバックアップです。 サイズはは100メガくらいです。 スケジューラは使います。 ログもそのまま保存します。 みなさまのお力をお貸しください。(__)
145 :
初心者 :2007/12/03(月) 03:38:14 ID:ukVIXvlY
すいませんMicrosoft SQL Server 総合スレ でいいんですかね?
146 :
NAME IS NULL :2007/12/04(火) 15:54:19 ID:V8j0VlBH
MySQLのON DUPLICATE KEYと同等のことをPOSTGRESQLで行いたいのですが 変わりになるようなものは用意されていないのでしょうか?
147 :
NAME IS NULL :2007/12/04(火) 19:34:23 ID:g6rhgp+g
すいません。質問です。 DECIMAL型について勉強しているんですが、 salary DECIMAL(5,2) この例で、5 (precision) は、値に対して格納される 10 進数の桁数を表わし、2 (scale) は、小数点に続いて 格納される桁数を表わします。したがって、この場合、 salary カラムに格納できる値の範囲は、-99.99 〜 99.99 になります。(MySQL では、正数の符号を格納する必要がないため、 このカラムには、実際には、999.99 までの数値を格納することができす)。 とあったんですが、 5桁まで格納できるなら -999.99~999.99じゃないんですか?
149 :
146 :2007/12/05(水) 09:21:40 ID:???
>>148 ありがとうございます
教えていただいた内容で調べてみます
テーブルにAとBがあって、A>Bの行数とA<Bの行数を取りたいんだけど、 SELECTは2回発行するしかないよね?テーブルの全行を2回スキャンするしかない と思ってンだけど。
152 :
NAME IS NULL :2007/12/06(木) 13:07:14 ID:0iWlbZYz
すみません、教えて下さい。 あるゲームがあるとして、ユーザー数千人の各一人一人の 行動をログに取りたい場合なんですが、 全員のユーザーのログを、ユーザーIDとログIDをキーとして 一つのテーブルに入れると、膨大なレコード数になっちゃいますよね。 そうなるとインサートの時や索引張るときに かなり負荷がかかりそうだし さらにその詳細情報も…。 なんてことになったら詳細テーブルには更に指数的にレコードが増えてしまいます。 そこで、ユーザーごとにログテーブルと ログ詳細テーブルを作ってやればいいんじゃね? と思ったのですが こういうやり方ってどうなんでしょう? テーブルがめちゃくちゃ増えるだけで 結局情報量は変わらないですが、 負荷は減りそうな気はするんですが…。 他にもっとスマートなやり方があれば 教えて頂きたいッス〜m(_ _)m
負荷は増えるしいいことないと思うけど。
小さいテーブルに分割すれば一つのテーブルの負荷は明らかに減るけど、 テーブルを管理するあたりの部分が大量のテーブルに耐えられるつくりに なっているかどうかはわからんな。巨大な1テーブルとユーザごとの大量の テーブルの中間が現実的な落としどころじゃない? 実際のところは具体的 にやってみないとわからんと思う。
155 :
NAME IS NULL :2007/12/06(木) 15:53:02 ID:0iWlbZYz
>>153-154 ありがとうございます。
確かに問題はテーブルの管理部分ですよね。
テーブルが増えるとシステム管理系のテーブルが重くなって
全体的な負荷が上がることは考えられますね…。
DBの構造にインスタンス的な情報を入れると
DBの保守性もあまりよろしくない感じなので、やっぱり難しいですかね…。
書き込みが多く、見ることは少ないので、
イベントの種類別でテーブル作って、
見るときはそのテーブルを
マージするSELECT文作るあたりが中間の落としどころですかね…。
156 :
NAME IS NULL :2007/12/06(木) 17:02:54 ID:pzP20kps
パーティションとかはどうよ?
ログってことは追記だけだろうし、根本否定して悪いが ユーザごとにログファイルを置いてもいいような。 ユーザごとなら同時書き込みなんて起こらないし。
>152 どの程度の頻度で更新されるのか、データ量はどれくらいあるのか、によると思う。 MMORPGのように、例えば1秒とか数秒ごとに記録をするのもあれば、 PBWのように月1で記録するものもあるだろう。
160 :
NAME IS NULL :2007/12/07(金) 14:00:12 ID:V9WCgeuV
レスいただいた方々、ありがとうございます。
>>157 パーティションは名前だけで良く知りませんでした、
ちょいと調べてみたところ、検討する価値がありそうですね。
>>158 ログから今度統計を取ったりするので、DB化した方が良いかなと…。
例えば全ユーザーが一番苦手とする敵とか。
>>159 MMO程じゃないですが、ログ書き込みは平均10秒に1度程度を予定してます。
また、ロギングするイベントの種類も
せいぜい15個程度なので…。
161 :
NAME IS NULL :2007/12/08(土) 20:30:33 ID:jFBCt3fk
SQLでShiftJISの文字列を扱うとシングルクォート(\x27)によるSQLインジェクションの問題が起きると思うんだけど 普通どうやって回避するの? ShiftJIS以外を使うしかないの? 一応今使ってるDBはMySQL
ストアドにすれば?
163 :
NAME IS NULL :2007/12/08(土) 20:54:38 ID:M+oCyQsj
上に出てくるのとよく似ているのですが、SQL文がうまくかけません。 DBは、Oracle9です。 取り扱いメニュー(T_MENU) 店舗Code | メニューコード | 適用開始日 101 | 001 | 20071001 メニューマスタ(MENU) メニューコード | 副番 | メニュー名 | 適用開始日 | 適用終了日 001 | 1 | メニューA | 20070901 | 20070930 001 | 2 | メニューB | 20070931 | 20071020 001 | 3 | メニューC | 20071001 | 20071015 とある場合に、「取り扱いメニュー」を基に結合してメニュー名を取得したい のですが、業務用件として取得するメニュー名は、取り扱いメニューテーブル の適用開始日時点で有効なメニューの副番のうち、一番若い副番のものという 指示がありました。 つまり、結果として得たいクエリは、 店舗コード | メニューコード | メニュー名 101 | 001 | メニューB というものです。 副問い合わせで SELECT MIN(MENU.副番) FROM MENU WHERE MENU.適用開始日 <= T_MENU.適用開始日 AND MENU.適用終了日 >= T_MENU.適用開始日 GROUP BY MENU.メニューコード みたいなことをしたいのですが、うまくいきません。 どうぞ皆さんのお知恵をお貸しください。
>>163 レス付かないようなので。
とりあえずmysqlだとたぶんこんな感じ。
select 店舗Code, メニューコード,
(select メニュー名 FROM MENU
WHERE MENU.適用開始日 <= T_MENU.適用開始日
AND MENU.適用終了日 >= T_MENU.適用開始日 order by 副番 limit 1)
from T_MENU
Oracleだと、limitではなくRow_Number()とか使うことになるんかな。
イマイチ意味が... 汎用的(に書いたつもり)だとこんな感じか? SELECT T_menu.店舗コード,メニューコード, (SELECT メニュー名 FROM Menu WHERE (メニューコード,副番)=(SELECT min(メニューコード)AS メニューコード,min(副番) AS 副番 FROM Menu WHERE メニューコード=T_menu.メニューコード AND T_menu.適用開始日 BETWEEN 適用開始日 AND 適用終了日)) FROM T_menu;
SQL Server2005を利用しております。 Select文の中にバインド変数を使用したのですが SELECT 得意先名 FROM 得意先マスタ WHERE 得意先コード =: 得意先 を実行すると ':' 付近に不適切な構文があります とエラーが出ます。 =: のやり方はoracleだけなのでしょうか?
>>166 MSSQLでは、変数のプレフィクスは「@」じゃないっけ?
ちなみにOracleでも、「=:」が演算子なわけではなく、
「:」が変数のプレフィクスなだけだよね。
その質問の仕方だと、代入演算をしたがってるように誤解される(てか俺もした)。
168 :
166 :2007/12/12(水) 18:22:37 ID:???
>>167 トンクス!
「@」でした!
ちなみに、CSEでやろうとすると
スカラ変数 "@得意先" を宣言してください。
と出るのですが、どうしたらよいですか?
今までずっとOracleの現場でosqleditを使っていましたが
今回、初めてSQLServerなので、最初で苦労してます。。。
>>168 CSE ってのが何のことやらわからんけど、
パラメータについて調べるとよいかもしれん。
で、このスレは SQL についてのスレで、
SQL Server についてのスレではない。
専用スレに Go!
170 :
168 :2007/12/12(水) 20:51:21 ID:???
>>168 SQL Serverなら、クエリアナライザという優秀な標準GUIツールがあるというのに・・・
MSDEならその限りではないが。
この前勉強を始めたばかりなんですが、 テーブルの上からn行目を指定、したりできますか?
>>173 データの取り出し順はソートしない限り保証されないので
「テーブルの上からn行目」ってのはできない。
ソートした結果からn番目ってのはいくらでもやりようがある。
175 :
NAME IS NULL :2007/12/14(金) 01:31:20 ID:nj9wJu5D
あるデータベース内のテーブル名の一覧を取得するには、 SHOW TABLES FROM db_name; となり、更にテーブル名が「dtb」から始まるものを同様に取得するには、 SHOW TABLES FROM db_name LIKE 'dtb%"; になると思いますが、 逆にテーブル名が「dtb」から始まるもの以外の一覧を取得するには どのような SQL 表現となりますでしょうか? 間違っているとは分かっていながら、あえて書くと SHOW TABLES FROM db_name NOT LIKE 'dtb%"; のような感じのことをしたいのです。 どなたかご教示ください。
>>175 SHOW TABLESってMySQLの方言じゃないのか?
MySQLスレのがいいね
178 :
175 :2007/12/14(金) 20:26:41 ID:???
ORACLEのSQLのソースを見ていたら、 to_date('20071216','YYYYMMDD') - to_number(T.STRINGDATE) というのがあったのですが、 日付型から数値を引くとどのような演算がされるのですか?
>>180 ありがとう、ネットで暗黙の型変換に関するドキュメントがなかったので助かりました。
SQL Server 2000/MSDEで、インスタンス一覧、データベース一覧、テーブル一覧を得るSQLってある? 朝から調べてたけど見つけられなかった。orz
GUIでしか調べられないから諦めろ。
sysobjectsでも眺めてろ
次のようなテーブル ID VALUE ---------- 0 NULL 1 NULL 2 1 3 NULL 4 NULL 5 0 6 NULL 7 NULL 8 2 9 NULL 10 NULL があったとして、 ID VALUE ---------- 0 NULL 1 NULL 2 1 3 1 4 1 5 0 6 0 7 0 8 2 9 2 10 2 のようにNULLの箇所を直近の値で埋めるような方法はありますか?
全データ、掴んで一件一件回すしかないな 件数によっては果てしなく時間がかかる
>>185 UPDATE Table AS T1
SET value=(SELECT value FROM Table WHERE id=(SELECT max(id) FROM Table WHERE id<T1.id AND value IS NOT NULL))
WHERE value IS NULL;
DBによってはちょっと変えないとダメかな。
189 :
NAME IS NULL :2007/12/20(木) 15:29:03 ID:WQA8NgrI
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というデータがあっても無視して構いません。 環境はSQLServer2005です。 よろしくお願いします。
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; とかでいいのかな?
{ID, SUBID, SEQ} の 3項目があるテーブルに {1, 1, 0} {1, 2, 0} {1, 3, 0} {1, 3, 0} {1, 3, 0} {1, 4, 0} {1, 5, 0} : で、ID, SUBID でみた時に重複していればSEQに連番を振りたい(SEQの初期 値は0)んですが、これをカーソルを使わずに処理可能でしょうか? {1, 1, 0} {1, 2, 0} {1, 3, 0} {1, 3, 1} {1, 3, 2} {1, 4, 0} {1, 5, 0} :
UPDATE対象のレコードを特定できないから無理じゃね? RANK関数を使えば結果セットを得ることはできるから それを一旦別テーブルに突っ込んで元テーブルと総入れ替えするとか。。。
>>192 そこまでするなら普通にcursor使うけど。
最初はこう考えたんですよ
update tab A
set A.seq = (select count(*) from tab B where A.id = B.id and A.subid = B.subid and B.seq = 0)
1行目から順番に処理してるとして、3行目の処理の時点で
{1, 1, 1} 1
{1, 2, 1} 2
{1, 3, 3} 3 ←今ここ
{1, 3, 0} 4
{1, 3, 0} 5
{1, 4, 0} 6
{1, 5, 0} 7
すると、4行目を処理する際にはseq=0の行は1行減ってるから
{1, 1, 1} 1
{1, 2, 1} 2
{1, 3, 3} 3
{1, 3, 2} 4 ←今ここ
{1, 3, 0} 5
{1, 4, 0} 6
{1, 5, 0} 7
まあ、やってみたらダメだったわけだがw
一時シーケンスで仮番振って、再処理。 まぁ複数行のバッチ処理には違いないが。 CREATE TEMP SEQUENCE t_seq; UPDATE Table AS T1 set c3=nextval('t_seq') WHERE 1<(SELECT count(*) FROM Table AS T0 WHERE (T0.c1,T0.c2)=(T1.c1,T1.c2)); UPDATE Table AS T1 SET c3=c3-(SELECT min(c3) FROM Table WHERE (T.c1,T.c2)=(T1.c1,T1.c2)) WHERE 1<(SELECT counT(*) FROM Table AS T0 WHERE (T0.c1,T0.c2)=(T1.c1,T1.c2));
195 :
NAME IS NULL :2007/12/21(金) 07:48:40 ID:vB2UAvni
サーブレットからJDBCを経由して、select count〜のSQLを実行した時に、DBMSは排他領域を使用しますか?
実行計画って、対象となるテーブルのレコード件数で変わるよね? 数件しかなければインデックス使わない、数万件ならインデックスを使う、み たいな。
>>196 オプティマイザの実装次第だろ。
オプティマイザヒント使うとか
幾らでも変えようのあるRDBMSも存在するしな。
198 :
NAME IS NULL :2007/12/23(日) 01:32:21 ID:HZ1Naom1
SQLに関して質問があります。 DBはオラクル10gです 以下のレコードが格納されていまして、 1 10 A 2 20 B 3 10 C 4 10 A 5 20 B 6 30 A 取得したいのは 1 10 A 2 20 B 6 30 C 2列目の重複を省きたいのです。重複さえ省ければどの行を取得しても 大丈夫です。(例えばAに関しては4 10 Aの行でもOK) 自己結合を使って取得することはできたのですが、 出来ればサブクエリは使いたくありません… (実際は50万行くらいある表なのでできるだけパフォーマンスを良くしたいのです) オラクルの関数などを使って取得できないでしょうか? よろしくお願いします。 ※自分が考えたのは以下のSQLです select * from A a1 where 1列目=(select max(1列目) from A a2 where a1.2列目=a2.2列目)
distinctぢゃだめなのか?
>>199 DISTINCTは行全体が一致しないと無理っぽいです…
> 6 30 C って存在しないのだが?
>>201 6 30 Aの間違いでした。すみません。
>>198 のクエリは相関サブクエリがあってインデックスが効くならまだしも
1+50万回(行数分)のseqスキャンが走ってそうだな。
で、Oracle独自の関数でいいのならOracleスレで聞いた方がいいかも。
ちなみにPostgreSQLなら DISTINCT ON を使えば1回のスキャンで済むので、
「Oracle "DISTINCT ON"」でググれば何かわかるかもしれない。
>>203 DISTINCT ONっていうのがあるんですか!それはかなり便利ですね。
postgreSQLはまだ一度も使ったことないですが、覚えておいていざというときに使いたいと思います!
「Oracle "DISTINCT ON"」で調べたところ、やはり自己結合を使う方法しかないっぽいです…
とりあえず自己結合をする形で進めて、パフォーマンスに影響がでるようだったら他の方法を
考えてみます。ありがとうございました!
>>204 PostgreSQLのDISTINCT ONは目的カラムでORDER BYして
一つ目をとったら出力して違った値が出るまでスキップ、
そして出力の繰り返し。ORDER BY 2列目,1列目 DESCをつけると
各2列目の値で1列目が最大の行をとってくれると云うことになる。
と言うことで、そんなに難しい訳でもないからPL/SQL等でで自作関数
でも作った方がいいんじゃね。
>>198 なんか難しく考えてるようだけど、ROW_NUMBER関数と
ROWID擬似列を組み合わせればできんじゃね?
select max(a1), b1, max(c1) from tbl group by b1 じゃだめなん?
>>198 すまね。
>>207 で言ってたROWID擬似列はいらなかった。
select *
from ( select row_number()
over (partition by col3
order by col3) grp_num
,col1
,col2
,col3
from test
)
where grp_num=1
order by col1
;
結果↓
GRP_NUM COL1 COL2 COL3
---------- ---------- ---------- ----------
1 1 10 A
1 2 20 B
1 3 10 C
ずれまくりなのは勘弁。
ユーザID 名前 123 あ 223 い 555 う 上記の状態でたとえばユーザIDを昇順で並べた時に3行目の名前を変更する方法ありますか? UPDATE NAME set 名前='AAA' (ここの書き方がわからない) ORDER BY ユーザID LIMIT 2,1←これで一応3行目が指定出来ると
update NAME set 名前='AAA' where ユーザID=(select ユーザID from NAME order by ユーザID limit 2,1) じゃダメなん?
>>211 UPDATE name SET 名前='AAA' WHERE ユーザID=(SELECT ユーザID ORDER BY ユーザID LIMIT 3, 1);
これでやってみたんですが,更新されません・・・
まだ勉強不足だorz
なんで2,1が3,1に変わっちゃうんだ? select ユーザID from NAME order by ユーザID limit 3,1 で何も結果が出てこなければもちろん何も更新されない。
>>213 特定の1行を更新できれば良いので番号はなんでもOKです(汗
調べたらUPDATE … WHERE ユーザID IN (SELECT … LIMIT)って方式で可能みたいなんですが
INを使用するとLIMITが併用出来ないらしいです.
他の方法でなんとか任意の行を選択するのを考えます・・・
>>210 UPDATE Table AS T1
SET name = 'AAA'
FROM (SELECT id,(SELECT count(*) FROM Table WHERE id<T2.id) AS cnt FROM Table AS T2) AS T3
WHERE T1.id=T3.id AND cnt=2;
ユーザIDは当然ユニークで、不等号で順列通りの比較が可能という条件で、
cnt=2というのは3列目な。
でも、MySQL(かな?)で動くかどうかは知らん。
216 :
NAME IS NULL :2007/12/25(火) 17:25:26 ID:8tRohosM
第一列各行に一意の整理番号を割り振った表計算ドキュメントをデータソースとし、バラバラの整理番号を指定して第二以降の列も抽出する事なんてOOoBase上でHSQLで出来ますか?
・MySQL4 ・テーブルデータ comment テーブル post_id, comment 1, テストコメント 2, コメント ・欲しい結果 該当結果がなくても、post_id, nullの形で3を含めた結果が欲しい ・実行しているSQL分 SELECT post_id, COUNT(*) AS count FROM comment WHERE post_id IN (1,2,3) GROUP BY post_id 現状、post_id 1,2の結果しか出ない post_id 3も0または、nullの形で出したい。
>>217 ないものを出せと言われてもな・・・
コメントテーブルに 3, NULL のレコードを入れとくか、
必要な post_id を列挙した別テーブルを用意しといて OUTER JOIN するか
じゃない?
TBL_AとTBL_Bがあって、どちらもSEQがPKです。 Aの内容をBにコピーしたいのですが、AのSEQ順を崩さず、かつBにコピーする 際のB.SEQはSEQオブジェクトを使いたいのです INSERT INTO TBL_B SELECT SEQ.NEXTVAL, 〜 FROM TBL_A ORDER BY TBL_A.SEQ これでTBL_Bの順序は必ず保証されるのでしょうか? カーソルで回して1行ずつinsertしないとだめでしょうか?
220 :
NAME IS NULL :2007/12/27(木) 17:47:28 ID:EI8HSTce
結合に関する話です。 SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.t1_id WHERE t1.id=1 といった結合の場合、t1.id=t2.t1_id の条件に合致するレコードが、t2テーブルに複数ある場合、 結果セットとして、複数レコード(t1のデータは同一)が返ってきますが、 1件しか返ってきてほしくない場合は GROUP BY t1.id とするのが、普通の方法でしょうか? 他に、もっと適切な方法はあるのでしょうか?
t2テーブルに複数ある場合、1件だけ返したいと言うんだけど t2テーブルのどの1レコードを選ぶの? t1.id, t2.id, t2.id2, t2.data 1, 1, 1, あああ 1, 1, 2, いいい 2, 2, 1, ううう 3, null, null, null ここからどんな結果を出したいの?
>>220 1件だけにしたい場合はどういう条件で1件に絞るのかを記述するのが普通です。
よく使うのはmaxとかminとかです。
この場合は必然的にgroup byも使うことになります。
厳密に言えば、min()/max()は1「件」を選ぶんじゃないね。
224 :
220 :2007/12/28(金) 10:22:49 ID:p8DR0nlD
ありがとうございます。 今回の場合、 関連するt2のデータが1件以上存在することさえ確かめられればいいので、 t2のデータについては、どれが取れてきても構いません。 (t2のデータ自体は使わない) t1とt2の関係は1対多です。 とすると、やっぱりGROUP BYのみでOKですかね?
DISTINCT は使えるかな?
foo( number INTEGER -- 登録番号 PRIMARY KEY ,dataA DECIMAL(13,6) -- aの値 NOT NULL ,datab DECIMAL(13,6) -- bの値 NOT NULL ,dataC DECIMAL(13,6) -- cの値 NOT NULL ,name TEXT -- 名前 NOT NULL ,today TEXT -- 日付 NOT NULL ); というテーブルが有ります。 例えばこの中には、 1, 100, 500, 400, マサル, 12/23 2, 200, 400, 300, メソ, 12/24 3, 300, 430, 200, フーミン, 12/25 4, 200, 300, 600, マサル, 12/26 5, 500, 250, 400, モエモエ 12/27 のようなデータが入っています。 そして、 SELECT * FROM foo WHERE dataA > 90 AND dataA < 210 というクエリーを発行しています。 しかしこの方法だと、 1, 100, 500, 400, マサル, 12/23 2, 200, 400, 300, メソ, 12/24 4, 200, 300, 600, マサル, 12/26 とマサルが二回出てきてしまいます。 データベースの設計が悪いと思うんですが、 どのように正規化すれば、宜しいでしょうか? また、 6, 150, 500, 400, マサル, 12/28 のような感じでnumber,dataA,dataB,dataC,todayは違うけれどnameが同じ場合、 うまくnameの重複を無くして、INSERT出来るようにしたいです。
227 :
221 :2007/12/28(金) 12:34:26 ID:???
少しエスパーすると t2に該当レコードがなくてもt1のレコードは返してほしいんだよね。 select distinct t1.id from t1, t2 where t1.id = t2 これだとt2に該当するレコードが無いとt1も出ないからダメなんだよね。 SQL> select * from t1; ID ---------- 1 2 3 SQL> select * from t2; ID ID2 DATA ---------- ---------- -------------------- 1 1 a 1 2 b 2 1 c SQL> r 1 select t1.id, nvl(tmp.flag, 'NO HIT') 2 from t1 3 left outer join 4 ( 5 select distinct t1.id, 'HIT' flag from t1, t2 6 where t1.id = t2.id 7 ) tmp 8 on t1.id = tmp.id 9* order by 1, 2 ID NVL(TM ---------- ------ 1 HIT 2 HIT 3 NO HIT これでよい? nvlはOracleの独自ファンクションだから適当に改造してくれ。
228 :
226 :2007/12/28(金) 13:33:19 ID:???
誰か〜。
マサルが重複していてはいけない理由が他の人に伝わってない。 俺もわからん。
2件あるマサルのうち1件だけ取り出したいにしても どっちのマサルが欲しいのかが不明。
232 :
220 :2007/12/28(金) 14:23:58 ID:p8DR0nlD
>>225 あ、そうか。
こういう場合はGROUP BYじゃなくて、
DISTINCTの方が正しいですね。
(結果は変わらないようですが)
>>227 > t2に該当レコードがなくてもt1のレコードは返してほしいんだよね。
その通りです。
確かに、書いていただいたSQL文だと、やりたい意図がかなり明確ですね。
(でもちょっと重そうなSQL文)
うーむ。どうしようかな。
>>226 エスパー向け問題ですね。
正規化の話としては、userテーブルなどを作って、
名前はそっちに持たせて、
fooテーブルにはそのidだけ入れとくってのが正解だと思います。
user (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
foo(
number INTEGER PRIMARY KEY
,dataA DECIMAL(13,6) NOT NULL
,datab DECIMAL(13,6) NOT NULL
,dataC DECIMAL(13,6) NOT NULL
,user_id INTEGER NOT NULL
,today TEXT NOT NULL
);
233 :
220 :2007/12/28(金) 15:08:57 ID:p8DR0nlD
>>227 すみません。急いで訂正。
いまのところ、GROUP BYで意図していた結果が得られていたので、
そのままにしていたのですが、実際に書いていたSQL文が、
文法的に間違いだということが分かりました。
t1 (
id INTEGER PRIMARY KEY,
name TEXT,
description TEXT
)
t2 (
id INTEGER PRIMARY KEY,
t1_id INTEGER,
data TEXT
)
SELECT t1.id, t1.name, t1.description, t2.id
FROM t1 LEFT JOIN t2 ON t1.id=t2.t1_id
GROUP BY t1.id
というクエリを投げて、
t2.idがNULLかどうかを見てt1の特定レコードに関連する
t2テーブルのレコードがあるか?を見ていました。
意図通りの結果を得られていたわけです(SQLite3)。
でも、SQLの文法としては間違いのようです。
間違い1:GROUP BYは集合関数なんだからDISTINCT使えよ
間違い2:GROUP BYには取得するカラム全部指定しなきゃダメ
というわけで、正しくは
>>227 以外にないということですかね?
234 :
227 :2007/12/28(金) 19:51:20 ID:???
>>233 たしかMySQLもGROUP BYの指定漏れは動く仕様だったと思う。
SQL標準からすると誤りなのは確か。
もちろんOracleではエラー。
なんか227は冗長な気がしてきた。
SQL> select * from t1;
ID NAME DESCRIPTIO
---------- ---------- ----------
1 tanaka manager
2 takahashi sales
3 satou developer
SQL> select * from t2;
ID T1_ID DATA
---------- ---------- ----------
1 1 computer
2 1 foma
3 2 wimax
SQL> r
1 select distinct t1.id,
2 t1.name,
3 t1.description,
4 nvl(t2.t1_id, -999) flag
5 from t1 left outer join t2
6 on t1.id = t2.t1_id
7* order by t1.id
ID NAME DESCRIPTIO FLAG
---------- ---------- ---------- ----------
1 tanaka manager 1
2 takahashi sales 2
3 satou developer -999
これでどうか
>>233 そこまでわかってたら、これでいいんじゃ?
select t1.id, t1.name, count(t2.id)
from t1
left outer join t2 on t2.id = t1.id
group by t1.id, t1.name
mysql 5.0.45 株価の週足を作ろうとする場合、 kabukaテーブルが stockcode 銘柄コード vol_date 出来高年月日 startingprice 始値 highprice 高値 lowprice 安値 closingprice 終値 volume 出来高 とあったとして select max(highprice),min(lowprice), sum(volume) from kabuka where stockcode=〜 and vol_date between yyyy-mm-dd1 and yyyy-mm-dd2 で週間高値・安値・出来高は得られますけど、yyyy-mm-dd1 とyyyy-mm-dd2は予め判っているとして、週初始値、週末終値 をこのsqlのなかで求める事って出来ますか?
select句の中に週初始値、週末終値をそれぞれ求める スカラー副問合せを書けばできると思うけど。 それかselect句の中でcase文を使ってごにょごにょやるとか。
二つの列が一致しているレコードの数を知りたいのですが、どうすればよいでしょうか。 名前 都道府県 年齢 AAA 東京 32 BBB 東京 31 BBB 千葉 30 BBB 千葉 29 CCC 千葉 28 CCC null 27 名前と都道府県の両者が一致しているものを1件と数える場合、 3,4行目は同じなので、5を得たいです。 DBはDerbyで、 select count(distinct 名前, 都道府県) … select count(名前) from (select 名前, 都道府県 from テーブル group by 名前, 都道府県) はどちらも使えないみたいです…。 select count(distinct 名前)ならできるのに><
SELECT count(*) FROM (SELECT ... GROUP BY 名前,都道府県);
こういうのはできないんだっけ? select count(distinct 名前||都道府県)
table:tbl __________ id,name _________ 123,aa 456,bb 789,cc 234,dd ____________ という表にSELECT * FROM tbl WHERE id=456でid直打ちした場合、 前後の行の有無を調べる方法を教えてください(idは不連続です)
前後ってのはどのカラムをどういう順序で並べたときの前後なのか示さないと無意味。
244 :
239 :2007/12/29(土) 23:53:36 ID:???
ありゃ? なんか勘違いしてる?
> 名前と都道府県の両者が一致しているものを1件と数える場合、
> 3,4行目は同じなので、5を得たいです。
で、
>>239 だと思ったんだが、あぁ、1行目の意味はさっぱりだし、
Derbyもしらんので、
>>239 で違うのなら俺にはさっぱりわからんわ。
>>241 直後は
SELECT min(id) FROM tbl WHERE id>456
直前は
SELECT max(id) FROM tbl WHERE id<456
で返り血の有無を判断すればいいんじゃね?
248 :
NAME IS NULL :2007/12/31(月) 13:15:27 ID:+l9W5+We
質問させていただきます。 年内のデータから、年初めと年終わりのデータを欲しいと思っています。 つまり select * from hoge where hiduke >= '2007/1/1' その中から hiduke = min( hiduke ) とmax(hiduke) したいのですが どうすればいいのでしょう?
select * from hoge where hiduke = (select min(hiduke) from hoge where hiduke >= '2007-01-01' and hiduke < '2008-01-01') union select * from hoge where hiduke = (select max(hiduke) from hoge where hiduke >= '2007-01-01' and hiduke < '2008-01-01');
250 :
NAME IS NULL :2007/12/31(月) 15:35:02 ID:5qw/Iwgf
whereのandでいいじゃん
>>251 whereのandだと、なぜか引っかかるの0件。
たぶん、min(hiduke)で、はるか昔のとandになってるような。
>>249 サンクスです。
そりゃ最大でかつ最小なんだから1件だけのとき以外は0件だろう OR でいいのでは
254 :
NAME IS NULL :2008/01/01(火) 00:33:10 ID:Q6OJPCZ+
あけましておめでとう(′∀`)ノシ ところで1つの行から複数の行を返すSELECT文ってどう書くですか? たとえばテーブルが ----+-- HOGE 3 のときに ----+-- HOGE 1 HOGE 2 HOGE 3 みたいな結果せっとが欲しいんですけど… 教えて!エロいひと!
255 :
254 :2008/01/01(火) 01:30:53 ID:???
日本酒飲みながらこんなの思いついたけど有り? こんなダミーテーブル(FOO)を作る REF --- 1 2 3 4 5 … MAX(BAR.NUM) んで抽出対象のテーブルBARに対して NAME NUM -----+--- HOGE 3 SELECT NAME,REF FROM FOO,BAR WHERE NUM >= REF でいいのかな? あんましCROSS JOHN使ったことないしなぁ… (自宅には携帯しかないので判りにくくてすみません)
256 :
NAME IS NULL :2008/01/02(水) 05:19:27 ID:8Xd67UwA
・DBとバージョン mysql ver5 ・テーブルデータ aaa,bbb ------- 1,111 2,121 3,111 4,111 5,143 ・欲しい結果 aaa,bbb ------- 2,121 4,111 5,143 ・説明 2番目のカラムでかぶってるのがあったら 一番下から持ってくる方法をお願いします。
mysql> select max(aaa) aaa, bbb from ab group by bbb order by 1; +------+------+ | aaa | bbb | +------+------+ | 2 | 121 | | 4 | 111 | | 5 | 143 | +------+------+ 3 rows in set (0.00 sec)
258 :
NAME IS NULL :2008/01/02(水) 06:04:25 ID:8Xd67UwA
259 :
NAME IS NULL :2008/01/02(水) 23:09:25 ID:UHDITXaq
・DBとバージョン mysql 5 ・テーブルデータ +------+------+ | id | bunrui-A | bunrui-B | bunrui-C....................................... +------+------+ | 2 | aa | null | bb | 4 | null | cc | dd | 5 | ee | null | null +------+------+ ・欲しい結果 +------+------+ | id | youso1 | bunrui1 | youso2 | bunrui2....... +------+------+ | 2 | aa | bunrui-A | bb | bunrui-C | 4 | cc | bunrui-B | dd | bunrui-C | 5 | ee | bunrui-A | null | null +------+------+ ・説明 類語データベースを作っています。 一つのレコードには同意語が品詞別にカラムに納められています。 新しい品詞が出る度に新しいカラムを足していき、品詞分類カラムが20を超えてしまいました。 一つのレコードあたり最大でも五種類の品詞の単語しか持たないため 一つのレコードで15以上のカラムがnullとなっています。 そのため、意味1、品詞1、意味2、品詞2、、、、という形にテーブルを整理し直したいのですが... caseで場合分けしてnullで無い場合はinsertみたいにしようと思ったのですがうまくいきません... 教えて!エロイ人!
品詞1と品詞2の違いは何? 違いがないんだったら、その「欲しい結果」を第一正規形にしろ。
261 :
NAME IS NULL :2008/01/03(木) 16:37:08 ID:qHl7adYm
>>260 ググってきました。第一正規形 = 繰り返しグループの排除でOK?
説明が足りなかったのですが、今のテーブルは
+------+------+
| id | 意味分類id | | 意味 | 一般語 | 敬語 | 文語.......
+------+------+
| 2 | 1 | 食べる| 食べる、食う、 | 召し上がる | ヌル
| 4 | 2 | 考える |考える |ヌル |思考する
| 5 | 2 | よく考える |よく考える、深く考える| ヌル|熟考する
+------+------+
+------+------+
| id |意味分類
| 1 | 食に関する言葉
| 2 | 考えることに関する言葉
+------+------+
一般語、敬語、等の語の分類カラムは外国語です。
実は、259で言った品詞分類とは語の分類のことで、文語、敬語、ことわざ、重語、王語....etcみたいな感じです。
正規化するとこんな感じですか↓?
意味分類テーブル→そのまま
意味テーブル
+------+------+
| id | 意味分類id |意味 |
+------+------+
| 1 | 1 | 食べる |
| 2 | 2 l 考える |
| 3 | 2 | よく考える |
+------+------+
単語テーブル
+------+------+
| id | 意味ID | 単語 | 語の分類|
+------+------+
| 1 | 1 | 食べる、食う | 一般語
| 2 | 1 | 召し上がる | 敬語
| 3 | 2 | 考える | 一般語
| 4 | 2 | 思考する |文語
+------+------+
> 新しい品詞が出る度に新しいカラムを足していき、 > 品詞分類カラムが20を超えてしまいました。 だったら品詞分類テーブルも作っといたほうが。 +--+---------- |id|品詞分類名 +--+---------- | 1|一般語 | 2|敬語 | 3|文語 +--+----------- 単語テーブルに「食べる、食う」とあるのは 正規化できてないだろう。 +--+------+----------+------------ |id|意味ID|品詞分類ID|単語 +--+------+----------+------------ | 1| 1| 1|食べる | 2| 1| 1|食う | 3| 1| 2|召し上がる | 4| 2| 1|考える | 5| 2| 3|思考する +--+------+----------+------------ こうじゃね?
263 :
NAME IS NULL :2008/01/05(土) 02:10:08 ID:YdrW63jX
以下のようなテーブルがあります。 それぞれの所属に対して同じ名前の人はいないとします。 ID 所属 名前 -------------------- 01 社員 菊池 02 社外 矢薙 03 社外 小暮 04 社員 田中 05 社外 田中 06 社員 矢野 社員の菊池さんと矢野さん、社外協力者の田中さんの3人を取得したい場合、条件式を (所属=社員 AND 名前=菊池) OR (所属=社員 AND 名前=矢野) OR (所属=社外 AND 名前=田中) にしなければならないと思いますが、これを IN のようにスマートに記述する方法はありませんでしょうか? 文字列合成して IN ……というのも考えましたが、速度的にマズそうですし。 ちなみにMySQL 3.23です。
SQLの標準としては (所属, 名前) in (('社員', '菊地), ('社外', '田中'), ...) と書けることになっている。 MySQLで書けるかどうかはシラネ。
265 :
NAME IS NULL :2008/01/05(土) 15:40:34 ID:nKj5MD+j
>SQLの標準としては > (所属, 名前) in (('社員', '菊地), ('社外', '田中'), ...) >と書けることになっている。 MSSQL鯖使いの俺。 知らなかった!画期的だ!と思って試してみたが...... 出来なかった.....orz >文字列合成して IN ……というのも考えましたが、速度的にマズそうですし。 レコード数と抽出対象数でも変わると思うが、orでだらだら記述するより早いと思うよ。 あとはインデックスとか設計の問題だろ。
SQL標準だったのか。 Oracle以外で使えるのを見たことがなかったので、 Oracleの拡張だと思ってた。
267 :
263 :2008/01/05(土) 16:14:03 ID:???
thxです。 >264 残念ながら、ウチの環境でも出来ませんでした……。 すげー便利そうなのに。 >265 ORってそんなに速くなかったんですね。 パターンとindexを変えつつ実測してみます。
>>267 文字列連結して...なんてtrickyな方法は初心者のうちはやらんほうが良い。
どっちにしろ、大してメリットはない。
269 :
NAME IS NULL :2008/01/05(土) 16:45:57 ID:nKj5MD+j
265だ。SQL鯖だが検証してみた。 3レコード抽出 200万件のテーブルだと 文字連結 3秒 or 1秒以下 1万件のテーブルだと、どちらも1秒以下 実行プランを見ると、1万件だと同じ、200万件のorだと内部で最適化している。 俺は、レスポンスが同じなら文字連結には可読性が高いというメリットがあると思う。
270 :
264 :2008/01/05(土) 18:18:36 ID:???
間違えた。
SQL92のBNF見てみたら
(所属, 名前) in (values ('社員', '菊地'), ('社外', '田中'), ...)
が正しいっぽい。
ちなみにこっちはUDBで動いた。
>>264 のはOracleのみかな?(Oracleではvaluesつきは動かなかった。)
>268 どうしても速度的にダメだったら考える方向でやってみます。 >269 僕も試してみましたが、インデックスの関係もあって速度差が大きかったです。 MySQLって関数インデックス無かったですよね……。 検索用のフィールドを作るという手段も検討してみます。 >270 どっちもダメでした orz
272 :
NAME IS NULL :2008/01/05(土) 20:43:19 ID:Ible2iRH
CDタイトル トラック アーティスト ------------------------------------- A 1 あいうえお A 2 あいうえお A 3 あいうえお B 1 かきくけこ B 2 かきくけこ C 1 さしすせそ D 1 たちつてと となっている場合で表示を タイトル アーティスト --------------------- A あいうえお B かきくけこ C さしすせそ D たちつてと のように、どんな場合でも必ず一つ表示するようにしたいのですができません。 どうすればいいでしょうか?
distinctじゃダメなのけ?
おぉできました こんな簡単な方法があったんですね、知りませんでした。。 ありがとうございました。
276 :
NAME IS NULL :2008/01/09(水) 11:46:51 ID:0hzAlDFs
初歩的な質問で恐縮ですが、教えて下さい。 2つのテーブルを結合した結果以外のデータを抽出する方法はありますか? 具体的には、 SELECT TABLE1.data_id,TABLE1.data FROM TABLE1,TABLE2 WHERE TABLE1.data_id=TABLE2.data_id; によって求められたTABLE1の結果以外のデータが欲しいのですが。 例えば、 TABLE1 data_id data ----------- 1 a 2 b 3 c 4 d 5 e TABLE2 data_id ------- 1 3 5 のとき、結果として TABLE1 data_id data ------------ 2 b 4 d を取得したいという意味です。 WHERE NOT でいいかと思ったら全然違いました。
SQL> select table1.data_id, table1.data 2 from table1 left outer join table2 3 on table1.data_id = table2.data_id 4 where table2.data_id is null; DATA_ID DATA ---------- ---------- 2 b 4 d SQL> select table1.data_id, table1.data 2 from table1 3 minus 4 select table1.data_id, table1.data 5 from table1, table2 6 where table1.data_id = table2.data_id; DATA_ID DATA ---------- ---------- 2 b 4 d SQL> select table1.data_id, table1.data 2 from table1 3 where not exists 4 ( 5 select 1 6 from table2 7 where table1.data_id = table2.data_id 8 ); DATA_ID DATA ---------- ---------- 2 b 4 d 好きなの選べ
>>277 なるほど、left outer join を使うのですね。良く分かりました。
ありがとうございました。
9時間前を日時をdatetime型に書き込もうと INSERT INTO tbname value(NOW()-090000); としてもデフォルトの0000-00-00 00:00:00となってしまいます。 SELECT NOW()-090000; だと正しく表示されるのですが、何がいけないのでしょうか?
280 :
279 :2008/01/10(木) 02:10:39 ID:???
MySQLスレと勘違いしてました。 MySQLスレに行ってきます。スレ汚しすみません。
281 :
NAME IS NULL :2008/01/10(木) 19:14:10 ID:WGaCv2Wl
PostgreSQLでconstraint_exclusionパラメータがonになっていることを確認した上でSELECT文で検索をかけたのですがoffのときと処理時間が全く変化していません explainオプションで検索対象となっているテーブルを見てみるとちゃんとその条件に合ったテーブルのみを検索していました なぜ処理時間が短くなっていないんでしょうか・・・
パラメータがoffの場合には条件に合ってないテーブルも検索していると いうことはexplainで確認しているんだな? だとすれば、その検索条件での「条件に合ってないテーブル」の検索 時間がほぼ0だったということだろうな。 パーティションキーと同じインデックスが設定されていたりしたら、そういう こともあるだろうね。 つかスレ違い。
283 :
NAME IS NULL :2008/01/11(金) 03:22:11 ID:8tmgKopy
このようなことは可能でしょうか? ・Oracle10g ・テーブル グループ 番号 ------------- A 2 B 1 B 2 A 1 C 1 C 2 ・得たい結果 例)ログインユーザーのグループが、Aのとき グループ 番号 ------------- A 1 A 2 B 1 B 2 C 1 C 2 例)ログインユーザーのグループが、Bのとき グループ 番号 ------------- B 1 B 2 A 1 A 2 C 1 C 2 ・説明 指定したグループをかならず一番上にまとめて表示させたい。 このグループ内の順番は番号順に並べる。 WHEREで指定すると指定されたグループしか表示されないが、 指定していなかったグループも指定したグループが終わった後に 表示させたい。 指定していないグループ内の順番は番号順でもそうでなくてもよい。 これをSELECT文一回で表示させたい。 よろしくお願いします。
>>283 > 例)ログインユーザーのグループが、Aのとき
SELECT * FROM Table ORDER BY CASE WHEN グループ = 'A' THEN '' ELSE グループ END,番号;
> 例)ログインユーザーのグループが、Bのとき
SELECT * FROM Table ORDER BY CASE WHEN グループ = 'B' THEN '' ELSE グループ END,番号;
該当グループなら空白('')に置き換えている。ORDER BY で空白が先頭に来ないなら他の文字とかに置き換えてみて。
グループがA-Zならスペース(' ')でもいいかな。
285 :
NAME IS NULL :2008/01/11(金) 09:18:24 ID:n21xRFqN
>>284 できた!すげえ
283じゃないが
ORDER BYにCASE文書けるの知って
感心したのでカキコ
287 :
NAME IS NULL :2008/01/14(月) 19:38:59 ID:nql/697b
DBとバージョン SQLServer7 テーブルデータ テーブルX ID1 ID2 商品名 --------------------------------- 001 111 あああ 001 222 いいい 002 111 ううう 002 222 えええ テーブルY ID 商品説明 -------------------------------------- 001000111 aaa 001000222 bbb 002000111 ddd 002000222 ccc 説明 テーブルYのID列の値は「ID1列の値 + '000' + ID2列の値」になっています。 上記2つのテーブルを結合し、商品名と商品説明を1つのSQL文で取得することは可能でしょうか? お分かりになる方がおられましたら、ご教授宜しくお願い致します。
SELECT X.商品名, Y.商品説明 FROM X INNER JOIN Y ON X.ID1 + '000' + X.ID2 = Y.ID SELECT X.商品名, Y.商品名 FROM X, Y WHERE X.ID1 = LEFT(Y.ID 3) AND X.ID2 = RIGHT(Y.ID, 3) SQLServer7は触ったこと無いから、動作確認は取ってないが。
289 :
NAME IS NULL :2008/01/15(火) 03:33:19 ID:hl8ko7ED
Access 2000 条件によって範囲が異なる集計値を得たい場合のテーブル・クエリ設計をご指導ください。 たとえば以下のようなものです。 Table A CondA CondB CondC Value ------------------------ . 1A 1B 1C 100 . 1A 1B 2C 200 . 1A 2B 3C 300 . 1A 2B 2C 400 というツリー状(?)のテーブルAに対して Table B ID CondLevel CondA CondB CondC ---------------------------- . 1 1 1A . 2 2 1A 1B . 3 3 1A 2B 2C のような条件テーブルを作り、 各レコードに対してのValue合計を出すことは可能でしょうか。 結果 ID Sum(value) ------------ 1 1000 2 300 3 400 それぞれの条件を事前に決めておいて、 各条件に見合った集計を出した後にUNIONで連結するしかないのでしょうか。 これらのテーブルは仮なので変更OKです。 どうぞ、よろしくお願いします。
>>289 TableBの空のところはNULLだとして
accessじゃIF NOT FALSEは無理かな。
SELECT B.id,sum(A.value)
FROM TableB AS B JOIN TableA AS A
ON (A.CondA=B.CondA)IS NOT FALSE
AND (A.CondB=B.CondB)IS NOT FALSE
AND (A.CondC=B.CondC)IS NOT FALSE
GROUP BY B.id;
Cond*を連結して前方一致でおkなら
SELECT B.id,sum(A.value)
FROM TableB AS B JOIN TableA AS A
ON A.CondA||A.CondB||A.CondC LIKE B.CondA||COALESCE(B.CondB,'')||COALESCE(B.CondC,'')||'%'
GROUP BY B.id;
291 :
NAME IS NULL :2008/01/15(火) 16:11:40 ID:VmdUH5Fg
>>289 TableBの空白を「*」で埋めてから
SELECT B.ID, Sum(A.value) AS [sum(value)]
FROM TableB AS B, TableA AS A
WHERE ((A.CondA Like B.CondA)
AND (A.CondB Like B.CondB)
AND (A.CondC Like B.CondC))
GROUP BY B.ID
292 :
NAME IS NULL :2008/01/15(火) 16:16:36 ID:VmdUH5Fg
追加 入る値によっては「*で埋めないでも」こっちでも可 SELECT B.ID, Sum(A.value) AS [sum(value)] FROM TableB AS B, TableA AS A WHERE ((A.CondA Like (B.CondA & "*")) AND (A.CondB Like (B.CondB & "*")) AND (A.CondC Like (B.CondC & "*"))) GROUP BY B.ID
293 :
NAME IS NULL :2008/01/15(火) 18:06:21 ID:Az9jU2qh
MySQL SNSの友達登録のような事をやりたいのですが、テーブル設計についてお聞きします。 テーブル 友達 依頼者 受諾者 承認 -------------------------- 001 002 1 001 003 NULL 002 003 1 002 004 1 というようなテーブル設計で良いのでしょうか? 一度承認されたら依頼者・受諾者関係なく双方から友達を抽出したいのと、下記のような重複をさせたくないのですが。。 依頼者 受諾者 承認 --------------------------- 001 002 1 002 001 1
常に重複した形にするって手もある。 元の設計じゃあ、2行目がどっちの承認が必要なのかわからんし。
295 :
NAME IS NULL :2008/01/15(火) 23:30:31 ID:Az9jU2qh
>>294 お返事ありがとうございます。
>>293 では承認は常に依頼者→受諾者という風には考えているのですが、
重複の制御や双方からの抽出を考えたら、やはり全て重複させるほうが
いいんですかね?
という事は、
ユーザー1 ユーザー2
----------------
001 002
002 001
002 001
というような承認列を無くし、重複(双方向に)した場合のみ承認というような設計にすれば良いのでしょうか?
296 :
NAME IS NULL :2008/01/15(火) 23:33:01 ID:Az9jU2qh
訂正。
>>294 お返事ありがとうございます。
>>293 では承認は常に依頼者→受諾者という風には考えているのですが、
重複の制御や双方からの抽出を考えたら、やはり全て重複させるほうが
いいんですかね?
という事は、
ユーザー1 ユーザー2
----------------
001 002
002 001
002 003
というような承認列を無くし、重複(双方向に)した場合のみ承認というような設計にすれば良いのでしょうか?
上の場合001と002は承認済み、002は003に依頼中。
SNS系は全く関与したこと無いから外しているかもしれないが、
最初の
>>293 で良くね?
お友達一覧は、
あるIDが依頼して承認された受諾者一覧
UNION
あるIDが受諾承認した依頼者一覧
で出来るし。
SQLにすると、
SELECT 受諾者 FROM Table WHERE 依頼者='あるID' AND 承認=1
UNION
SELECT 依頼者 FROM Table WHERE 受諾者='あるID' AND 承認=1;
後で、どちらが依頼したのかわかるし、依頼中や承認待ちも出せる。
UNIONよりは普通にORしたほうが速いんじゃね? SELECT 受諾者 FROM Table WHERE (依頼者='あるID' OR 受諾者='あるID') AND 承認=1 テーブルの大きさによっては有意な差にはならんかもしれんけど。
299 :
NAME IS NULL :2008/01/16(水) 15:25:11 ID:nIBpbjue
>>297 ,298
ありがとうございます。
>>293 の設計でやってみようと思います。
実は現在
>>296 のようなテーブルでお気に入り登録のような形(承認無しの一方向登録)で運用していまして、できればデータ移行をしたいのですが、
id1 id2
----------------
001 002
002 001
003 001
↓
id1 id2 承認
-----------------------
001 002 1
003 001 NULL
というようにテーブル移行したいのですが、これはどのようにしたら良いのでしょうか?
select id1,id2 from 友達 as A where A.id1 IN (select B.id2 from 友達 as B where A.id2=B.id1); で、双方向登録分
select id1,id2 from 友達 as A where A.id1 NOT IN (select B.id2 from 友達 as B where A.id2=B.id1); で、一方向登録分
で一応重複レコードは抽出できたのですが、その重複2レコードを1レコードにする方法がわかりません。
2レコード→1レコードする場合のid1とid2の方向は気にしません。
300 :
298 :2008/01/16(水) 19:41:06 ID:???
これで承認済、未承認とも一発でいけるかな。
select A.id1,
A.id2,
case when B.id1 is null then null else 1 end
from 友達 A
left outer join
友達 B
on A.id2 = B.id1
and A.id1 = B.id2
where A.id1 < A.id2
or B.id1 is null
;
あと、
>>298 はSELECT句にCASE文を入れてごにょごにょやるとかしないと
このままじゃダメだなって今気付いた。
301 :
NAME IS NULL :2008/01/16(水) 20:35:21 ID:nIBpbjue
>>300 298さん、多謝ですm(__)m
>where A.id1 < A.id2
の部分に目から鱗でした。
302 :
NAME IS NULL :2008/01/17(木) 13:07:15 ID:BskMVrmk
埼玉 麻生●郎 埼玉 麻生●郎 東京 麻生●郎 東京 安倍●三 東京 中川酒 東京 中川酒 ↓ 埼玉 麻生●郎 東京 麻生●郎 東京 安倍●三 東京 中川酒 のように、都道府県と住所が全く同一のデータがあった場合、 1つのデータとしてまとめたいのですが、 SQLでこの動作をさせるには どのようにしたらよいでしょうか? 当方Accessなので、クエリのやり方でもかまいません。
group by address, name
304 :
302 :2008/01/17(木) 13:53:08 ID:???
305 :
289 :2008/01/17(木) 17:22:31 ID:Q2ceU5zI
>>290-292 ありがとうございました。
Accessでは is not null が使えなかったので、
>>292 の方法を使わせていただきます。
WHEREで指定した条件で抽出したデータの件数をcount(*)で数えて出力したいのですが、 WHEREで指定した条件に当てはまらない場合に0と表示させるにはどうしたらいいでしょうか? 具体的には、 SELECT DISTINCT 名前,count(*) FROM 表名 WHERE 条件 ←この条件に当てはまらない「名前」項目が存在する GROUP BY 名前; としたときに、全ての「名前」を表示させ、条件に当てはまらなかった場合は0と表示したいのです。 (正確にはこの条件でビューを作成したいので、条件に当てはまらない場合は0という値を入れたい) isnullというのが必要なのかと思い試してみましたが上手くいきません。 SQLはMySQLです。よろしくお願いします。
>>306 WHERE句で絞るんじゃなくて、SELECT句の中でCASE文使って絞らないと無理かと。
ひょっとしたら自己結合が必要じゃないのかな? サンプルデータがあればわかりやすいのだが。
309 :
306 :2008/01/17(木) 21:26:34 ID:???
>>307 まだSQLを学習したばかりなのでCASE文というのを初めて聞きました。これから調べてみます。
>>308 テーブルの内容は、スポーツの試合結果で、「試合の通し番号」「チーム名」「チームの得点」
この3つのデータが入っています。WHERE文の中では自己結合を行い、
試合結果が引き分けであったもののみを抽出し、その数をチーム名ごとにcount(*)で数えています。
(条件:通し番号が等しい、チームの得点が等しい、チーム名が同一でない)
問題は、引き分けた試合がないチームが存在していて、そのチームの名前が出力されないことです。
307さんの仰っていたCASE文でできないかどうか試してみます。
>>307 ,308
CASE文を使い、SUM(条件式 THEN 1 ELSE 0)としたらできました!ありがとうございました。
CASE文、もーちょっとシンプルになればいいのになといつも思う。
312 :
NAME IS NULL :2008/01/18(金) 17:47:33 ID:Izw6jTBj
当方postgresqlです。 住所録から市(町村は無視)ごとの人数をカウントしたいのですが、 どのようにしたらよいでしょう? データは↓のように市名以降の住所が1つのカラムに入っています。 さいたま市○○1−2−3 川越市○○4−5−6 所沢市○○7-8 秩父市○○10-11-12-103 さいたま市○○14-15-206 秩父市○○1−2○○マンション さいたま市○○○○○センター ↑のDBから↓の結果を得たい さいたま市 3 秩父市 2 川越市 1 所沢市 1
ナントカ市村とかそういう地名がどっかにはありそうなので、一般性を持たせて まじめにやると市名データを全部もつしかないような気がするな。 適当に手抜きをする場合でも市川市と四日市市に注意。
市ごとに集計したいのに市を別カラムにしなかったのが敗因だな
315 :
312 :2008/01/18(金) 18:44:46 ID:???
ですねorz
>>313 市原市と廿日市市もね。
あと、伊達市(北海道、福島県)と府中市(東京都、広島県)も
場合によっては要注意かも。
【質問】 1行だけ更新してすぐにコミットするような処理ではデッドロックは起きないのでしょうか? また、1行だけ削除してすぐにコミットするような処理でもデッドロックは起きないのでしょうか? デッドロックがトラウマになって眠れません。すいませんが教えてください
ロックのタイムアウトでも設定しとけ。 どっちかが落ちてロールバックされる。
>>317 デッドロックは起きませんがロック待ちはありえます
PL/SQLの効率改善をしようとしています。 データベースはOracle 8 です。 SQLは以下のようになります。 SELECT A.abc,A.def,B.ghg FROM TEST_1 A INNER JOIN TEST_2 B ON A.fff_cd = B.fff_cd WHERE A.ccc_cd = '1' AND (A.ddd_cd = '1234' OR A.ddd_cd = '2222' OR A.ddd_cd = '3333' OR A.ddd_cd = '4321' OR A.ddd_cd = '5555' OR A.ddd_cd = '6666' OR A.ddd_cd = '9999') ORDER BY A.bbb,A.hhh,A.kkk 現在問題になっているのは、TEST_1がFULL SCANになっており、参照時間が遅いようなのです。 INDEXは付与していますが、参照するデータ件数が多い場合は効果がありません。 TEST_1は今後データ件数が増えるので、参照データが多い場合でも効率がよくなるようにしたいと思っています。 ddd_cdはカーディナリティが高いためビットマップ索引は不向きと思われますので、これ以外で何かいい方法は ないものでしょうか?
>>321 オプティマイザヒント与えればいいと思うけど。
それが嫌ならORをやめてUNION ALLにするとか。
てかOracle 8て。。。
>>322 ありがとうございます。
教えていただいた方法を試してみます。
確か8だったと思うんです。
ちなみにOracle 9以降だと別の方法があったりするのでしょうか?
現在環境がない為、すぐに試してみることができないのですが、
他にも案がある方がいらっしゃれば、教えて頂けないでしょうか?
よろしくお願いします。
>>321 indexがあるといっても、どういうindexがあるのか書かなきゃわからんだろ。
TEST_1.ddd_cdのカーディナリティが高いのなら普通のbtree-indexが効くはずだが、
これも「高い」じゃわからん。
325 :
NAME IS NULL :2008/01/20(日) 16:06:59 ID:TfWLYbOj
>>324 ありがとうございます。また説明不足ですみませんでした。
現在、SI Object Browser9を使用して作業をしており、INDEXはこれで
付与したいオブジェクトを選択し、特に何の設定もなしで作成したものです。
このINDEXがどの種類なのか今現在は分かっていない状態です。
確認不足ですみません。
これがbtree-indexではないならば、試してみようと思います。
カーディナリティについても、現状では高いことしか認識しておらず、
詳しい回答ができません。今後の為にもどのような情報があれば
よいのか教えていただければ幸いです。
いや、聞きたかったのはbtreeかbitmapかということ以前に、どの フィールドにindexを付与したのかということ。 その情報がないのにsqlだけ見せられて、indexが使われない理由を 答えられるわけがない。 full scan になってしまうのが期待と違うということならば、どのindexが どう使われるか期待していたはずだから、なぜそうならなかったのか 調べてみればいい。
> 参照するデータ件数が多い場合は効果がありません
てのが気になるな。
参照するデータが少ないときはINDEX使ってるってことでしょ?
同じSQLで右辺の値が変わっただけでアクセスパスが変わることはない
(ヒストグラム取ってればありえるのかな?)から、
「参照するデータ件数が多い」ってのはOR条件を足していってると思うんだ。
だとすれば
>>322 のようにORをやめてUNION ALLにするってのは
効果あるかもしれん。
328 :
NAME IS NULL :2008/01/20(日) 19:57:10 ID:TfWLYbOj
>>326 WHERE句にある項目(ccc_cd,ddd_cd)に付与しています。
INDEXが期待通りに使われないのは、「OR」が連なっているところにあると思われます。
「OR」の数を減らすとFULL SCANではなくなりましたので。
>>327 ありがとうございます。
UNION ALLを使用してみます。
ちなみに「OR」を使用したまま少しでも効率を上げる方法(322の方から
教えていただいた「オプティマイザヒント」を試してみる以外)はありますでしょうか?
329 :
NAME IS NULL :2008/01/20(日) 23:50:06 ID:68hHwUdb
Oracle10G R2@PLSQLの質問です。
板違いならば、誘導御願いします。
動的SQLを作成し、DBMS_SQL.executeは正常にできているようなのですが、
DBMS_SQL.fetch_rowsの際に失敗してしまいます。
どうもEXCEPTIONにも飛んでいないようで、困っております。
動的SQLのWhere句の長さも大したことありませんし、取得してくるデータもそんなに沢山ではありません。
同様の現象に悩まされた方いらっしゃいますでしょうか?
現象としては、下記URLと同様です。
http://www7.big.or.jp/~pinball/discus/oracle/68425.html 以上、お力添えのほど御願いします。
330 :
NAME IS NULL :2008/01/21(月) 09:50:23 ID:2Jz4cX3z
POSTGRESQLのSQLで以下はどのように書くのでしょうか? テーブルは次のようになっています. hizuke(日付)は timestamp without time zone 型 ecr_no(レジ番号)は integer 型 hizuke | ecr_no 2008/01/21 00:10:10 | 1 2008/01/21 00:31:00 | 1 2008/01/21 02:05:21 | 2 2008/01/21 03:24:18 | 1 2008/01/21 03:24:57 | 2 ここから以下のような結果を得たいのですが, このようなときどのように書くのでしょうか? yyyy/mm/dd hh | 1 | 2 2008/01/21 0 | 2 | 0 2008/01/21 1 | 0 | 0 2008/01/21 2 | 0 | 1 2080/01/21 3 | 1 | 1
>>330 SELECT
to_char(hizuke,'YYYY/MM/DD HH24')AS hidukeDesyo,
sum(CASE WHEN ecr_no=1 THEN 1 ELSE 0 END)AS "1",
sum(CASE WHEN ecr_no=2 THEN 1 ELSE 0 END)AS "2"
FROM Table
GROUP BY to_char(hizuke,'YYYY/MM/DD HH24');
但し、
>> 2008/01/21 1 | 0 | 0
は出ない。標準だったかオプションだったか忘れたけど、
数列を返すテーブル関数があったと思うので、
それを利用して結合させれば出るかな。
すいません、教えてください。 データ 番号,人,日付 1,aさん,2007-1-2 2,bさん,2007-1-3 3,aさん,2007-1-5 4,bさん,2006-1-1 で人でグループ化して日付がMINのときの人、番号を取得したいのですが。 結果 aさん,1 bさん,4 初心者の質問ですいません、よろしくお願いします。
333 :
グループ化って :2008/01/21(月) 16:53:15 ID:HFSWx6s6
あげときます。
334 :
NAME IS NULL :2008/01/21(月) 16:56:15 ID:2Jz4cX3z
>>331 ありがとうございます.
これから数列を返すテーブル関数について調査します.
■DBとバージョン MySQL 5 ■テーブルデータ [games] date, point, player_id ------------------------- '2007/1/2', 10, 1 '2007/11/3', -3, 1 '2008/11/3', 4, 1 '2006/10/9', 7, 2 '2005/11/9', 15, 2 '2007/8/20', -30, 2 '2007/9/20', -9, 3 [players] ------------------------- id, name 1, 'taro' 2, 'hanako' 3, 'edogawa' ■欲しい結果 ('2008/1/1' までの場合) name, sum(point) 'taro', 7 'hanako', -8 'edogawa', -9 ■説明 特定の日付までのプレイヤー毎のポイントの合計を名前と一緒に出したいと思っています。 単に合計であれば、group by と sum で出来るのがわかるのですが、 名前を付加したい場合にどうすれば良いかわかりませんでした。 実際のデータが多いので、SQL一発出来ない物かと思いました。 (playersが約3000、gamesが20万くらい) よろしくお願いします。
んー、GROUP BY で出したものと players をLEFT JOIN するというのでどうか。 SELECT name,points FROM players LEFT OUTER JOIN (SELECT player_id,sum(point) AS points FROM games WHERE date1 <= '2008-1-1' GROUP BY player_id ORDER BY player_id) AS x ON x.player_id = id こんな感じ?
>>338 うまいことできました。ありがとうございます。
それにしても、結構時間がかかってしまうものなんですね。
>>337 ふつーにJOINしてGROUP BY nameじゃだめなのか?
同じnameの別idがいるとか?
>>340 なるほど、アドバイスありがとうございます。
自分で "join" で色々ググって書いてみました。
select name, sum(point)
from players
left join games
on games.player_id = id
where `date` < '2007/12/31'
group by id
name は被る可能性があるのでダメなんですが↑で出来たようです。
342 :
NAME IS NULL :2008/01/23(水) 11:00:18 ID:+ZXzx9CZ
ソーシャルブックマークシステムでタグで検索する仕組みを検討しています。 あるブックマーク(記事)を基にして、同じようにタグがついた類似記事を探す場合SQLはどのように書いたら良いのでしょうか? タグはマスタ化してます。 記事テーブル D_BOOKMARK BM_ID BM_TITLE ... 記事のタグテーブル D_TAG BM_ID TAG_ID ※複数の人が記事に同じタグを付けることもありますが問題を簡単にするために、 記事にあるタグが件数に関わらずついていたらD_TAGに1レコード入ります。 タグマスタテーブル M_TAG TAG_ID TAG_NAME
>>342 「類似」をどう定義するかによると思うけど。
例えば「BM_IDが:hogeの記事に対して、3つ以上のタグが一致する」
みたいなので良ければ
select A.BM_ID, count(*)
from D_TAG A
inner join
(select TAG_ID from D_TAG where BM_ID = :hoge) B
on A.TAG_ID = B.TAG_ID
where A.BM_ID <> :hoge
group by A.BM_ID
having count(*) >= 3
;
とか。
344 :
NAME IS NULL :2008/01/24(木) 17:49:38 ID:5OB0Vz41
345 :
NAME IS NULL :2008/01/24(木) 20:28:44 ID:M1TBm+9M
論文書いててプログラムを一行ずつ説明する必要があるんですが 下のような記述がいっぱいあるのですがどうも理解不足で説明できません。 特にwhileの条件部分が難しいです。配列に$resultの値を入れてさらにその値を$row に渡すのが疑問です。 $result=mysql_query("select count(input) from abc where input='100'",$mylink); while($row=mysql_fetch_array($result)){ $coin100=$myrow[0]; } 質問内容もあいまいになってしまいましたが、なんとなくわかるかた↑の文の解説 お願いします
346 :
NAME IS NULL :2008/01/24(木) 20:34:11 ID:cEy3KHbK
>345 自分でわからんものを論文に書くな。 わからないなら論文各のやめれ。
347 :
のぞみ :2008/01/24(木) 22:46:36 ID:HV897WY2
すみません。 SQLで、聞きたい事があります。 VBを使用してデータベースにアクセスしてデータテーブルを取得してデータグリッドに表示させるのですが、 空のデータテーブルを取得するには、どうしたら良いのでしょうか? 列名が取得できれば良いのですが・・・。 例えば、私は、方法が思いつかなかったので、 VB側 Dim strSQL As String 'SQLを入れる変数 strSQL = _ "SELECT ID, NAME FROM Syain_Masuta WHERE =" & 有り得ない値 と言うようにWHEREで有り得ない値を取得しデータグリッドに表示させているのですが、 もし、 SQLerver等でINSERT文で有り得ない値を追加されてしまうとデータグリッドに表示されてしまいます。 データグリッドには、列名(ID, NAME)だけを表示させたいのです。 長文ですみませんが、解る方がいましたらよろしくお願いします。
>>347 where 1<>1 でいいんじゃね?
349 :
のぞみ :2008/01/24(木) 23:45:00 ID:HV897WY2
>>348 すみません。ありがとうございます。
「WHERE1<>1」の意味って、1は1と等しくないって意味でしたよね?
仕事で、急にSQLやらされて昨日から本を買って勉強して・・・。
助かりました。
350 :
NAME IS NULL :2008/01/25(金) 16:26:27 ID:qwwMjCS6
MySQL TABLE A id date -------------------------- 1 2007/08/05 1 2007/03/03 2 2008/01/03 1 2006/12/12 3 2007/09/05 1 2008/01/03 2 2007/10/20 これをID毎に2件となるまでdateの古い方から削除したいのですが、 SQL一文で書く方法はありますでしょうか?
>>350 MySQLで動くかどうか不明ですが、
DELETE FROM TableA AS T1 WHERE 2 < (SELECT count(*) FROM TableA WHERE id = T1.id AND date > T1.date);
CompanyCode ShopCode 300 100 300 110 300 120 300 150 300 160 350 90 350 100 350 150 350 170 400 80 400 100 400 110 とある時に会社・店で選択する時、同じ会社であれば 例えば where companycode= 300 and shopcode between 120 and 160 と書けますが、300の150から400の80までを選択したい時 ってどう書けば良いでしょうか?
where companycode * 1000 + shopcode between 300150 and 400080 とか?
354 :
352 :2008/01/26(土) 22:54:38 ID:???
>>353 あ〜、やっぱりそうなりますよね。どうもですm(_ _)m
>>354 まて、そんなんで「やっぱり」とか納得すんなw
where (companycode = 300 and shopcode >= 150) or (companycode = 400 and shopcode <= 80)
それじゃだめ。場合分けをきちんと。
where (companycode = 300 and shopcode >= 150) or (companycode > 300 and companycode < 400) or (companycode = 400 and shopcode <= 80)
companycode = 350 の店も含むのか。
360 :
352 :2008/01/27(日) 08:05:22 ID:???
おおっ。起き抜けに見たら皆さんありがとですm(_ _)m w
SHOP_id products・・・set('1','2','3','4','5','6','7','8') ---------------------------------------------------------------- 1 1,2,3 2 1,2,3,4,5 3 5,6,8 4 1,2,7 5 2,4,5,6,7,8 というようなTableがあるのですが、たとえばSHOP_idが1とproductsが多く重なるものでソートして抽出したいのですが可能でしょうか? 期待する結果はSHOP_idの順番で2,4,5なのですが。
テーブルA 名前 目的 山田 エアロビ 鈴木 水泳 佐藤 水泳 テーブルB 名前 目的 佐藤 エアロビ 田中 ランニング 山本 水泳 テーブルC 名前 目的 鈴木 ランニング 田中 水泳 というテーブルがあったとして、 名前 目的 山田 エアロビ 鈴木 水泳 佐藤 水泳 田中 ランニング 山本 水泳 という結果を得たいです。名前は一意に決まってます(テーブルAとテーブルBの佐藤は同一人物) 目的がテーブルごとにかわるような感じで、名前を重複なく、目的とセットで抽出したいです。 (同一人物の目的が複数ある場合はその中のどれでもよい) select * from テーブルA union all select ・・・ とやって、最後に group by とやろうと思ったら、* を含む場合はダメと怒られてしまいました(access です)。 調べてもわからず途方にくれてます。何かよい方法ないでしょうか?
DB初心者です。 GROUP BY について質問があります。 ----TABLE_A---- |DataA|DataB|DataC| ------------------ | AAA | WWW |1111 | BBB | XXX |2222 | AAA | YYY |3333 | DDD | ZZZ |4444 この様なテーブルがあった場合に、DataAカラムがAAAの物を選び出し、 更にDataCの中の最大値を調べ、最大値となった行のDataBを抜き出す方法はあるのでしょうか? 自分でやってみた方法として以下の様なSQLを試してみたのですが SELECT DataB MAX(DataC) FROM TABLE_A WHERE(DataA=AAA) GROUP BY DataA このSQLだとDataBのカラムがMAX(DataC)と同じ行の値にはならない様です。 なにか句が足りないのでしょうか? また、上記の抽出をDataAがAAAであるカラムに限定せずに行いたいのですが、何か良い方法はありませんでしょうか。 具体的には以下の様な抽出結果を求めています。 ----結果---- |DataA|DataB|DataC| ------------------ | AAA | YYY |3333 (AAAグループの中の最大値を持つ行を抽出) | BBB | XXX |2222 (BBBグループの中の最大値を持つ行を抽出) | DDD | ZZZ |4444 (CCCグループの中の最大値を持つ行を抽出)
>>362 SELECT * FROM TableA
UNION ALL
SELECT * FROM TableB WHERE 名前 IN (SELECT 名前 FROM TableB EXCEPT SELECT 名前 FROM TableA)
UNION ALL
SELECT * FROM TableC WHERE 名前 IN (SELECT 名前 FROM TableC EXCEPT SELECT 名前 FROM TableB EXCEPT SELECT 名前 FROM TableA);
AccessでEXCEPTが使えなかったら、EXISTS述語で相関クエリに置き換える。
(SELECT 名前 FROM TableB EXCEPT SELECT 名前 FROM TableA) は
(SELECT 名前 FROM TableB WHERE NOT EXISTS (SELECT * FROM TableA WHERE TableA.名前=TableB.名前))
>>363 SELECT * FROM Table_A AS T1 WHERE dataC =(SELECT max(dataC) FROM Table_A WHERE dataA=T1.dataA);
その他いろいろ...
365 :
362 :2008/01/31(木) 23:52:29 ID:???
>>364 回答ありがとうございました!
これでできたのですが、実はテーブルは時がたつに連れて増えていくため、
教えていただいた方法で実行するのは(例えば一ヶ月分)かなり厳しいです…
そもそも私が望むことをSQLを使ってやろうとしているのが間違いでしょうか?
テーブルが増えていくってところが間違い。
367 :
364 :2008/02/01(金) 00:04:20 ID:???
>>365 なにが(例えば一ヶ月分)なのかよくわからないけど、
テーブル設計が間違っているっぽい。
まぁ、"目的"が複数の場合どれでもいいということなので、
SELECT 名前,max(目的) FROM (
SELECT * FROM TableA
UNION ALL
SELECT * FROM TableB
UNION ALL
....
) AS T1
GROUP BY 名前;
でいいかな。
368 :
NAME IS NULL :2008/02/03(日) 02:24:36 ID:JW+WwUKE
SELECT table1.* FROM table1, table2 WHERE table1.id = table2.id と SELECT * FROM table1 WHERE EXISTS (SELECT * FROM table2 WHERE table1.id = table2.id) とでは、一般にどちらが高速になりますか? DB は PostgreSQL 7 です。
PostgreSQL8.1.9使用中。 pg_dumpで拾い上げたデータをpgAdminIIIでリストアさせようとしても、 毎回応答無しになって死んでしまう。 ひとつだけ処理が怪しいテーブルがあって、それが原因だと思うんだけど、 特定のテーブルだけスキップさせたりとか出来る方法があったら教えてくれー。 ファイル直で弄れよ、という突っ込みがありそうなんだが、 dumpファイル10Gもあるんだor2
>>368 上のSQL、distinctつけないと結果が変わってしまう。
SELECT distinct table1.* FROM table1, table2
WHERE table1.id = table2.id
下のSQLも、副問い合わせ内の選択列が無駄。
SELECT * FROM table1
WHERE EXISTS (SELECT 1 FROM table2 WHERE table1.id = table2.id)
一般には以下の傾向がある。
・EXISTSのヒット率が低い ⇒ 内部結合の方が速い
・EXISTSのヒット率が高い ⇒ EXISTSの方が速い
大概のデータでは内部結合の方が速い。
また、Oracleの場合は
EXISTSのSQLを内部結合に書き換える
「副問い合わせのネスト解除」機能がある。
そのためどっちのSQLでも同じ性能が出る。
MySQLにはこの最適化機能はない。
PostgreSQLはしらない。
>>368 table2.idのインデックスがちゃんと機能してればEXISTSの方が速いだろう。
テーブルの大きさにもよるけどさ。
インデックスが効かないのならどう転んでも結合の方が速い。
>>369 スレチだな。
>>370 > 下のSQLも、副問い合わせ内の選択列が無駄。
オプティマイザ任せで、SELECT * で十分。
PostgreSQL 8.3RC2確認してみたんだけど、ほんの僅かだがSELECT * の方が速かった。
たしかOracleでもSELECT * にした方がいいって、どこかでみたなぁ。
oracle9iでレコードを更新したいのですが 表の構造が グループ(VARCHAR2) 開始日(DATE) 終了日(DATE) 削除フラグ(VARCHAR2) となっている場合で、 グループごとに開始日の昇順に並べたとして、終了日を同じグループの次のレコードの開始日の前日に 更新し、削除フラグが立っているなら、終了日をnull値にする。 また同じグループに次のレコードがなくてもnull値にする という処理をしようと思ったらどうすればいいでしょうか?頭ではわかるのですが それをSQLで実現しようと思うとできないのです。ご教授おねがいします
373 :
NAME IS NULL :2008/02/03(日) 15:38:06 ID:JW+WwUKE
テーブル table1 に update_date (更新日時) というフィールドがあって、 この日時が最近の順にレコードを取得したい。 SELECT * FROM table1 ORDER BY update_date DESC; しかし、update_date は NULL の場合もある。 NULL の場合は、ORDER BY で一番最後になるようにソートしたい。 でも上記の SQL では NULL が一番上になってなってしまう。 さて、どうしたらいいでしょうか?
374 :
NAME IS NULL :2008/02/03(日) 16:49:56 ID:P2xtVcgZ
where update_date is not null
375 :
NAME IS NULL :2008/02/04(月) 00:59:36 ID:YaEm3x7N
order by update_date desc null last
376 :
NAME IS NULL :2008/02/05(火) 20:37:19 ID:z0f3Z9+p
すいません質問があるんですけど・・・ 重複したデータを削除したいのですが記述の仕方がわかりません.. 条件が非常に縛られているので削除方法がわからないんです... このようなデータベース ↓ ○テーブル名:main1 ・カラム:id, name ○テーブル名:main2 ・カラム:id, info ○テーブル名:relation ・カラム:id, main1_id, main2_id, point 以上のような3つのデータベースを作りました. relationはmain1とmain2の関連テーブルになっています. ここで問題が起きたのですが,relationにはmain1とmain2のidを結びつけたインスタンスが 登録されています. なのでmain1とmain2のidの組み合わせが重複することはないのですが,なぜか 存在してしまいました. つまり,main1とmain2のidが等しいデータが違うidで存在しています. この重複部分を削除したいのですがわからないのでカキコしました. 消すデータは後ろのidの方のデータを消したいと思っています. このrelationのデータ数が非常に多いので,手動では時間がかかりすぎるのでSQLで解決したいんです! どなたか教えてくれませんか?? 一度,重複しているidをすべて1度selectしてからdeleteしても全然おkです.
複数の場所に同じ質問書き込むな
378 :
NAME IS NULL :2008/02/05(火) 22:58:42 ID:B/kVefGR
Oracle9iです。 KEY = IN (no1, no2, no3・・・)など、カッコ内が可変で、 数百個、もしくは数千個ある場合、IN句を使用しデータを 一度に取得するのではなく、PRO_KEY = no1のSELECT処理を発行、 PRO_KEY = no2のSELECT処理を発行・・・し、ARRAYに検索結果を 1つずつ詰めていく方が良いのでしょうか? くは数千個あるかもしれない場合、INとORではどちらが速いのでしょうか? INが速い場合、1000個までという制限があるので、KEY = no1・・・を 数千回発行した方がよいのでしょうか?
テーブルが非常に大きくて、かつ PRO_KEY にインデックスがあれば、 SELECT千回 < IN ≒ OR じゃない? まあ一概には言えんけど。 もしかしたら一時テーブル作ってJOINしたほうが速いかもしれんし。
SALESテーブルにある、このようなデータの格納状況から、 +---+---------------+----------+----+------------+ |UID |PRODUCT_NAME|UNIT_PRICE |QTY |TOTAL_PRICE| +---+---------------+----------+----+------------+ |001 |WindowsXP | 100| 5| 500| +---+---------------+----------+----+------------+ |002 |WindowsXP | 100| -2| -200| +---+---------------+----------+----+------------+ |003 |WindowsVista | 150| 1| 150| +---+---------------+----------+----+------------+ |004 |Linux | 50| 2| 100| +---+---------------+----------+----+------------+ 同じPRODUCT_NAMEのものについて、unit_priceとqtyを計算した結果を ここではWindowsXPについて、 +---------------+----------+----+------------+ |PRODUCT_NAME |UNIT_PRICE|QTY |TOTAL_PRICE| +---------------+----------+----+------------+ |WindowsXP | 100| 3| 300| +---------------+----------+----+------------+ |WindowsVista | 150| 1| 150| +---------------+----------+----+------------+ |Linux | 50| 2| 100| +---------------+----------+----+------------+ このような表で返すには、どのようにSQLを記述すればいいでしょうか?
>>380 UNIT_PRICEの金額を平均、最大値、最小値などどうもとめるかを決める。
あとはGROUP BYで教科書どおり。
382 :
380 :2008/02/07(木) 16:22:53 ID:???
>>381 ありがとうございます。申し訳ないことに、
見直していたら、条件に抜けがありました。。。
下記のように、同一のPRODUCT_NAMEのものについては
TOTAL_PRICE=UNIT_PRICE * QTY
の計算をしてまとめつつ、UIDはそのPRODUCT_NAMEグループ?の
中の最大値を求める、という場合にはどう考えればいいでしょう。。。
+---+---------------+----------+----+------------+
|UID |PRODUCT_NAME |UNIT_PRICE|QTY |TOTAL_PRICE|
+---+---------------+----------+----+------------+
|002 |WindowsXP | 100| 3| 300|
+---+---------------+----------+----+------------+
|003 |WindowsVista | 150| 1| 150|
+---+---------------+----------+----+------------+
|004 |Linux | 50| 2| 100|
+---+---------------+----------+----+------------+
383 :
380 :2008/02/07(木) 17:14:21 ID:???
解決しました。お騒がせしました。
384 :
NAME IS NULL :2008/02/07(木) 19:52:01 ID:fdkVCoKH
未知のウイルス
386 :
NAME IS NULL :2008/02/07(木) 20:43:52 ID:fdkVCoKH
どちらにしろ、そんな正体不明のzipなんぞ踏めるか。 手を抜かずに文章で書け。
388 :
NAME IS NULL :2008/02/07(木) 20:56:52 ID:fdkVCoKH
>>387 エクセルのファイルをインポートする問題なので
見てもらったほうが早いと思ったんですが
私は全くの無知なので、どこまで書けば回答できるようになるのかわからないんですが…
とりあえず書いてみますね
389 :
NAME IS NULL :2008/02/07(木) 21:07:50 ID:fdkVCoKH
あの、調子のいいお願いかもしれないんですが… できればお願いします…
ウィルスってか、個人情報入ってんじゃね?
392 :
389 :2008/02/07(木) 22:12:19 ID:fdkVCoKH
できれば今日明日中に回答をもらえると嬉しいです
>>389 ACCESSを起動して新規MDBの作成→ファイルからインポートで拡張子をEXCELにして例題のEXCELをインポート。
これで分からないならあきらめなさい
394 :
389 :2008/02/07(木) 23:38:38 ID:fdkVCoKH
>>393 それは分かってます
知りたいのは1と2の問題です
395 :
389 :2008/02/07(木) 23:39:31 ID:fdkVCoKH
396 :
389 :2008/02/07(木) 23:40:57 ID:fdkVCoKH
私自信アクセスのことは全くわからないんですけど 自分なりに調べてインポートして セレクト〜って書くのはわかりました でも分かったのはそれだけです
397 :
389 :2008/02/07(木) 23:41:28 ID:fdkVCoKH
問題1 社員の性別を調べる表示:社員番号、氏名、年齢、性別 問題2 「経理部」と「営業部」の社員を調べる表示:社員番号、氏名、部署名. これを出すにはどういったSQL文?を書けばいいのですか?
∩___∩ | ノ ヽ / ● ● | クマクマ | ( _●_) ミ 彡、 |∪| 、`\ / __ ヽノ /´> ) (___)f^f^f^f^f^f^f^f^f^┐ | |~ ~ ~ ~ ~ ~ ~ ~ ~ │ | | 知ってるが │ | / | お前の熊度が | | / | 気にクマない | ∪ |___________| \_)
399 :
ヒント :2008/02/07(木) 23:57:57 ID:???
| 何について調べますか? | ┌────────────┐ | | 問題1 社員の性別を調べる表示:社員番号、氏名、年齢、性別 | | 問題2 「経理部」と「営業部」の社員を調べる表示:社員番号、氏名、部署名. | | これを出すにはどういったSQL文?を書けばいいのですか? | └────────────┘ | [ オプション(O) ] [ 検索(S) ] | `──────────┐ ┌─── , '´l, ..| ./ , -─-'- 、i_ |/ __, '´ ヽ、 ',ー-- ● ヽ、 `"'ゝ、_ ', 〈`'ー;==ヽ、〈ー- 、 ! `ー´ ヽi`ヽ iノ ! / r'´、ヽ `´ヽノ
400 :
389 :2008/02/08(金) 00:14:23 ID:7P/NUdqG
401 :
389 :2008/02/08(金) 00:14:56 ID:7P/NUdqG
>>399 そんなことできたら便利すぎるwwwwwww
ここは質疑応答スレであって、 サポートセンターではない。 「安請け合いしたけどやっぱ無理だから、 おまいらオレの代わりにいつまでにやってくれ」 ってのはアホすぎw 時間的制約などがあって急ぐなら、 MSのサポートセンターなどに問い合わせるべき。 業務でMS-Access使ってるなら、当然サポートも使えるだろ。
多少出来るバイトでも雇えや。 それで充分片づくから。
|・|ここは質疑応答スレであって、サポートセンターではない。 |「安請け合いしたけどやっぱ無理だから、おまいらオレの代わりにいつまでにやってくれ」ってのはアホすぎw | |・時間的制約などがあって急ぐなら、MSのサポートセンターなどに問い合わせるべき。 ||業務でMS-Access使ってるなら、当然サポートも使えるだろ。 | `──────────┐ ┌─── , '´l, ..| ./ , -─-'- 、i_ |/ __, '´ ヽ、 ',ー-- ● ヽ、 `"'ゝ、_ ', 〈`'ー;==ヽ、〈ー- 、 ! `ー´ ヽi`ヽ iノ ! / r'´、ヽ `´ヽノ
405 :
NAME IS NULL :2008/02/08(金) 20:27:34 ID:9uM6oTD/
mysqlに関する質問ですが、 #mysql 〜とか#mysqladmin 〜とかうっても全部 mysql:unknown option '--ut mailing lists for MySQL discussion.' と返ってくる不思議な現象に出会いました。どなたかご教授お願いします。
406 :
NAME IS NULL :2008/02/08(金) 23:04:04 ID:9uM6oTD/
すいません。自己解決しました。 なぜか/etc/my.cnfのコメントの#が5行ほど抜けていました。
407 :
NAME IS NULL :2008/02/09(土) 00:47:33 ID:xrPHvNc0
a
408 :
NAME IS NULL :2008/02/09(土) 16:18:16 ID:aOhFc46s
ニュースのタイトルをLikeで検索するプログラムを書いています。 タイトルに「%」が含まれているレコードを検索するにはどうしたらよいでしょうか? title like '%%%' では全件が表示されてしまいます。 ちなみにDBはPostgreSQLを使ってます。 よろしくお願いいたします。
410 :
NAME IS NULL :2008/02/09(土) 16:37:54 ID:aOhFc46s
>> 409 title like '%\%%' ではだめでした。(結果同じ) 何でエスケープしたらよいのでしょうか。
>>410 PostgresはよくしらんからANSI SQLで答えるけど
LIKE '%\%%' ESCAPE '\'
412 :
NAME IS NULL :2008/02/09(土) 16:44:12 ID:aOhFc46s
>>411 回答ありがとうございます。
でも残念ながらダメでした。。。
413 :
NAME IS NULL :2008/02/09(土) 16:49:45 ID:aOhFc46s
'%\\%%'
どうやっていいのか分からないことがあるので教えてください。 1年1組、2年3組といった二つの整数を一組にして、主キーとして扱いたいのですがどのように すればよいのでしょうか? たとえば、文字列として「1-1」「2-3」とすれば良いと思うのですが、 これではソートする際にたとえば「11-1」「2-1」というデータで整列順がおかしくなってしまいます。 これを回避するには「0000-0000」といったフォーマットでデータを格納すればよいのですが、 これでは「9999-9999」以上のものを扱うことが出来ません。 それに文字列でやるというのも気持ちが悪いです。何か良い方法は無いでしょうか?
416 :
415 :2008/02/09(土) 19:53:06 ID:???
自己解決しました。 主キーって複数列に設定できるんですね。 スレ汚し失礼しました
CREATE TABLE 幼女名簿 ( 学校 STRING NOT NULL, 学年 INTEGER NOT NULL, クラス INTEGER NOT NULL, 出席番号 INTEGER NOT NULL, 名前 STRING NOT NULL, PRIMARY KEY(学校, 学年, クラス, 出席番号) ); こゆこと?
ちょwwwテーブル名おかしいってwwwwwwwww
YojoMebo
★質問(既出だったらごめんなさい) ある列に、半角文字が含まれているレコードを探し当てたいのですが、 以下のSQLで大丈夫でしょうか? ------------------------------------------ --前提条件:文字コードは「JA16SJIS」 SELECT * FROM TBL WHERE LENGTH(COL) <> LENGTHB(COL)/2 OR COL LIKE '%゙%' OR COL LIKE '%゚%' ; ------------------------------------------ どうぞよろしくです。
大丈夫・・・だと思うけど、テストデータを作って実験してみたら?
422 :
NAME IS NULL :2008/02/10(日) 17:36:59 ID:JZWkGzXi
SQL初心者です 二つのテーブルがあって、構成は以下の通りなんですが、 T商品(商品ID、商品名)、T価格変動(変動ID、商品ID、価格、更新日時) これら二つのテーブルをもとに 商品ID、商品名、各商品の最新の価格 というふうに表示したいのですが、 どのようなSQL文を書けばよいのでしょう? AccessのDMax関数を使った方法は調べられたのですが、 SQL文だとわからないです。 よろしくお願いします
T価格変動だけでちゃんとセレクトできれば、あと商品IDと商品名を結びつけるだけじゃないの??
select T商品.商品ID
select T商品.商品ID AS 商品ID,T商品.商品名 AS 商品名, max(T価格変動.価格) AS 最新価格 from T商品,T価格変動 where T商品.商品ID = T価格変動.商品ID group by T商品.商品ID,T商品.商品名 もしくは select T商品.商品ID AS 商品ID,T商品.商品名 AS 商品名, T価格変動.価格 AS 最新価格 from T商品,T価格変動 where T商品.商品ID = T価格変動.商品ID and T価格変動.価格 = (select max(価格) from T価格変動) でいけますでしょうか?
426 :
NAME IS NULL :2008/02/10(日) 20:31:31 ID:JZWkGzXi
すみません、説明不足かも 価格の変化するタイミングはすべて違うのと、 後になって商品ごとに価格変動の履歴を見たいので、こういう テーブル構成にしています。 質問したかったのは、たとえば 「100個ある商品群のうち、ある条件を満たす商品をセレクトして、 その商品の現時点での価格を横に表示したい」 ということです。 SELECT 商品ID,商品名,MAX(更新日時) FROM T価格変動 WHERE 商品ID.T価格変動=商品ID.T商品 GROUP BY 商品ID.T価格変動 でいいんですかね?ぜんぜんだめ?
427 :
NAME IS NULL :2008/02/10(日) 20:40:14 ID:JZWkGzXi
>>426 書き方もテーブル名とカラム名が逆になってしまってました。
AccessのクエリとDMaxやDLookupばかり使っていて、SQL勉強はじめた
ばかりです。すみません。
それじゃ肝心の価格を表示してないよ あとグループ関数使うときはそれ以外の列を すべてSelect句に入れないと構文エラー SELECT 商品ID,商品名,価格 FROM T価格変動,T商品 WHERE T価格変動.商品ID=T商品.商品ID AND ある条件? GROUP BY 商品ID,商品名,価格 HAVING 更新日時 >= ALL(select 更新日時 from T価格変動) じゃない?
>>428 を訂正
× あとグループ関数使うときはそれ以外の列を
すべてSelect句に入れないと構文エラー
○ あとグループ関数使うときは、その列以外でSelect句に挙げた列は
すべてGROUP BY句に入れないと構文エラー
でした
430 :
NAME IS NULL :2008/02/10(日) 21:26:39 ID:JZWkGzXi
>>428 HAVING 更新日時>=ALL(select 更新日時 from T価格変動) の部分は
その前のGROUP BY句があるので、それぞれの商品ごとの
価格変動の中で最新の更新日時のもの、ということに
なるんですね?
と、思います。。たぶん。 今考えてみたら、最新の更新日時を求めるのは HAVING句じゃなくてWHERE句でも指定可か。 ともあれ簡単なテーブルを実際に作って 10件程度のデータを入れて試してみてください。 ACCESSに入れてSQLで問い合わせするだけでもいいので。 たぶんいけるでしょう。 SELECT 商品ID,商品名,価格 FROM T価格変動,T商品 WHERE T価格変動.商品ID=T商品.商品ID AND 更新日時 >= ALL(select 更新日時 from T価格変動) AND ある条件? GROUP BY 商品ID,商品名,価格
432 :
NAME IS NULL :2008/02/10(日) 23:37:09 ID:JZWkGzXi
>>431 なるほど・・・
とても参考になりました
試してみます
ありがとうございました
433 :
NAME IS NULL :2008/02/11(月) 02:22:38 ID:SPfJ3PrH
MySQLのストアドプロシージャ内などで、列名を動的に設定する方法はありますか? 以下のように書くともちろんエラーになってしまいます。 SET @p = 10 ALTER TABLE `temp` CHANGE COLUMN `列` CONCAT("列", @p); #列「列」を「列10」に名前変更したい 何がしたいかというと、ちょっとした個人プロジェクトの仲間向けにモジュールの開発進行表を作るためです。 テーブル「モジュール」: モジュールID, モジュール名 テーブル「仕事の種類」: 仕事の種類ID, 仕事の名前 テーブル「タスク」: タスクID, 仕事の種類ID, モジュールID, タスクの担当者 という3つのテーブルがあって、テーブル「仕事の種類」には(1, "設計")(2, "コーディング") (3, "テスト") などが入ります。 (これらを固定にしてしまえば話は簡単なんですが、事情があって運用開始まで この項目がどうなるのか分からないのと、運用開始後にも変更が加わる可能性があります。) この条件下で、 モジュールID, 仕事1の担当者, 仕事2の担当者, 仕事3の担当者, … という列の出力を得たいのです。(担当者がいない場合はそのセルにはNULLが入る) そこでストアドプロシージャをつくり、 1、仕事の種類をすべて列挙する 2、一時テーブルを二個用意する 3、「モジュール」と仕事の種類ごとにテーブル「タスク」よりフィルタした結果を 一時テーブルに入れて次々にLEFT JOINする というふうにしようと考えました。 が、こうすると列「タスクの担当者」がダブってうまくいきません。 これ以外に、もっと上手な方法があればアドバイスしていただけると助かります。
434 :
NAME IS NULL :2008/02/11(月) 02:49:34 ID:eKNtLRaH
>>433 そういった表の加工はアプリケーション側で制御するものだと思う。
435 :
NAME IS NULL :2008/02/12(火) 16:03:59 ID:Yl3+Idbd
| birthday | name +----------+------ |1981-10-10| aaa |1979-05-09| bbb |1992-06-02| ccc という情報ありbirthdayの4月から9月生まれの人を 西暦に関係なく取得したい場合はどのように すればいいのでしょうか? DBはmysqlを使用しています
MONTH(birthday)っていう方法じゃダメかな?
437 :
NAME IS NULL :2008/02/12(火) 17:17:27 ID:IyGxDC8i
>>435 こんな感じじゃない?
SELECT * FROM table
WHERE ( 4 <= MONTH(birthday) AND MONTH(birthday) <= 9 )
438 :
NAME IS NULL :2008/02/12(火) 17:18:26 ID:IyGxDC8i
>>434 ありがとう。へんなことするのはやめてプログラム側で制御することにしたよ。
439 :
NAME IS NULL :2008/02/12(火) 18:25:39 ID:Yl3+Idbd
>>436-437 ありがとうございます
教えていただいたSQLで思ったとおりのことが出来ました
お、お前ら、IQ高そうだな…
だいたい190くらいです>IQ
フリーザ様は53万です
443 :
NAME IS NULL :2008/02/13(水) 20:04:15 ID:I4UapyfH
パフォーマンスについて教えてください。 例えばプライマリキーの設定がA,Bとなっていて、 そのうちBについてのみ抽出条件の指定が必要だった場合、 Aについてはすべてのデータが取得できるような条件の指定があった方がいいのでしょうか? DBはDB2です。バージョンは分かりませんが、古めだと思います。
Aも条件に加えるなんて全く意味無いと思うけど。 とりあえず、実行計画見ればいいじゃん。すぐ答えがでるよ。
445 :
NAME IS NULL :2008/02/13(水) 22:08:01 ID:I4UapyfH
>>444 やっぱり意味ないですかね?規約であるんです。
プライマリキーやインデックスキーは(例え意味がなくても)すべて順番通りに
指定しなければならないと。
実行計画ですか。勉強してみます。
そういう規約があってそういうindexしかないなら、Aを絞れないか 考えてみろってことだろ。 すべてのAに合致する条件なんて、他人に聞くまでもなく意味が ないことくらい分かれ。
447 :
NAME IS NULL :2008/02/13(水) 22:50:58 ID:USKASoPv
お願いします。 以下のようなテーブルがあります。 テーブル名:member_item member_id | item_id 1 | 1 1 | 2 1 | 3 2 | 1 2 | 3 2 | 4 3 | 4 4 | 1 4 | 2 item_id 1と2を持つ人を抜き出したいです。(この場合はmember_id 1と4) MySQL4.0.27です。 サブクエリが使えません。 よろしくお願いします。
>455 実行計画って別に勉強するほどのことじゃないよw ツールの機能かなんかでボタンひとつででないの? B列のみの条件で検索する要件があることをDB設計者が知らないか忘れてるだけでしょ、Bだけのインデックス張ってもらえばいいじゃん。 それだけの話だよ。
>>447 mysql> select a.member_id from member_item a, member_item b
where a.member_id = b.member_id and a.item_id = 1 and b.item_id = 2;
+-----------+
| member_id |
+-----------+
| 1 |
| 4 |
+-----------+
2 rows in set (0.00 sec)
450 :
NAME IS NULL :2008/02/14(木) 01:56:56 ID:FPmSI381
データ内に1か2のデータが書き込まれていて、 それを読み込んで、 1は> 2は>= の関係演算子を同じSQL内で使うとするとエラーがでるんですが このようなときはどのように記述すればよいか教えてください。 WHERE ZZZZZZ DECODE(AAAAA,'1',>,'2',>=) YYYYY
よくわからんが、こういうことか? where (AAAAA='1' and ZZZZZZ>YYYYY) or (AAAAA='2' and ZZZZZZ>=YYYYY)
RDBMSって通常、どれくらいのデータ数/テーブルを扱っていくものなんでしょう? うちの会社のシステムは売り上げ実績が100万件くらいを超えると、 参照系にしろ更新系にしろパフォーマンスがぐっと下がります。 たぶん横長テーブルを3つくらいjoinして 全列を構造体につっこんでいるのがまずいのじゃないかと思うんですが・・・。
通常どれくらいまで、と聞かれても返答に困るけど 100万件程度は間違いなく「通常」の範囲内に入るだろう。
ハードのスペックにもよるでしょ それに、 > たぶん横長テーブルを3つくらいjoinして > 全列を構造体につっこんでいるのがまずいのじゃないかと思うんですが・・・。 これはRDBMSの問題じゃない
455 :
NAME IS NULL :2008/02/16(土) 10:04:11 ID:ZAE8bFc6
DB:SQL SERVER 2005において、サーバーグループと新規サーバーを登録した 際に、オブジェクトエクスプローラに接続しようとすると、以下のような エラーが出て、接続できません。 「SQL Server 2005 に接続しているときときにこのエラーが発生した場合は、 SQL Server の既定の設定がリモート接続を許可しないようになっていること がエラーの原因である可能性があります。」 「SQL Server Browser」を”無効”→”自動”に変え、「DatabaseEngine」 のリモート接続を、”ローカル接続のみ”→”ローカル接続及びリモート接続” に変えましたが駄目です。 何か他に対処法はありますでしょうか?
スレ違い
コード 名前 001 A 001 A 001 A 002 A 002 A 003 B 003 B 003 B 003 B 003 B こういうデータで名前Aのようにコードが分かれているグループ だけを抽出したいです。名前Bのようにはコードと名前の グループ件数が同じものは選ばない。どう書けばいいでしょうか? 欲しい結果 コード 名前 001 A 001 A 001 A 002 A 002 A
458 :
457 :2008/02/16(土) 23:27:37 ID:???
失礼しました。ACCESS2000を使ってます。
select * from TableName A where exists ( select * from TableName B where A.名前 = B.名前 and A.コード <> B.コード )
460 :
457 :2008/02/16(土) 23:48:10 ID:???
>>459 おおお、これでできました。ありがとうございました。
461 :
447 :2008/02/17(日) 00:25:26 ID:MxRoVOZ3
大変おそくなりまして、申し訳ございません。
>>449 様ので見事に取得できました。
ありがとうございます。
WebProgの世界で初めて実運用でDBに接したプログラマ1年生ですが、 ストアドでもない普通のSQL文が300行〜1000行って常識なんでしょうか。 LEFT JOINだらけです。 ちなみに先輩に聞いたらそもそも設計がアレだから仕方ないとのことでした。 (アレが何かは詳しくは教えてもらえませんでした)
どんなクエリだよ。 俺はテーブルいろいろ結合しまくって10行くらいになったとこでメゲた。
600行までなら見たことある だいたいA4に印刷して1枚に収まらなくなってきたらなんかおかしい
465 :
NAME IS NULL :2008/02/18(月) 15:41:45 ID:p0thSFUk
メンバテーブル(members) member_id menber_name 1 a-san 2 b-san 3 c-san 得点テーブル(points) point_id member_id period points 1 1 1 20 2 1 2 40 3 1 3 70 4 2 1 10 5 2 2 20 6 2 3 30 7 3 1 80 8 3 2 50 この中から特定の期間における全てのメンバー名とポイントを取得したい(ポイントが無い場合も取得したいので左結合)のですが、 SELECT * FROM members LEFT JOIN points USING (menber_id) WHERE period = 3 とselectすると、period=3でデータがないCさんが取得できません。 データが無い場合はNULLでもいいので、Aさん〜Cさん+存在する場合はポイント、という形の出力を得るにはどうしたらいいですか
〜 OR period IS NULL でいいような気がする
467 :
NAME IS NULL :2008/02/18(月) 19:19:28 ID:p0thSFUk
>>466 ありがとうございます。
NULL値で条件を取るとインデックスが使われないという話を聞いたことがあるのですが、
大量のレコードに対して検索する場合に影響ないでしょうか?
JOINした結果に対してIS NULLが適用されるなら どのみちインデックスはないから問題はないだろう。 オプティマイザが変に気を利かせてWHERE句を先にやろうとしたら 問題あるかもしれん。 まあやってみにゃ分からん。
469 :
468 :2008/02/18(月) 20:14:46 ID:???
と、思ったけどIS NULLを先にやったら意味が変わっちゃうから前者だな。
470 :
462 :2008/02/18(月) 22:54:38 ID:???
>>463 ,464
ありがとうございます。そうですか、やっぱりちょっと大杉なんですね。
クエリとしてはよくある売り上げを店舗ごとにとかそんなのなんですが、
中身にはCASEごとで異なるテーブルから異なるフィールドを取得してくるような、
長大なSELECT CASE文やら、何かのカウント用の1 AS CountHogeやらが
たくさん入っていて結構混沌としています。
量を減らすには別途中間テーブルを作るか、
SQL Serverなのでビューを小分けに設けるかというのが定石なのでしょうか。
これから勉強してみたいと思います。ありがとうございました。
postgreSQLを使ってるんですが、 SQL文、あるいはpsqlのコマンドで、あるデータベース内にあるテーブルの一覧を取得するコマンドってありますか?
select tablename from pg_tables
473 :
471 :2008/02/19(火) 00:04:39 ID:???
Access2007を使っています。 社員マスタ(全社員の社員番号と氏名等)、 資格テーブル(社員番号と資格)、 所属テーブル(社員番号と所属)、 業務テーブル(社員番号と業務)があります。 これを全社員について一覧表示できるようにしたいのですが、 LEFT JOIN あるいは RIGHT JOIN のネストは出来ないのでしょうか? やってみたのですがエラーになってしまい・・・ すっきり書くにはどうしたら良いですか
>>474 です。
できたようです。
お騒がせしました。
476 :
NAME IS NULL :2008/02/19(火) 15:09:15 ID:V1WdCTqi
sum()のような合計ではなく、論理和したものを得ることはできますか?
477 :
NAME IS NULL :2008/02/19(火) 22:20:26 ID:6GCK1zbs
user nickname aaaa '' bbbb '' cccc '' dddd '' eeee '' という状況で最初にnicknameを設定した人は user aaaを割当て次の人はbbb・・・という風に 被らずに割り当てたいのですがどういうSQL文を発行すれば いいですか?mysql5です。
countとenumを駆使するとか case文でもいいけど
479 :
NAME IS NULL :2008/02/20(水) 18:37:03 ID:0cdARB7/
すいません、少し長くなるのですが、どなたか答えが解る方いらしたら解答をお願い致します。 ■前条件 #################################################################### create table t_product ( id serial not null primary key unique, name text not null, price integer not null ); create table t_customer ( id serial not null primary key unique, email text not null, password text not null ); create table t_order ( id serial not null primary key unique, customer_id_fk integer not null ); create table t_order detail ( id serial not null primary key unique, order_id_fk integer not null constraint orderdetail_order_id_constraint references t_order(id) product_id_fk integer not null constraint orderdetail_product_id_constriant number integer not null );
480 :
NAME IS NULL :2008/02/20(水) 18:43:47 ID:0cdARB7/
t_product:
+---+--------------------+-----------+
| id | name | price |
+---+--------------------+-----------+
| 1 | gPod Classic 160G | 42,800 |
| 2 | gPod nano 8GB | 22,800 |
| 3 | gPod Shuffle 1GB | 9,800 |
+---+--------------------+-----------+
t_customer:
+---+------------------+-----------+
| id | email | password |
+---+------------------+-----------+
| 1 |
[email protected] | okada_pw |
| 2 |
[email protected] | suzuki_pw |
| 3 |
[email protected] | tanaka_pw |
+---+------------------+-----------+
481 :
NAME IS NULL :2008/02/20(水) 18:44:18 ID:0cdARB7/
t_order: +---+------------------+ | id | customer_id_fk | +---+------------------+ | 1 | 1 | | 2 | 2 | +---+------------------+ t_orderdetail: +---+-----------+---------------+---------+ | id | order_id_fk | product_id_fk | number | +---+-----------+---------------+---------+ | 1 | 1 | 1 | 2 | | 2 | 2 | 1 | 1 | | 3 | 2 | 2 | 1 | | 4 | 2 | 3 | 3 | +---+-----------+---------------+---------+ ####################################################################
482 :
NAME IS NULL :2008/02/20(水) 18:47:25 ID:0cdARB7/
・問題1
上記の前条件から以下のSQL文を記述せよ。トランザクションは考慮しない。
(1)t_productに「gPod touch 16GB,4800円」を追加する。
(2)t_customerの「
[email protected] 」を削除する。
(3)gPod nano 8GB を22,800円から23,800円に更新する。
(4)t_customerの中で、メールアドレスが.comで終わるユーザ一覧を出力する。
483 :
NAME IS NULL :2008/02/20(水) 19:08:59 ID:0cdARB7/
・問題2 (1) t_customerのpassword列は、本来では(md5でハッシュをとるなど)何らかの変換をして保存する事が望ましい。その理由は何か? (2) t_orderのcustomer_id_fk列には、t_customerのid列に含まれる値をとる制約がかける必要がある。その制約を記述せよ。制約名は各自の自由とする。 (3) t_productのprice列と、t_orderdetailのnumber列には、ある制約があることが望ましい。それはどんな制約で、実際にcreate table ...の中に埋め込むとしたら、どんな記述になるか。それぞれの制約を記述せよ。
484 :
NAME IS NULL :2008/02/20(水) 19:12:50 ID:0cdARB7/
485 :
NAME IS NULL :2008/02/20(水) 19:18:44 ID:0cdARB7/
・問題4 t_customerにユーザを加える作業をPHPから加えるとき、 $stmt = $dbh->prepare("insert into t_custtomer (email,password) values(",$emai.",".$pass.")"); $stmt->execute(); この方法をAとする。方法Aよりも $stmt = $dbh->prepare("insert into t_customer (email,password) values(:EMAIL, :PASS)"); $stmt->bindParam(':EMAIL',$email); $stmt->bindParam(':PASS',$pass); $stmt->execute(); この方法をBとする。方法Bの方法が好ましい。 その理由をセキュリティの観点から説明せよ。 ここで、$dbhはPHPにおけるPDOのDBハンドル、$stmtはStatementオブジェクト、$email と$passはPHPのフォームでテキスト形式で渡されたE-Mailアドレスとパスワードとする。
486 :
NAME IS NULL :2008/02/20(水) 19:21:12 ID:0cdARB7/
長くてすいません、どなたか解答が解る方至らしたら是非お願い致します。m(_ _)m
宿題は自力でやれ
丸投げか・・・少しくらい自分で考えようよ
まあアレだ。 氏ねと言っておこうかw
490 :
NAME IS NULL :2008/02/20(水) 20:39:49 ID:0cdARB7/
すいません、解答が解る方がいないようなので他で質問します。 失礼致しました。
あははははw
492 :
NAME IS NULL :2008/02/21(木) 13:41:02 ID:iDr1OTgx
元のデータ ID DATA 001 ABC 002 AC 003 C 欲しい結果 ID A B C 001 ○ ○ ○ 002 ○ ○ 003 ○ このように文字列DATAの中に'A','B','C'があったら それぞれ該当する列に○を出力したいのですが どうしたらよいでしょうか?
宿題は自力でやれ
495 :
NAME IS NULL :2008/02/21(木) 19:14:14 ID:oQVe31id
ヒント:クロス集計クエリ
496 :
NAME IS NULL :2008/02/21(木) 21:07:47 ID:7djH4nfP
oracle9iです。 テーブル1とテーブル2があり、 テーブル1には列a、列b、列c、列d、列e テーブル2には列A、列B、列C、列D、列Eがあります。 テーブル1の列d、列eとテーブル2の列Dと列EはNOT NULLです。 テーブル1の列aとテーブル2の列A、 テーブル1の列bとテーブル2の列B、 テーブル1の列cとテーブル2の列Cが等しければ、 テーブル1の列dと列eをテーブル2の列Dと列Eで更新するというSQLを 作成したいのですが、うまく更新ができません。 (更新はできるのですが、NULLで更新されてしまう) 以下が私の考えたSQL文なのですが、何が悪いのか教えて頂けないでしょうか。 UPDATE テーブル1 SET (列d, 列e) = ( SELECT 列D, 列E FROM テーブル2 WHERE テーブル1.列a = テーブル2.列A AND テーブル1.列b = テーブル2.列B AND テーブル1.列c = テーブル2.列C )
>>497 「ゆとり」ってこういうのを言うのかね?
>>496 (列a、列b、列c)と等しい(列A、列B、列C)がない場合にNULLになるってこと?
だったら WHERE EXISTS (同じサブクエリ) をつければいいんでね?
499 :
NAME IS NULL :2008/02/21(木) 22:59:24 ID:7djH4nfP
498 回答ありがとうございます。 (列a、列b、列c)と等しい(列A、列B、列C)は必ず存在します。 それなのに、すべての行がNULLで更新されてしまいます。
501 :
NAME IS NULL :2008/02/21(木) 23:19:25 ID:7djH4nfP
>>500 サブクエリでtypoとは、どういうことでしょうか?
あまり知識がなくてすみません。
typo −名C(複〜s) 《口語》 誤植. typographic error の短縮形
503 :
NAME IS NULL :2008/02/22(金) 00:06:46 ID:hwdD2s1c
>>502 SELECT
列D, 列E
FROM
テーブル2
WHERE
テーブル2.列A = 'aa'
AND
テーブル2.列B = 'bb'
AND
テーブル2.列C = 'cc'
これだと、しっかりと期待どおりの結果が返るんですけど。。。
Oracleはさわってないけど、
>>496 のSQLそのものは間違っていないと思うよ。
なので、問題があるとすれば、例じゃなくて"本当"に実行しているサブクエリあたりだろうと言うこと。
SET (d,e)=(SELECT D,E ...)
な場合、サブクエリは1行だけ返さなくてはならないのだけど、本当に1行だけ返っているか?
0行ならNULLで、複数行ならエラーになると思うが、Oracleだとどうなのかな?
実は本当のSQLがsum(D),min(E)の様な集約関数になっていて結果がNULLになっていたり。
とまぁ、いろいろ考えられるので問題の切り分けをした方がよさそう。
>>503 どうせやるなら、
SELECT 列D,列E FROM テーブル2 JOIN テーブル1
ON テーブル2.列A = テーブル1.列a
...以下略
で確認してみてはどうか。
SQLの初歩的な質問です。 テーブルの項目に ・社員ID ・作業開始日 ・作業終了日 があり、そのテーブルから社員ごとの、最も新しい情報が格納されているレコードを 抽出したいのですが、どのようなSQL文になるのでしょうか。 社員ID 開始日 終了日 1 1/1 1/31 1 2/1 2/29 2 1/1 2/29 ↓抽出 社員ID 開始日 終了日 1 1/1 1/31 2 1/1 2/29
>最も新しい情報が格納されているレコード 日付のどれを見ていってるの? ほしい抽出結果が最も古い情報を取得してるように見えるけど
>>506 申し訳ない、ミスです。。。
抽出されるべきは
1 2/1 2/29
2 1/1 2/29
です。
>>505 同じ社員で同じ開始日が複数あったら欲しい結果はどうなるの?
509 :
NAME IS NULL :2008/02/22(金) 23:51:14 ID:FAMACLRa
相関サブクエリ
直感で書いたから間違ってたらすまそ ってかPL/SQLだがが… デバッグ環境もないД select MAX(社員ID) 社員ID , CASE WHEN MAX(開始日) > MAX(終了日) THEN MAX(開始日) ELSE '' END 開始日, CASE WHEN MAX(終了日) > MAX(開始日) THEN MAX(終了日) ELSE '' END 終了日 from テーブル名 group by 社員ID
↑のSQL軽率だな…よくみてなかった 開始日も終了日も年月日で、'2008/02/04' みたいになってるとして、 終了日の方が開始日より強い(開始日 = 終了日のデータの場合) っていう方針でいくと、 SELECT MAX(社員ID) , MAX(開始日) , MAX(終了日) from テーブル名 where CASE WHEN 終了日 >= 開始日 THEN 終了日 ELSE 開始日 END 更新日 IN (select CASE WHEN MAX(終了日) >= MAX(開始日) THEN MAX(終了日) ELSE MAX(開始日) END 最終更新日 from テーブル名 group by 社員ID ) group by 社員ID これでおk?
がんばれ。正解はこのスレの前のほうに書いてある。
アンケート集計と分析の為DBの勉強を始めました テーブルをどのような構造にすればスマートに処理できるか悩んでいます。 :アンケートの内容は「好きな料理をいくつでも上げて下さい」 :欲しい値は 「各料理の総得票数」と、そ「の料理を選んだ人が他にどんな料理を好むか」 :データ数は1000件程 :モニターの答える料理名の数は不定。 [没案1] 各料理にコードを振って16進数で収納し正規表現で取り出す→CPU負荷高で不可 table1 モニター毎のデータ |id(int)|cooknum(text)| |1|0003(たこ焼き カレー)| |2|000f(カレー たこ焼き シチュー 栗ご飯)| table2 料理コード |1|カレー| |2|たこ焼き| |4|シチュー| |8|栗ご飯|
続 [没案2]各料理ごとにフィールドを作る→フィールド数が増えすぎて不可 |id|カレー|たこ焼き|シチュー|栗ご飯| |1|1|1|null|null| |2|1|1|1|1| [没案3]料理一票毎にレコード→重複チェックが困難な為不可 |id|料理| |1|カレー| |1|たこ焼き| |2|カレー| etc [没案4]極端に多くの料理を上げるモニターがいた場合フィールド数が不足 |id|料理1|料理2|料理3|料理4| |1|カレー|たこ焼き|null|null| |2|カレー|たこ焼き|シチュー|栗ご飯|
>>514 >没案3
重複チェックはUNIQUE制約付けてDBにやらせればいいのでは?
ごく自然な設計は モニターテーブル(monitor_id, 氏名など) 料理テーブル(food_id, 料理名など) 回答テーブル(monitor_id, food_id) だろうな。
>没案1 ビット演算でできんの?
>>516 没案1〜4ってすごいな
普通考えつかんでしょこんなのw
自然に考えたら516になると思うけど
みんなありがとう、勉強になったよ。
>>516 を参考にして
モニターテーブル(monitor_id, 回答数)
料理テーブル(food_id, 料理名)
回答テーブル(monitor_id, food_id)
こんな感じでやってみる。
とりあえず「紙」のアンケートを1000件、csvに打ち込んでくるわ
520 :
NAME IS NULL :2008/02/26(火) 17:55:00 ID:jUEYC6cI
1万件CSV形式のIDがあり、50万件分のデータがはいった テーブルのkeyをCSV形式に含まれるでIDで引き出す場合 IN ()とUNION ALLとではどちらが良いのでしょうか? ちなみにkeyにはindexが張られています。 それともこういった場合別のもっと良いやり方があるのでしょうか?
>>520 テーブルを用意してCSVを流し込んでHASH JOINがいいと思う。
522 :
仕様書無しさん :2008/02/26(火) 23:07:37 ID:uVBIAVZU
SQL Server2005を使用しています。 ALTER TABLE でデフォルト値を設定したいときは ALTER TABLE テーブル名 ALTER 列名 SET DEFAULT デフォルト値 ; でよろしいでしょうか?
523 :
520 :2008/02/27(水) 08:47:50 ID:???
>>521 ありがとうございます
HASH JOINも検討してみます
>>522 回答待つよりヘルプみたほうがはやいと思われ
525 :
NAME IS NULL :2008/02/29(金) 11:53:19 ID:oX/QaCte
ひとつのODBCネームで必要に応じて接続先SQLServarを変更したいのですが 方法がわかりません VBAを使って変更したいと思っています。 どなたか教えていただけませんでしょうか
ここはSQLのスレで、SQLServerのスレじゃないよ。 実行時に切り替えるならデータを、そうでないならレジストリ直とか
527 :
NAME IS NULL :2008/03/02(日) 10:40:35 ID:1J2fGyJN
すみません質問です。 実行する度にテーブルfooのWHERE条件に該当するレコードのhoge列に 1加算するSQLを作りたいのですが、どう書けばよいか教えてください。 サブクエリで書いても同じテーブルは指定できないと怒られ出来ないようです。 環境はMySQL4.0.27です。
>>527 update foo set hoge=hoge+1 whre ほげほげ
じゃないの?
>>528 そんなシンプルだったとはっ・・・!
やってみたらできました。ありがとうございます。
530 :
ミミ :2008/03/03(月) 19:08:52 ID:oS8vdq4t
fruits テーブルがあります。 fruits.id : (主キー) fruits.name : 果物名 fruits.date : 入荷日 これを、入荷日が最近のものからソートして一覧表示したいのだけど、 同じ果物名はひとまとまりで一覧表示したい。 同じ果物名の中で一番最近の入荷日でソートしたい。 つまり、 みかん, 2008-02-18 みかん, 2008-03-02 りんご, 2008-03-03 りんご, 2008-03-01 りんご, 2008-02-15 をソートしたら りんご, 2008-03-03 りんご, 2008-03-01 みかん, 2008-02-18 みかん, 2008-03-02 りんご, 2008-02-15 になるようにしたい。 どうしたらいいかな?
531 :
ミミ :2008/03/03(月) 19:10:17 ID:oS8vdq4t
★ごめん、さっきの間違いね☆ fruits テーブルがあります。 fruits.id : (主キー) fruits.name : 果物名 fruits.date : 入荷日 これを、入荷日が最近のものからソートして一覧表示したいのだけど、 同じ果物名はひとまとまりで一覧表示したい。 同じ果物名の中で一番最近の入荷日でソートしたい。 つまり、 りんご, 2008-02-15 みかん, 2008-02-18 りんご, 2008-03-01 みかん, 2008-03-02 りんご, 2008-03-03 をソートしたら りんご, 2008-03-03 りんご, 2008-03-01 りんご, 2008-02-15 みかん, 2008-03-02 みかん, 2008-02-18 になるようにしたい。 どうしたらいいかな?
>>531 普通に
order by fruits.name,fruits.date desc
で良いジャマイカ。
533 :
ミミ :2008/03/03(月) 19:16:47 ID:oS8vdq4t
>>532 そうじゃなくて、りんごとみかんの比較は、
りんごの最近の出荷日である 2008-03-03 と
みかんの最近の出荷日である 2008-03-02 で比較したいの。
もちろん、各果物の中では、出荷日でソートしたい。
>>531 SELECT * FROM fruits AS T1 ORDER BY (SELECT max(date) FROM fruits WHERE name=T1.name) DESC,date DESC;
535 :
ミミ :2008/03/03(月) 19:44:03 ID:???
できた! (date→nyuka) select * from fruits, (SELECT name AS name2, MAX(nyuka) AS recent FROM fruits GROUP BY name) AS recent_table WHERE fruits.name = recent_table.name2 order by recent, name, nyuka;
536 :
ミミ :2008/03/03(月) 19:46:34 ID:???
>>534 あ!それいいね。
ORDER BY 句だけで全部できると、
(SQL を埋め込んだ PHP の) コードの分離ができていい。
537 :
534 :2008/03/03(月) 19:53:07 ID:???
>>536 データの内容(分布)やインデックスの張り方などで状況は変わるけど、
>>535 の方が速い場合が多いかも。
>>354 は相関クエリだからfruitsの行数分fruitsテーブルを走査してしまう。
538 :
NAME IS NULL :2008/03/06(木) 14:06:30 ID:8vCwTipO
SQLサーバを使用しています。 テーブルAとテーブルBから コード | 日付 | 項目名 −−−−−−−−−−−−−−−− 001 |2008/03/06|あああ 001 |2008/02/15|いいい 001 |2009/03/31|ううう 002 |2008/03/01|AAA 002 |2009/03/31|BBB 003 |2008/03/01|かかか という結合表(T1)を UNION を使用して作成しました。 この T1 からコードでグループ化し、日付の最も小さな値をもつ行のみを 抽出したいのです。 コード | 日付 | 項目名 −−−−−−−−−−−−−−−− 001 |2008/02/15|いいい 002 |2008/03/01|AAA 003 |2008/03/01|かかか このようにしたいのですが、GROUP BY でコードでグループ化し、 SELECT コード, MIN(日付), MIN(項目名) FROM T1 GROUP BY コード とすると コード | 日付 | 項目名 −−−−−−−−−−−−−−−− 001 |2008/02/15|あああ のように欲しい表ではなくなってしまいます。 どのようにSQLを記述すればいいでしょうか? よろしくお願いします。
それで取り出したコードと日付を使って(サブクエリにして) 取り出せばおk
バッチとかじゃなくて普通のアプリで発行されるSQLで、IN句に1万個くらい値を書くのってありですか? 今までそんなのやった事なかったんだけど、今の現場でそんなのをばんばん投げててちょっとびびってます。
そんな長い SQL 書けるのか?
>>541 どのDB使ってるか言ってなかったですね。DB は Oracle です。
で、OracleだとIN句には1000個までしか書けないので、1000個ずつのIN句をORでつなげてます。
A -------- MM07-1 MM07-10 MM07-11 MM07-2 となっているフィールドをソートして MM07-1 MM07-2 MM07-10 MM07-11 としたのですが、order by A としたのでは思うような結果が得られません。 上記の結果を得るにはどのようにしたらよいのでしょうか? 使用しているのはT-SQLです
× としたのですが ○ としたいのですが
>>544 6文字目以降をSUBSTRING命令などで切りだす。
切り出した文字列を数値型にCASTしてソート。
頻繁にこういう処理が必要なら最初から並び順のフィールドを準備しておく。
>>544 ハイフン以降の数値だけでいいのならそこだけ抜き出して整数に変換すりゃいい。
以下はハイフン前と後をそれぞれ正規表現で抜き出してハイフン後のみ数値変換してORDER BY
ORDER BY substring(a from '^[^-]+'),cast(substring(a from '[^-]+$') as int);
レスありがとうございます。 SQLで正規表現が使えるのは目からウロコだったのですが、 使用している環境がSQL Server2000なので残念ながら正規表現は 使用できないようです。これを先に言うべきでした。
>>542 INの中身をサブクエリにして、
内容を適当なテーブルに格納しておけ。
>>548 正規表現は使えなくても、文字(列)で分割するsplitやexplodeとかあったりしないのかな、
substring(a from 6 for 7) でもいけるわけだが、まぁAに入る規則次第かな。
phpmyadminはSQLを覚える必要がなく誰でも簡単にデータベースを構築できますね。 って本当ですか?
552 :
NAME IS NULL :2008/03/07(金) 18:59:04 ID:uMhc0dqS
特定のDBという訳ではないのですが、 テーブル内でレコードを特定するために、 連番を採番する場合に、DBのオートインクリメント機能を使うのがいいのか、 それとも、採番テーブルを作ってそこから最新の番号を取るのがいいのでしょうか? DBのオートインクリメント機能を使う方が楽だと思うのですが、 ずっと前に居たプロジェクトで採番テーブルを使っていたので、 何の為にそれを使う必要があるのか、お聞きしたいです。 宣しくお願いします。
削除時の歯抜けとかが気にならないなら、オートインクリメントで十分。 いろいろ処理をしたければ(ビジネスロジックを挟みたいとか)、採番 テーブル、って感じで使い分けてる。
554 :
NAME IS NULL :2008/03/07(金) 22:12:18 ID:uMhc0dqS
>>553 アドバイスありがとうございます。
> いろいろ処理をしたければ(ビジネスロジックを挟みたいとか)、採番
> テーブル、って感じで使い分けてる。
よく分かりました。確かにそうですね。
一つ思うのは、採番テーブルから番号を取得した際に、
その番号を元にビジネスロジックで処理が確定するまで、
採番テーブルをロックする必要があると思うのですが、
これって、もっとスマートな方法はないでしょうか?
リアルタイムで大量の処理を要求される場合に、
ビジネスのトランザクションが確定するまで採番テーブルがロックされてしまうと、
待ち行列が大量に発生する可能性が出てきますよね。歯抜け可とすればいいのでしょうけど。
だから採番テーブル自体スマートじゃない。
確定時に最新番号をふるのではダメなの? それならロックはほぼ一瞬で済む
他のスレでも出た話題だか日本人によって縁起の悪い数字(4とか9)とかは スキップする必要があったので採番テーブルが必要だった。 面倒だった。 いやまあ、状況によってはテストや運用が楽だったりするので どっちもどっちだと思うけど。
アクセスログなどの履歴データをテーブルに突っ込んで分析しています。 ただ、履歴データが溜まりに溜まり、3,000万件、4GBになっています。 分析の頻度は決して高くありませんが、必要に応じて解析につかいますので、 テーブルに残しておきたいと思います。 分割したいとは思っているのですが、同じ構造のテーブルを2006年度、 2007年度分とか分けるのって美しくないですよね? 集計する際にも、結合する手間がでますし。 このようなテーブルはどのように運用するべきなのでしょうか? DBはMYSQL5.0です。宜しくお願いします。
テーブル.フィールド:概要 member.name:参加者リストの名前 kirai.name:嫌いな人の名前 suki.name:好きな人の名前 というテーブル、フィールドを用意しています。 member.name から kirai.name に存在しない名前、もしくは kirai.name に存在していても suki.name に存在している名前 を取ってくるにはどんなSQLを書けばよいでしょうか? 数時間悩んでいるのですが、カッコカッコANDORとかしてたら 混乱してきました。 どなたかお願いします。 mysql5で使用予定です。
>>559 select name
from member
where
name in (select name from suki)
or
name not in (select name from kirai)
名前で好き嫌いを判断するのはよくないがな。
(後藤)真希は嫌いだが(堀北)真希は好きだ。
561 :
559 :2008/03/08(土) 18:09:59 ID:???
>>560 天才!!
本当にありがとうございます!!!
僕も、
同じく(掘北)真希大好きです!!!
562 :
559 :2008/03/08(土) 18:36:37 ID:???
すいません、、、 560を サブクエリなしでする方法ってありますか。。 ちょっとサブクエリが使えない事情がありまして。。。
>>562 select member.name
from member
left outer join
suki
on
member.name = suki.name
left outer join
kirai
on
member.name = kirai.name
where
suki.name is not null or kirain.name is null
>>558 その質問は自分で結論がでてるじゃん。
としかコメントできんが。
まあ、妥協案で過去年度分の情報はcsvにでも書き出して圧縮して保管し
テーブル上から削除、使うときに一時的に戻せば?くらいの事しか思いつかんが。
パーティションや圧縮はどう?MySQLでは出来なかったっけ?
パーティショニングは使いどころを選ぶからなぁ。 その判断が事前に出来ないんだったら、素直に設計するのが吉。 つか、4GBくらいだったらマシンスペックによっちゃあ メインメモリに収まってしまうだろ。
例えば 山田万太郎 と検索し 結果表示↓ _________ |名前|住所 |Age| | | |_________ と 名前に 山田万太郎と表示されますが、この山田万太郎にリンクを付けて 山田万太郎のプロフィールを表示させたいのですが、どのようにリンクを付ければいいのでしょうか? 説明ばんばん下手で申し訳ないです。
それってデータベースの問題か?切り分けができないなんてバカ?
idつければいいじゃん
"SELECT x,01,02,03,04,05,06,07,08,09,10,11,12,13 FROM map WHERE x BETWEEN 2 AND 14" このクエリでちゃんと取得してくれないんですが どこかおかしいのでしょうか。。
そのクエリでどういう結果が得られて、本当はどんな結果がお望み?
えーと xに2~14がある行で、01~13の列の部分だけ表示したいのですけど 分かりますかね・・・。。
すいません答えになってなかったorz
phpでMySQLを使ってるんですが
SELECTの部分を指定しているからか、何故かMySQLのフィールドの値を返さずに
添字配列の数字の1~13を返してきます。
SELECTを*に置き換えたら、フィールドの値が正常に返ってきたんですけども。
本当は
>>574 のようにしたいのですが。
単純な勉強不足でしょうか。
'01', '02', のように ' ' で囲む必要があるんじゃないか? カラム名じゃなくて式だと思われてるんだと思う
試してみましたが改善しませんでした。。 うーん。。
01、02、・・・がカラム名なの? だったらダブルクォートか、MySQLならバッククォートで括るんじゃない? てか念のためdescribe mapの結果を貼ってもらったほうがいいかも。
"SELECT [x],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12],[13] FROM map WHERE [x] BETWEEN 2 AND 14"
580 :
NAME IS NULL :2008/03/10(月) 19:56:16 ID:AZYyHfNJ
SELECTの質問です MySQL 4.1.15 フィールド名: ID name age job date mail ID以外を指定したいとき、 SELECT name, age, job, date, mail from … ではない方法で、全体からIDだけを除いた指定の仕方ってあるのでしょうか イメージで言えば↓みたいな感じでシンプルにできないのでしょうか SELECT * - ID from …
>>580 ないだろ。
テーブルのカラム一覧から SQL を組み立てるパーサでも
書けよ。
>イメージで言えば↓みたいな感じでシンプルにできないのでしょうか >SELECT * - ID from … 時々でてくるネタなんだが、こういう発想するヤツは後でテーブルが変更になったときに どうやって対処するのか聞いてみたいな。
583 :
580 :2008/03/11(火) 09:10:36 ID:???
レス、サンクスです やっぱ、ないっすか 確かにテーブル変更時は面倒ですね
>>575 です
SELECTのカラム名をバックウォートで囲ってみたところちゃんと通りました。
皆さんご教授ありがとうございました。
585 :
NAME IS NULL :2008/03/11(火) 18:03:15 ID:IX6430zP
select count(id) as id from test_tbl; 上記のようにただカウントをするSQLを書いたのですが テーブルには3404800件データがあり結果出るまでに 56149.726 msかかります (idはプライマリーキーです) order by desc でひっくりかえして最終idを取得して MAX値とするのも考えましたが、データには論理削除されている 物も含まれており、正しい数字にはなってくれません こういった場合はどのようにすれば良いのでしょうか?
>>585 DBMSは何?
プライマリキーであっても自動的にはインデックスが張られないDBMSなのかもしれん。
インデックスがあってもOracleで言うanalyzeをしないと使われないDBMSなのかもしれん。
インデックスがあってかつ使っているけど遅いんなら単にスペック不足かもしれん。
EXPLAINしてみ
588 :
585 :2008/03/11(火) 19:27:10 ID:IX6430zP
>>586 DBMSはpostgresです
バージョンは8.0.13です
>>587 EXPLAIN ANALYZE した結果のトータルタイムが
Total runtime: 56149.726 ms
でした
589 :
585 :2008/03/11(火) 19:35:39 ID:IX6430zP
別のところで以下のような発言を見つけましたので 一度それを試してみようと思います (現在まではVACUUM ANALYZEまでしかやっていません) ありがとうございました >1週間に一度ほどの間隔で、レコードが全てが入れ替わるので >CronでVACUUMを走らせていましたがVACUUM FULLすると >見違える程高速になりました。
SQLSEVER2005使用してます。 文字列の20080312を2008/03/12に変換したいのですが、 select convert(datetime,誕生日,111) だと、結果が 2008-03-12 00:00:00.000 になるので select CONVERT(CHAR,convert(datetime,誕生日),111) にしてます Oracleだと簡単にできるのに、SQLSEVERはconvertを2回しないと駄目ですか? TO_DATE(誕生日, 'YYYY/MON/DD')
591 :
NAME IS NULL :2008/03/12(水) 20:17:29 ID:2ioX00Cq
Oracle8です。 「い」「ろ」「は」という列があります。 列単独ではユニークではありません。 3列をあわせるとユニークになります。 抽出したい対象は「い」列のある項目です。 「い」列だけでは1つに特定できないので、 「ろ」列の昇順、「は」列の降順で優先度を設けてその優先度の高い行を抽出対象とします。 このようなSQLを書きたいのですがどのように書けばよいのでしょうか?
>>591 where い = value
order by ろ, は desc
で上から取るしかないんじゃない?
「い」列がある値で、かつ、 「い」列の値が一致して「ろ」列の値がそれより大きい行が存在しなくて、かつ、 「い」列と「ろ」列の値がそれぞれ一致して「は」列の値がそれより小さい行が存在しない 行。
594 :
NAME IS NULL :2008/03/12(水) 20:40:09 ID:2ioX00Cq BE:256738098-2BP(2831)
>>592 肝心な部分を書き忘れましたが、
抽出される行を対象行だけ(1行)にしたいのです。
595 :
NAME IS NULL :2008/03/12(水) 20:42:15 ID:2ioX00Cq BE:96277739-2BP(2831)
>>595 Oracle専用の手抜き。
select * from (select * from TableName where い = SomeValue order by ろ, は desc) where rownum = 1;
top とか limit とか、いろいろあんだろ。
598 :
NAME IS NULL :2008/03/12(水) 21:41:45 ID:KqWYWQmi
ACCESS 2003です。 テーブルAとテーブルBがあり1:nの関係です。 フィールドhogeが両テーブルのキーになっています。 但しテーブルBのキー値はテーブルAにない可能性があります。 このときテーブルAにないキー値をテーブルBから削除するSQLを教えてください。 (テーブルBに同一キーが一つしかない場合はすぐ思いつきますが、 複数ある場合、スマートな方法が思い浮かびません。)
599 :
NAME IS NULL :2008/03/12(水) 21:54:51 ID:2ioX00Cq BE:53487735-2BP(2871)
>>596 面倒なんですが副問合せでお願いします。
>>598 delete from B where hoge not in (select hoge from A)
>>599 ,600
ありがとうございました。
試してみました。
・・・がそこそこスペックのいいPC(CPU2.4GHz MEM2G)で実行しているのですが
めちゃくちゃ処理が重いです。
(テーブルAが5万レコード テーブルBが24万レコード程)
処理速度重視で見た場合、代替SQL文はありますでしょうか?
>>601 どんくらい時間かかるん? インデックスが壊れてるとかじゃないよね?
実行してから10分くらいしてますけど まだプログレスバーの半分くらいです・・・ テーブルBにはインデックス設定してなかったような。。
>>603 インデックスがないのにキー? インデックスつけてやり直してみ。
605 :
601 :2008/03/12(水) 22:41:08 ID:???
>>604 すみません、DBのことまだよくわかってないです。
テーブルAのhogeについては主キーに設定、インデックスあり(重複なし)
テーブルBについてはインデックスあり(重複あり)に設定しました。
上記設定で
delete from B where hoge not in (select hoge from A);
しましたが、重いです・・・
delete from B where not exists (select * from A where A.hoge = B.hoge) のほうが速いんじゃない?
607 :
601 :2008/03/12(水) 22:51:49 ID:???
>>606 うおー、めちゃくちゃ早いです、感動です。
ありがとうございました!
具体的なテーブル構造と抽出条件を書かないのに 答えをSQLで要求するのってどうなんだ
SQLite3で以下のようなテーブルになっています。 itm ( id TEXT NOT NULL, tid INTEGER NOT NULL, PRIMARY KEY (id, tid) ); id, tid ------ de31, 001 de31, 002 6884, 001 5e96, 002 7f72, 001 7f72, 003 このテーブルから、tidが001と002の両方を持つid(この場合はde31)を取得するのは どうすればいいんでしょうか…?
>>610 > PRIMARY KEY (id, tid)
なので
SELECT id FROM itm WHERE tid in(1,2) GROUP BY id HAVING count(id)=2;
>611 ありがとうございます。 SQLもしっかり勉強しよう…
in じゃなくて and の方が良いと思われるが。
614 :
NAME IS NULL :2008/03/15(土) 08:37:32 ID:vdIcUnbN
>>614 その辺は方言が多いから対象のデータベースをしぼって探したほうがいいと思う。
でOracleでいいの?
POSTGRESQLを使ってるのですが、列を50個丁度表示させたいのですが numberというauto_incrimentなprimary keyがあったとします。 それの0〜50をクエリーすると削除された列はクエリーされず45個など中途半端に表示されてしまいます。 データの列一番上から数えて50列目まで指定してクエリーするSQL文ってありますか?
>>616 列じゃなくて行のことを言ってるんだと思うけど、
Postgresだったらlimitが使えるだろう。
>617 助言ありがとうございます。limitについてGoogle先生に聞いてみます。
619 :
614 :2008/03/16(日) 12:37:17 ID:???
>614 失礼しました。 間違っていると思っていたサイトですが正解でした。 ごめんなさい
どうか教えてください。SQLServer2005Stdです。 下記のようなTableAとTableBがあります。 TableBの4番目のレコード(104 , 3 , aaa)から見て、 ・TableBのD列が同じ ・TableAのB列がTableBの4番目のレコードからみて一番近い過去 の条件でTableBのC列の値を取得したいのですが、一番簡潔なSQL文を教えてくださいませ。 この例だと、101が期待する結果です。 TableA A(int) , B(datetime) ---------------- 1 , 08/03/10 2 , 08/03/11 3 , 08/03/12 4 , 08/03/13 5 , 08/03/14 TableB C(int) , A(int) , D(varchar(3)) ------------------------------ 101 , 2 , aaa 102 , 4 , bbb 103 , 1 , aaa 104 , 3 , aaa 105 , 5 , bbb
>>620 select b2.C
from TableB b1
join TableB b2
on b1.D=b2.D
where b1.C=104
and b1.A=3
and b1.D='aaa'
and b2.A=(
select a.A
from TableA a
where a.A=b2.A
and a.B=(
select max(a2.B)
from TableA a2
where a2.A=a.A
)
)
テンプレのリンク先であるSQL-techscore-の3−4「データ値の制約」の実習課題なのですが、 解答通りに打っても、フィールド定義の構文エラー、と出てしまいます。 スペル間違いもうち忘れもないかと思います。どうやらcheck句で引っかかっているようなのですが、 なぜでしょうか?
何を以ってcheck制約を怪しんでいるのか、 その判断材料となるエラーメッセージを 教えてほしいです あと、DBMSは何ですか?
624 :
620 :2008/03/17(月) 23:28:08 ID:???
Access2007とmySQLを使ったフリーソフトの二つで試しました。 列名とデータ値のみを記入した表なら問題なく作れました。 そこからprimary key, not null,...と順に試して作っていくと check句を記入した時のみエラーが出ます。
単に check 句に対応してないとか、方言で書き方が違うとか、 そんなんじゃねーの?
エラーメッセージは 「ステートメントの構文エラー」(エラー3290) ・予約語または引数名のつづりに誤りがあるか不足している ・区切り記号に誤りがある の二つです
手元にあるOracle9iとOracle10g ExpressEditionでは、 どちらも回答をそのままコピペしたら成功しましたよ。 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ SQL> ed file afiedt.bufが書き込まれました。 1 CREATE TABLE employee 2 ( 3 e_num CHAR(4) PRIMARY KEY , 4 e_name VARCHAR(40) NOT NULL , 5 year INTEGER CHECK(year >= 1970) , 6 gender CHAR(1) CHECK(gender = '0' OR gender = '1') , 7 office CHAR(2) 8* ) SQL> / 表が作成されました。
ID列、A列、B列のテーブルがあって、 ID=1の行のうち、値がNULLの列に“0”に更新するってことは可能ですか? ループ処理使わないと無理ですか?
2回UPDATE発行するだけじゃないの?
実際の列は100以上あるので簡単にできないかなと・・
>>629 UPDATE Table SET A=CASE WHEN A IS NULL THEN 0 ELSE A END, SET B=CASE WHEN B IS NULL THEN 0 ELSE B END WHERE ID=1;
634 :
NAME IS NULL :2008/03/19(水) 19:52:21 ID:vKyZWKXy
素直にテキストエディタの置換で作れば
何ここ、レベル低ww
636 :
NAME IS NULL :2008/03/19(水) 23:25:52 ID:cnxNmH+f
ハイレベル回答者あらわる
isnull使ったselectとjoinさせてupdateすればいいんじゃないの?
つかSET A = NVL(A,0)… でいいんじゃないの。
処理系が明記されていないのに 処理系依存の回答をするのはどうかと思うが。
それは明記しない方が間抜けな話。そこまで回答者が推理しなければいけないのかえ?
めんどくせーな。 ISNULLなりIFNULLなり置き換えて読めばいいだろ。 そもそも何使ってるか書かない側が悪いんだし。
ひんとひょうじゅんえすきゅーえる
もういいよ。 馬鹿は喋るな。
644 :
632 :2008/03/20(木) 01:25:21 ID:???
あ、COALESCE(A,0)で良かったんだな。 今頃気づいたつーか、思い出したよ(´・ω・`) 100行っても、わざわざExcelとか持ち出さなくても、 ホスト言語側でループしてSET句を書き連ねればいいだけじゃね。
みなさんはFKをつけるメリット、デメリットは何だと思いますか? またFKを使用していますか? 宜しくお願いします。
デメリット:パフォーマンスに悪影響、テストがやりづらい メリット:せっかくだから 自分は付けない。 付けてるの見かけることもあんまり無い。
外部キーをつける場合は逆向きの索引の扱いが最大の課題。 FOREIGN KEY A_ID REFERENCES TABLE_A(ID)でA_IDに索引をつけるかどうかは ケースによるのだが結構悩む。
どういうことですか?
649 :
NAME IS NULL :2008/03/20(木) 19:33:55 ID:J4BXwI7W
連鎖制約で別途消す手間を省くために(私的に使ってるもんだけど)
>>648 外部キーをもつテーブルにデータを追加するか外部キーの内容を変更しようとすると、
リファレンス先(TABLE_A)で存在チェックをする。
リファレンス先は当然主キーかそれに準じるキーなのでチェックには索引が使われる。
一方TABLE_Aのレコードを削除またはキーの内容を変更しようとすると、
外部のテーブルから参照がないことを確認するために、
外部キーを持つテーブルをサーチすることになるが、
このフィールドに索引がない場合はデータレコードの全件サーチとなる。
索引があるばあいは索引でのチェックになるので高速ではあるが、
カーディナルが低い索引が作られることになるためこれによる同時実行性の低下が問題になる。
丁寧にどうも。
Jetの*.mdbのデータをORACLEに入れたいのですが、何かのアプリをインストールせずに それをすることはできませんか?
それはこのスレ向きなのか
ACCESSのクエリテーブルを使用してSQLを生成させます。 この時生成されたSQLをコピーして、C#などの言語からADO.NETを 通してSQLを実行すると、ACCESS上での結果と違うのですが、 どのような原因が考えられるでしょうか? (あいまい検索の*は変換してます) 対象はmdbです 具体的には以下のようなSQLです SELECT TBL_A.箇所, TBL_A.番号, TBL_A.品名, Count(TBL_A.番号) AS DataCount FROM (TBL_B INNER JOIN TBL_A ON TBL_B.受付 = TBL_A.受付) INNER JOIN TBL_C ON TBL_B.品目 = TBL_C.品目 WHERE (((TBL_C.形名) Like "hoge%") AND ((TBL_A.箇所)="fuga") AND ((TBL_A.箇所)<>"A")) GROUP BY TBL_A.箇所, TBL_A.番号, TBL_A.品名 ORDER BY Count(TBL_A.番号) DESC; 抽出されるレコード数、集計される値も違います
)の数足りなくね?
とりあえず、これをaccessとC#で実行してみて SELECT A.箇所, A.番号, A.品名, Count(A.番号) AS DataCount FROM TBL_A A, TBL_B B, TBL_C C WHERE C.形名 Like "hoge%" AND B.品目 = C.品目 AND A.受付 = B.受付 AND A.箇所 = "fuga" AND A.箇所 <> "A" GROUP BY A.箇所, A.番号, A.品名 ORDER BY Count(A.番号) DESC;
nullの扱いとか暗黙の変換が違うのかもしれんね
その外部キーって、明示的に設定できるの? 他テーブル参照するキーとして、つまり外部キーとして 使ってはいますが、特に設定したことないのですが
出来るよ。 詳しくはforeign keyで検索
勉強になりました。 でも上に書かれてますが、場合によってはパフォーマンス悪くなるんですね
662 :
NAME IS NULL :2008/03/23(日) 00:31:54 ID:iZ/v0z4F
IN句を使用して15万レコードのテーブルのうち任意の10万行を選択しようとしたところ SQL発行時にエラーとなります。IN句は900個ずつに区切って10行を指定しています。 テーブルにフラグ等を設定することはでません。 SQLを正常に実行できる方法はないでしょうか。 環境 Oracle10g
SQL文の長さに64KBだかの制限があったはず
INはなるべく使うな
多分エラーなくなってもパフォーマンス悪すぐると思うがw
処理時間が長すぎてエラー起こしてるんじゃ? まともなSQLに直せばOK
668 :
NAME IS NULL :2008/03/28(金) 20:54:29 ID:3+8kTwhZ
ta ( id integer, data text ); tb ( id integer, ta_id integer, data text, update_at timestamp, ); のような感じで、以下のような結合を行ってta,tbのdataを取得したいと思います。ta → tb は1対多です。 SELECT ta.data, tb.data FROM ta LEFT JOIN tb ON ta.id=tb.ta_id; このとき、tbの最新のデータ(update_at DESC)1件を取得したいと思います。 どのようなSQLを書けばよいのでしょうか?
>>668 max(update_at)じゃダメなの?
670 :
668 :2008/03/28(金) 21:36:52 ID:3+8kTwhZ
>>669 具体的にはどう書くのでしょうか?
SQL詳しくないので、max(update_at)を使う場面というのが、
update_atの最大値を表示したい場合しか思いつきません…。
671 :
668 :2008/03/28(金) 21:44:51 ID:3+8kTwhZ
説明が悪いかもしれないので補足すると SELECT * FROM ta; の結果に SELECT * FROM tb ORDER BY update_at DESC LIMIT 1; の結果をta.id=tb.ta_idでJOINする感じです。
ROW_NUMBERが使えるならそれがいちばんスッキリする。 具体的な書き方は「詳しくないので」とか言わずに調べろ
select ta.data, tb.data from ta left join tb on ta.id = tb.ta_id where tb.updated_at = (select max(updated_at) from tb)
675 :
念のため :2008/03/29(土) 13:32:58 ID:???
limit 1
676 :
668 :2008/03/31(月) 13:30:03 ID:???
SQLServerで 2を0002と出力させるに便利な関数ってありませんでしょうか? ご存知の方いましたらお願いします。 oracleで LPAD(数値,桁数,左側に埋めたい文字) LPAD(2,4,'0') や VBでいうFORMAT(数値,'0000')みたいな感じです。
>>677 そのものの関数はないと思うから以下で
declare @a int
set @a = 2
select right('0000'+cast(@a as varchar),4)
ベンダ製品ではなく SQL99 と考えてください。 某書で、SQLの基本的な説明として ----------↓抜粋 成績([k]クラス番号、[k]出席番号、氏名、点数) SELECT クラス番号, SUM(点数) FROM 成績 GROUP BY クラス番号 ORDER BY 2 ORDER BY 句には集合関数を指定できないという制約がある。 したがって、ORDER BY SUM(点数) DESC という記述はできないため、 代わりに列番号を指定する。 ----------↑抜粋 とあるのですが、次のようなSQLは問題なく通りました。 (ただし oracle xe で、ですが) SELECT SUM(SAL) FROM EMP GROUP BY DEPTNO ORDER BY SUM(SAL) 本の内容と矛盾するように思えます。 二つのSQLは別物で自分の勘違いでしょうか?
>>679 SQL99という規格上ORDER BY句に集約関数は書けられないとなっているのかどうか知らないけど、
もしそうなっているのであれば、上は規格上の話で、下はOracleの拡張ってことでいいんじゃね。
にしても、これを「制約」と云うには語弊があるような気がする。
本来SQLの処理手順からすると、ORDER BY句に集約関数を書くことは出来ない。
しかし、手元にあるPostgreSQL8.0で試すと、
SELECT クラス番号 FROM 成績 GROUP BY クラス番号 ORDER BY SUM(点数);
なんてSQLも通ったりする。内部的にはオプチマイザあたりが
SELECT クラス番号,SUM(点数) AS 合計 FROM 成績 GROUP BY クラス番号 ORDER BY 合計;
って書き換えて実行しているんだろうな。さすがに
SELECT クラス番号 AS CN,.... FROM 成績 WHERE CN=1;
は通らないけどねw。
内部結合をする時にINNER JOINを使うかWHERE句でするか、どちらが良いでしょうか? FROM句は結合条件、WHERE句は抽出条件を書く場所なのでINNER JOINが正しいあり方なんでしょうか?
682 :
679 :2008/04/04(金) 00:35:50 ID:???
ありがとう 思いついて試したところ、oracle xe 環境で SELECT SUM(SAL) FROM EMP GROUP BY DEPTNO ORDER BY AVG(SAL) これすらも通りました。 ORDER BY は取得列以外もいろいろ対象にできる という基本は私が勉強したoracle以外でも当てはまると予想していますが・・・ とここで次に思いついたのが、 もしかしたら本当に言いたかったのは GROUP BY 句がないのに ORDER BY で集計関数を使うことはできない ではないかと。(これは言うまでもなく正しい) でも GROUP BY の内容に沿って指定していれば通ると。 それを執筆者がどこかで間違ってしまったと。 ?
>>681 速度の差はないと思うけど、認識としてはそれでいいんじゃね。
>>682 > それを執筆者がどこかで間違ってしまったと。
ぃゃぃゃ、SQL99という規格とベンダー実装の差だろ。SQL99でどうなったか知らないが、本来SQLでは
「ORDER BY句はSELECT文の一部じゃなくてCURSORの一部」 By セルコ
つまり集約関数どころか、
SELECT 氏名 FROM 成績 ORDER BY 点数 ;
もダメ。SELECTリストに無いものはORDER BY句では使えようがないのが規格上の仕様。
>>682 > とここで次に思いついたのが、
> もしかしたら本当に言いたかったのは
> GROUP BY 句がないのに ORDER BY で集計関数を使うことはできない
> ではないかと。(これは言うまでもなく正しい)
Oracleなら、
GROUP BY がなくても、ORDER BY で集計関数を使うことはできる。
GROUP BY がない場合に集計関数を使うと1行しか返さないので意味はないが。
SELECT SUM(SAL)
FROM EMP
ORDER BY AVG(SAL)
685 :
677 :2008/04/04(金) 10:20:45 ID:???
>>678 返事が遅くなってしまいましたが
助かりました。ありがとうございました。
namae, shime ------- A, 25日・・・(2/26〜3/25) B, 15日・・・(2/16〜3/15) C, 月末・・・(3/01〜3/31) D, 月末 というようなテーブルと namae, date, shouhin ------- A, 2008/03/10, 商品A A, 2008/03/26, 商品B B, 2008/03/10, 商品C B, 2008/03/26, 商品D C, 2008/03/31, 商品E D, 2008/03/26, 商品F D, 2008/04/01, 商品G というようなテーブルがあって、 3月分で抽出すると namae, date, shouhin ------- A, 2008/03/10, 商品A B, 2008/03/10, 商品C C, 2008/03/31, 商品E D, 2008/03/10, 商品F というようなのを取得するにはどうすればいいのでしょうか。 お願いします。
int、unsigned、NOT NULL、auto_incrementといった用語が解説されているサイトはないでしょうか?
688 :
NAME IS NULL :2008/04/04(金) 22:07:14 ID:uQGlKR8g
SELECT文で条件に合うレコードが1つみつけられたら終了するような方法は無いでしょうか
SELECT TOP 1 項目 ・・・
690 :
NAME IS NULL :2008/04/04(金) 22:12:01 ID:uQGlKR8g
>>686 namae, shime
-------
A, 25日・・・(2/26〜3/25)
このテーブルには2カラムしかなくて、
1個目のカラムには「A」
2個目のカラムには「25日・・・(2/26〜3/25)」
が入ってるって事?
このスレで質問するのが適切がどうかわからないのですが、 名前 住所 山田 東京都世田谷区 山田 東京都千代田区 山田 神奈川県横浜市 鈴木 東京都北区 鈴木 東京都葛飾区 というデータがあったとして、 名前 住所 山田 東京都世田谷区、千代田区、神奈川県横浜市 鈴木 東京都北区、葛飾区 上のような出力(もしくは近い形)を得る方法はあるでしょうか?
名前を元にくっつけた住所を取得するファンクションをあらかじめつくっておいて select 名前 ,fnc_xxx(名前) from テーブル group by 名前 みたいに書けば取れる
694 :
692 :2008/04/05(土) 11:50:48 ID:???
レスありがとうございます > 名前を元にくっつけた住所を取得するファンクションをあらかじめつくっておいて これは、 山田 東京都世田谷区東京都千代田区神奈川県横浜市 鈴木 東京都北区東京都葛飾区 というものをあらかじめ作るということでしょうか? 列と行を入れ替えるとか結合で調べたのですが、処理の方法がやはり よくわかりませんでした
ストアドファンクションをつくる、ということ。 単なるSQLで一発取得は難しいと思う
696 :
682 :2008/04/05(土) 15:37:52 ID:???
ありがとう こうやって詰めると いまいち分かってないですね自分は ANSIの英語の有料pdfか、よい本か 何かありますか
697 :
692 :2008/04/06(日) 13:49:33 ID:???
>>695 いろいろどうもです。
その部分が一番わからなかったのですが、もうちょっと調べてみます
SQL に固執しないで、Perl で整形する方法も検討してみたいと思います
パラメータ@hogeによってIN句を変化させたいのですが、構文エラーとなってしまいます。 シングルクォーテーションを二重化したり、色々してますがどれも上手く逝きません。 SQLServer2005です。HELP ME 項目 IN ( CASE @hoge WHEN 1 THEN 'A' WHEN 2 THEN 'B' WHEN 3 THEN 'C,D' END )
途中で送信してしまいました。 NGなのは、最後のWHEN 3 THEN 'C,D' でIN句に二つ以上指定する場合です。
>>698 @hoge の中に入るのがカラム名なら無理。
素直に複数の SQL を使うか、SQL を組み立てて Exec すれ
(@hoge = 1 and 項目 = 'A') or (@hoge = 2 and 項目 = 'B') or …
ごめんごめん。見誤ってた。それなら、テンポラリテーブルに突っ込んで、 そのテーブルに IN (SELECT) したらどう?
703 :
NAME IS NULL :2008/04/06(日) 22:59:27 ID:KZufWnQN
ストアドファンクションってのを作ろうと思ってるんだけど レコードがあればTRUEなかったらFALSE返すにはどうすればいいの?
selectしてROWCOUNT取って結果でtrueなりfalseなり返す ROWCOUNTが無いならCOUNT(*)を変数に入れて… て、「こうやってみたけど何が悪いでしょうか」ならともかく ゼロから手取り足取り、ってスレじゃないだろう。
0
706 :
698 :2008/04/07(月) 00:16:26 ID:???
>>700 SQL を組み立てて Exec
やはり、それですかねえ・・・。
>>702 テンポラリテーブル
これも検討してみます。
皆さんありがとうございます。
初歩的な質問ですみません number, name -------- 1, 名前a 2, 名前b 3, 名前c と言うようなテーブルがあって 2と3の間に「名前d」を挿入して number, name -------- 1, 名前a 2, 名前b 3, 名前d 4, 名前c という風に、任意の場所に挿入してもnumberが1から連番になるようにするには 挿入位置以降のnumberをいちいち書き換えるしかないのでしょうか?
ROW_NUMBERでぐぐれ
710 :
708 :2008/04/07(月) 20:18:24 ID:iZiy2Fgc
ググってみたんですが、名前a〜dの順番を決定するために また別の要素が必要になってしまいませんか?
>2と3の間に「名前d」を挿入して てのがよくわからん。 テーブルに「この順番で格納されてます」なんてのは無いぞ。 order by 付けずにselectかければ 取得順番が毎回同じである保障は一切無い
712 :
NAME IS NULL :2008/04/07(月) 21:13:26 ID:iZiy2Fgc
それはわかっています なのでORDER BY numberにしようかと思っているんですが 末尾追加でなく挿入の場合INSERTの度にnumberを いちいち書き換えなきゃいけないのか知りたいんです
714 :
NAME IS NULL :2008/04/07(月) 21:25:01 ID:iZiy2Fgc
連番をROW_NUMBERで生成するとしたら numberの割り振りに効率的な方法はありますか?
そのnumberがどういう仕組みで振られるのかがわからん。
716 :
NAME IS NULL :2008/04/07(月) 21:31:01 ID:iZiy2Fgc
連レスすみません ROW_NUMBERを使うのであれば nameの並び順以外の意味はないです
> それはわかっています ↓ > 末尾追加でなく挿入の場合 末尾とか(行と行の間に)挿入とか、こういう言葉が出てくること自体、 ぜんぜんわかってないから 頭の中がExcelだろ?
挿入するって事は、何かしらの仕組みですでに順序付けられてるところへ挿入するってことだから、 そもそもnumberは不要なんじゃないの?
719 :
NAME IS NULL :2008/04/07(月) 22:01:22 ID:iZiy2Fgc
>>717 教えていただいてるので
頭ごなしに言われるのも仕方ないと思います
すみません
>>718 PHPの添字配列にarray_spliceで挿入するような感じを想定していたんですが
”順序”自体に意味があるので
numberの書き換えで組んでみようと思います
お手数おかけしました
ありがとうございました。
DB内部の並び順は意識する必要がなく、射影する時にROW_NUMBERとかで採番すればよい
なんでおかしな方へおかしな方へ突っ走る
>>719 ”順序”自体に意味があるなら
それしかないね
帳票出力とかの話かな。 帳票の2行目と3行目の間に新たに行を追加したい、とか。
・2と3の間に入れたい場合は2.5、2.5と3の間に入れたい場合は2.75、、、以下同様 ・number付け替えする の2つしか考えつかね。
>>724 それが現実的だろうけどすっきりしないねぇ
採番ロジックの設計からやり直したいところだね
Number付け替えはまず無いよな、以降のデータ全て変更対象となるし
質問です! 以下のテーブルがあるとします。 Name Age A B ------------ Mike 15 1 2 Mona 19 2 1 Yumi 25 3 4 YUko 30 5 6 Ageが20以下の場合は、Aで昇順ソートして、 21以上の場合は、Bで昇順ソートしたいと考えてます。 このような場合、SQLにするにはどうすればよいでしょうか?
SELECT Name, Age FROM AGE ORDER BY CASE WHEN AGE<=20 THEN A、 ELSE B END これでOK?
order byでcase使えたっけ。 select Name,Age from (select Name,Age,case …) a order by … とか書かないといけない気もする
スレチかも知れませんが ある一つの閉じたシステムで異なるベンダのDBへ アクセスするなんていうのは普通にあるものなのでしょうか? たとえば、受注マスタがOracleで発注マスタがSQL Serverだったり。 それをある一つのシステムから使い分けて接続する。 もしあるとした場合の注意点などありますでしょうか。 こういうのをADOが吸収してくれたりするのかな。
>>731 複数システムがある時は構成としてはあり得るんじゃないかな。
それぞれにコネクション張るんだから別に問題は無いと思うけど?
>>731 新規開発案件がSQLServerで、基幹DBがOracleとかよくあるけどね。
レイトバインディングでADOの汎用クラス使って、ベンダの違い意識せず
処理するのが理想だけど、実際のところ速度面やらコーディングのしやすさで無理
ラップするクラスとか作ったことあるけど、 結局 SQL の違いが吸収できなかったな・・・
ゴッドハンドか
誤爆したか
SQL自体をラップするクラスをかけばいいんじゃ? 違うところなんて型変換とかだけだろ
GRANT もずいぶんと個性が発揮されるようで
740 :
NAME IS NULL :2008/04/09(水) 22:51:11 ID:+aDl/n0V
質問失礼します。 今以下のようなテーブルがあります 地域 県 −−−−−−−−− 東北 0 東北 青森 東北 秋田 東北 宮城 関東 0 関東 東京 関東 埼玉 関東 千葉 東海 0 東海 静岡 ・ ・ 別表で 県 人口 −−−−−−−−− 青森 100000 秋田 150000 宮城 200000 東京 1200000 ・ ・ 長いので続きます
結合してからSum()すればいいんじゃね? とエスパーレス
742 :
740 :2008/04/09(水) 22:57:11 ID:???
740の表を内部結合して 地域 県 人口 −−−−−−−−− 東北 450000(東北の総計) 東北 青森 100000 東北 秋田 150000 東北 宮城 200000 関東 2000000(関東の総計) 関東 東京 1200000 関東 埼玉 600000 関東 千葉 700000 東海 1000000 ・ ・ のような結果を導きたいのです。 ただし内部テーブルとUNIONを使わず、SQLは一回の発行で 行いたいのです。 GROUP BY だと 地域 をキーにするときと 地域 県 をキーにするときとで分かれてしまってこまってます。 どなたかヒントをお願いいたします。よろしくお願いします。
無理じゃね? 地域 地域の総計 県 県の人口 ならサブクエリで出せる
1個目のテーブルを地域テーブル 2個目のテーブルを人口テーブルとして、 A: 地域テーブルと人口テーブルを県名でINNER JOIN して 地域でGROUP BY して地域ごとの人口を出す 地域テーブルに対して 人口テーブルをLEFT OUTER JOIN 結合キーは県 地域テーブルに対して 上記AをLEFT OUTER JOIN 結合キーは地域。 WHERE 地域テーブル.県 = 0 取得項目は SELECT 地域テーブル.地域 ,CASE 地域テーブル.県 WHEN 0 THEN '' ELSE 地域テーブル.県 END ,CASE 地域テーブル.県 WHEN 0 THEN A.人口 ELSE 人口テーブル.人口 END
745 :
744 :2008/04/09(水) 23:20:02 ID:???
そこまでするならUNION使えって話だが
脱帽です
747 :
740 :2008/04/09(水) 23:25:01 ID:+aDl/n0V
皆様お答えありがとうございます! 早速明日やってみます。 やっぱり打たないとだめですね。 本当にありがとうございました。
group by rollup と、何も考えずにレスしてみる
749 :
744 :2008/04/10(木) 00:00:51 ID:???
死のう…
使い方はワスレタw でも存在くらいは覚えておこうな
質問です。
SQLとはちょっと違うのですが、wikipediaの関係代数-商についてです。
http://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82%E4%BB%A3%E6%95%B0#.E5.95.86 例として挙げられている
R:
father, mother, child, age (文字列などは略)に対して、
S:
child, age
Maria, 4
Sabine, 2
を計算し、R÷Sを実行すると、
father, mother
Martin, Malanie
が出力されるとあるのですが、
Rの表中には、
child, age
Maria, 4
Sabine, 2
に適合するものとして他に
father, mother
Hans, Helga
Hans, Ursula
があります。
なぜ商としてのR÷Sに、Hans, HelgaやHans, Ursulaが出力されないのでしょうか。
>>751 Hans, Helga は Sabine, 2 をもっていないし
Hans, Ursula は Maria, 4 をもっていないから。
753 :
NAME IS NULL :2008/04/12(土) 01:50:09 ID:THUSkmHr
階層構造をもったデータで、ツリーの末端になるデータを一発で取得するには、どのようなSQL文を発行すればよいでしょうか?
ツリー型掲示板のメッセージのテーブル「message」
+------+--------------+---------+
|msg_id|msg_id_parent |msg |
+------+--------------+---------+
| 1 | | カキコ |
+------+--------------+---------+
| 2 | 1 | 2GET |
+------+--------------+---------+
| 3 | 2 | 3だよ |
+------+--------------+---------+
| 4 | 2 |
>>2 OK |
+------+--------------+---------+
| 5 | 4 | はい |
+------+--------------+---------+
| 6 | | カキコ2 |
+------+--------------+---------+
| 7 | 6 | 2GET |
+------+--------------+---------+
msg_id_parent は、親ノードの msg_id を指す
mdg_id=5,7 のレコードは、自分の下にぶら下がっているコメントなし=ツリーの末端になっている。
msg_id=5のレコードを抜き出す場合、msg_id=5 を msg_id_parent に持つデータがないということを、SQLで表現できれば良いと思いましたが、うまく取得できません。
副問い合わせ(サブクエリー)というのを使う必要があるのでしょうか?
>>752 おぼろげながら理解しました。ありがとうございました。
>>753 サブクエリまたはNOT EXISTSを使う必要有り。
NOT EXISTSの方が速い。
まあパフォーマンス気にするなら
(かつ参照回数の方が登録回数よりずっと多いのであれば)
末端です、というフラグでも持たせたほうがいいけど。
サブクエリだと
WHERE msg_id NOT IN (SELECT msg_id_parent FROM message)
756 :
753 :2008/04/12(土) 14:47:56 ID:THUSkmHr
>>755 ありがとうございます。
そのサブクエリでうまくできました。(・∀・)
参照回数が多いので、木の葉にフラグデータを持たせるやり方を試してみます。
質問させてください。 ID STAFFID Num IoType 1 1 50 0 2 1 30 1 3 2 10 0 4 2 15 0 5 2 20 1 6 3 10 0 上記の様なテーブル(iotest)が有ります。 IoType 0=出庫 1=入庫 というフラグです。 これをStaffID毎にSUM集計したいと考えております。 select out_list.staffid, out_list.outsum, in_list.insum, (out_list.outsum - in_list.insum) as Sasi_hiki from (select staffid, sum(num) as outsum from iotest where iotype = 0 group by staffid) out_list left join (select staffid, sum(num) as insum from iotest where iotype = 1 group by staffid) in_list on out_list.staffid = in_list.staffid order by staffid; STAFFID OutSum InSum Sasi_Hiki 1 50 30 20 2 25 20 5 3 10 -- -- StaffID=3は、出庫のデータしか無いため、InSumが集計されず、結果として、差引も 計算されません。 Sumで集計された結果が無い場合に0に置き換えて、 STAFFID OutSum InSum Sasi_Hiki 3 10 0 10 とする方法は有りますでしょうか?
>>757 DB書き忘れました。
Postgres 8.2.6です。
つCOALESCE
>>757 質問の本質とはズレるけどleft joinはfull joinの間違いじゃないの?
left joinだと入庫だけしたStaffIDが出てこないけど?
で、full joinでいいとすればこんな感じでいいと思う。
select staffid,
sum(case when iotype = 0 then num else 0 end) as outsum,
sum(case when iotype = 1 then num else 0 end) as insum,
sum(case when iotype = 0 then num else -num end) as Sasi_hiki
from iotest
group by staffid
order by staffid
;
>>757 です
>>759 こんな便利なものがあったとは・・・有難うございます
>>760 ご指摘のとおりです。
もちっと精進してまいります
有難うございました
お世話になっております select * from ( select case when a is null then '○' when r is null then '△' else '□' end as result from d ) as d としてデータを取得しています。 このとき where d.result = '○' とすればデータが抽出されるのですが、 where d.result = '△' とするとデータが1件も取得できません。 whenの部分を入れ替えてテストして見ると、一番上の値以外は取得できないようでした。 すべての値を取得する方法はないでしょうか?
763 :
762 :2008/04/16(水) 21:11:58 ID:???
DB書き忘れました SQL Server 2005になります
>>762 select count(*)
from d
where a is not null
and r is null
この結果は?
SQLServer2005で、 名前 日付 数字 A 4/1 1 A 4/2 0 B 4/1 1 B 4/2 3 B 4/3 2 というテーブルがあったとき、「各名前の最新の日付のデータ」を 取得するSQL文を教えてください。 この場合は 名前 日付 数字 A 4/2 0 B 4/3 2 こういうデータがほしいです。
767 :
765 :2008/04/17(木) 09:57:13 ID:???
>>766 ありがとうございました。
これを参考にやってみます。
>>764 遅くなりました
全データ1000件に対し、27件のデータが取得できました
条件に不備はなさそうな気がします
とりあえず状態を保存するカラムを一つ作成し、そちらを抽出することで対応しました
また他に方法があれば質問させてください
769 :
NAME IS NULL :2008/04/17(木) 22:36:38 ID:9kZUJlvR
列1 列2(文字列) -------------------- A 青 A 赤 というテーブルがあるとして 列1 列2 ---------------------------- A 青・赤 という感じに 特定の列でグループ化し、 残りの列のデータを結合したいのですが、 SQL で可能でしょうか?
group_concat なければ似たような関数を自作する
771 :
NAME IS NULL :2008/04/18(金) 08:57:24 ID:hKVau2G8
ありがとうございます。
772 :
NAME IS NULL :2008/04/18(金) 16:55:20 ID:XTKHrXny
質問です。 日本語カタカナのソートをしようと思い、 select * from テーブル名 order by フィールド名(カタカナしか入っていないフィールド) とやってみたのですが、うまくなりません。 エンコードはどちらもSJISなのがいけないのでしょうか? できれば、もうずいぶん作りこんでしまったので、このまま行きたいのですが。。。 宜しくお願い致します。 ちなみにサーバーはさくらインターネットを使っています。
どういうデータをどういうSQLでどういう結果になったんだよ そしてRDBMSはなに?
774 :
NAME IS NULL :2008/04/18(金) 17:28:16 ID:XTKHrXny
>773 すみません。 説明不足でした。 現在MySQLを使用していて、今回ユーザー登録画面を作成して、その登録した情報を一覧で見れるようにしたんです。 そしてそこから名前のソートができる機能を作ろうと思い、登録画面でカタカナで名前を入れていただき、それをDBに保存して、今回のSQL分を打ってみたのですがちゃんと「あ〜ん」の順に並んで表示をしてくれないため困っています。
>>774 質問する場合は最低限テンプレに目を通して書式を守りましょう
質問テンプレ
・DBとバージョン
・テーブルデータ
・欲しい結果
・説明
my.confいじれないのか SET CHARACTER SET か SET NAMES で何とかなるかな? まあMySQL特有の話なんで専門スレ行ったほうがいいかもね。
777 :
NAME IS NULL :2008/04/18(金) 17:55:22 ID:XTKHrXny
>>774 度々のご指摘申し訳ありません。
・DBとバージョン
mysql 4.1.20
・テーブルデータ
テーブル名 client_data
client_no client_kana_name
----------------------------
1 イソベ
2 アイダ
3 ツヤマ
4 タガワ
5 テライ
・欲しい結果
select * from cilent_data order by cilent_kana_name
と実行してカナ順にソートしようとしているのでが、なぜか
client_no client_kana_name
----------------------------
2 アイダ
3 ツヤマ
1 ウタガワ
5 テライ
4 タガワ
となってしまいます。
ちゃんとソートするにはどうしたらいいでしょうか?
fromの後ろにテーブル名 ショートカット名? って文法ですが、 このショートカットに当たる単語って何ていう名前なんでしょうか。 後、このショートカット名に当たる単語が同じものが2つあるんですが、 これって何か不具合になったりしますか?
>>778 正しくは「相関名」だけど普通は「別名」と呼ばれていると思う。
同じ相関名を使っても問題ない場合もあるにはあるけど
問題ある場合のほうが圧倒的に多いと思う。
>>765 SELECT
A.*
FROM
(
SELECT
A.名前,
MAX(A.日付)
FROM A
GROUP BY
A.名前
)B,
A
WHERE B.名前 = A.名前
AND B.日付 = A.日付
>>778 オレはエイリアス(別名)て言ってる。
問題がある場合と問題のない場合がある。
どれがどうとは簡単には言えんが、可読性の面から言って普通はかぶらないようにつけると思う。
ACCESS2003を使っています 元データ ID 日付 名前 100 2008/04/01 AAAAA 100 2008/04/02 BBBBB 100 2008/04/03 CCCCC 101 2008/04/01 DDDDD 101 2008/04/02 EEEEE 101 2008/04/03 FFFFF 欲しい結果 ID 日付 名前 100 2008/04/03 CCCCC 101 2008/04/03 FFFFF IDが同じグループで日付が一番大きいものを取得したいです。 よろしくお願いします。
783 :
NAME IS NULL :2008/04/19(土) 00:02:04 ID:YxsuLOQX
784 :
778 :2008/04/19(土) 00:47:33 ID:???
フィールド名(+)ってどういういみっすか
>>784 オラクルの独自文法で外部結合をあらわす
>>783 ありがとうございます。できました。
SELECT A.*
FROM [SELECT ID, MAX(日付) AS 最大日付 FROM A GROUP BY ID]. AS B, A
WHERE (B.ID=[A].[ID]) AND (B.最大日付=[A].[日付]);
787 :
778 :2008/04/19(土) 01:18:19 ID:???
ありがとう。 やっぱり別名の重複に関する事がわかんねぇんですが、 FROM T_tbl_DTL A, ( SELECT A. * , procedure1( K_SDATE ) ||'0123' K_F FROM Mast_Tbl1 A ) B, みたいな流れの文法ってOKなんでしょうか、オラクルです。
普通にありだけどやめたほうがいい 以下のようなSQLになった場合にAがどちらのAをさしているかパッと見ただけじゃわからないから。 こんな短いSQLだとわかるけどね。 SELECT A.* FROM T_tbl_DTL A, ( SELECT A. * , procedure1( K_SDATE ) ||'0123' K_F FROM Mast_Tbl1 A ) B WHERE A.X = B.X
動的SQLについて質問です。 @pal1 = 引き数1 @pal2 = 引き数2 PREPARE tempSql FROM 'select * from t1 where f1 =? or f2 = ?'; EXECUTE tempSql USING @pal1 , @pal2; PREPAREで?が2個あったら2個ともUSINGで与えないと駄目なんですか? 引き数1,2は両方受け取る、片方だけ受け取る、どっちも渡されないって場合でも動いて欲しいですけど 引き数1だけ受け取ったら 'select * from t1 where f1 = @pal1 引き数2だけ受け取ったら 'select * from t1 where f2 = @pal2 両方渡されなかったら 'select * from t1 という感じにしたいです。
そのへんはDBMSごとの方言なのでDBMSごとの専用スレで聞いたほうがいいと思うが。 ちなみにPostgres?
sql serverです
動的SQL自体使ったこと無いから書き方は別に出来るかどうか知りたかったので
>>789 の記述も大よそです
もしかしたらプログラムでwhere文を作ってパラメータにwhere文そのものを渡せば良いかもと思いました
普通に IF で組み立てればOK SELECT @sql = 'select * from t1' IF @pal1 IS NOT NULL BEGIN SELECT @sql = @sql + ' where f1 = @pal1' END
なるほど 条件が増えてもIF文をその分増やせば良いわけですね ありがとうございました
794 :
NAME IS NULL :2008/04/21(月) 04:20:53 ID:aI9R1Zko
教えて下さい。 ER図を書けと言われたんですが、selectでひっぱってきているところを線で結べばいいのか、 whereで=でつながれているところを線で結べばいいのか、 外部結合とかをしているところだけ線で結べばいいのか わからなくなりました。 どんな時に線で結べばいいのですか?
>>794 基本的には外部キーを張るところに引くが、
その質問内容からすると全然分かってなさそうなんで
ちゃんと勉強することをお奨めする。
796 :
NAME IS NULL :2008/04/21(月) 08:13:19 ID:aI9R1Zko
>>795 すみません、どうもありがとうございます。
データモデリングとかの本を読めばいいんですよね?
797 :
NAME IS NULL :2008/04/21(月) 18:00:07 ID:9zadaJoD
データモデリング以前の気がする
798 :
NAME IS NULL :2008/04/21(月) 19:09:30 ID:7qcT8f5N
DQN男の家族消えろ DQN男の親消えろ DQN男の友達消えろ DQN男の親戚消えろ DQN男の家族消えろ DQN男の親消えろ DQN男の友達消えろ DQN男の親戚消えろ DQN男の家族消えろ DQN男の親消えろ DQN男の友達消えろ DQN男の親戚消えろ DQN男の家族消えろ DQN男の親消えろ DQN男の友達消えろ DQN男の親戚消えろ ニヤニヤ(・∀・) ニヤニヤ(・∀・) ニヤニヤ(・∀・) ニヤニヤ(・∀・) 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね死ね 死ぬとき このレスの事思い出してくれよ ニヤニヤ(・∀・) ニヤニヤ(・∀・) ニヤニヤ(・∀・) ニヤニヤ(・∀・)
DQN かもしれん。 sqlite3 です。 TABLE1 CODE NAME COMMENT 1 KEY HHK 2 MOUSE SAM 3 MONITOR MS TABLE2 CODE PRICE 1 12000 2 2500 二つのテーブルをまとめて CODE NAME COMMENT PRICE 1 KEY HHK 12000 2 MOUSE MS 2500 3 MONITOR MS 0 TABLE2 にはデータが不足してたりするので(PRICE)には0をセットした形にしたいです。 select * from TABLE1,TABLE2 group by CODE; から挫折しております。
Group By なんていらんだろ。 Left Join して、 isnull(price, 0) で。 sqlite しらんけど。
SELECT TABLE1.*, COALESCE(PRICE, 0) FROM TABLE1 LEFT JOIN TABLE2 USING(CODE) こうかな
>>800 あ、ありがとうございます。
left *,ifnull(price,0) from TABLE1 left join TABLE2 using(CODE);
までたどり着きました。
(それなりに表示するけど間違ってるかもしれない)
呪文にしか見えないけど感激っす。
なんか微妙に違くないか?w
804 :
802 :2008/04/22(火) 21:26:31 ID:???
>>803 やはり。。た、たのむ。おしえてぐで〜っ
先頭のleftがselectだろうってのと、*は TABLE1.CODE, TABLE1.NAME, TABLE1.COMMENT ってちゃんと書いたほうがいいってくらいじゃね?
806 :
802 :2008/04/22(火) 22:30:17 ID:???
>>805 あああっ left は何を思って打ったんだろ。ミスでした。
* の処ありがと。
left join はマジ感激。sql って・・・凄い。
このスレを先頭からみてレスしてる文が呪文に見えて理解できないのが一杯あるけどかなり興味でてきた。
807 :
NAME IS NULL :2008/04/23(水) 00:22:43 ID:5eOZ8dG6
^^^^^
>>802 >>801 のSQLは試したのかな?
ifnullって標準じゃないと思うのでcoalesceを覚えておいたほうがいいと思うよ
その調子でSQLのすごさにどんどん気づいていってくれるとうれしいw
809 :
802 :2008/04/23(水) 07:21:28 ID:???
>>808 ああ、801 の直前なのに見逃してる。眠気でボートしてたのか・・・
isnull が sqlite3 で使えなかったので判らないなりに検索したら ifnull が。そう、これは方言っぽいんですね。
ありがとうございます。coalesce 試してまっす。
TRUNCATE TABLE 眠気;
811 :
802 :2008/04/23(水) 19:30:32 ID:???
ども、今日は一日(でもないけど)少しずつ理解?
>>808 ありがと。coalesce しっかり頭にはいりました。
select 色々 from TABLE1 left join TABLE2 on ...
までたどり着きました。皆さんからすると入り口の一歩目ですね。
で、今日判ったのは sqlite3 では left , natual 位しかなくて right とかその他のはまだ実装されてない・・悲
そんなんで TABLE1 にしかないキー?は出るけど TABLE2 にしかなかキーはこのままでは出せないって事まで判った。
ところで、スタイル的なところで質問なんですが 大文字と小文字って(見かけ上)気をつけてることってありますか?
キーワードは大文字あるいは小文字とか。。
私はどうも小文字打ちになってしまう傾向にあります。
大文字で書くのが常識。 パフォーマンス絡みで調べてみ。 あと、left join があればright jon はいらんと思う。
キーワードは大文字で書いたほうが倍くらい速いんだよw
どのDBMSでの話?
だとすると、SQLのパースがターンアラウンドタイムの 半分以上を占めていないと計算が合わんぞ。 100msオーダーのトランザクションシステムとかか?
Oracleにきまってる
大文字は小文字より霊力が強い。だから大文字で書いた方が速くなる。
内部では全て大文字に変換されるから大文字のほうが早いってのはあるけど、 過剰に気にするほどのもんでもないよね
mysql4のソートについて教えてください category, no, name ----------------- 1, 1, AAA 1, 0, BBB 2, 1, CCC 3, 0, DDD 2, 2, EEE 3, 1, FFF 2, 0, GGG categoryが同じレコードはnoを0から振ってあります このようなデータで、noが最小値のnameでソートしたいのですが同じcategoryはno順にまとめる必要があります 結果は 1, 0, BBB 1, 1, AAA 3, 0, DDD 3, 1, FFF 2, 0, GGG 2, 1, CCC 2, 2, EEE となるのが希望です どのようにSQLを書けばよいのでしょうか
>>820 サブクエリが使えない4.0なのか、使える4.1なのかはっきりした方がいいんじゃね。
4.0ならたぶん無理。4.1なら可能だと思うけど...。
とりあえずORDER BY句でサブクエリが使えて、 「noを0から振って」ってあるので少なくとも0はあるというのを前提に書くと。 SELECT * FROM Table AS T1 ORDER BY (SELECT name FROM Table WHERE category=T1.category AND no=0),no;
823 :
820 :2008/04/24(木) 08:40:03 ID:???
失礼しました、mysqlは4.1なのでサブクエリは使用できます
>>822 さんのSQLで希望の結果が出せました
ありがとうございました
>>811 SQL文は大文字で書く癖を付けておくと、
JSP/ServletなどでjavaからSQL文を発行するときに目印になる。
個人でやるならどっちでもいいけどね。
SQLServer2005です。 TableAとTableBの内容はお互いに関係性は無いのですが、これらを 1つの表として取得することは可能でしょうか? TableA 時間A:datatime 内容A:nvarchar(5) TableB 時間B:datatime 内容B:nvarchar(10) 下のような表として得たい 時間 , 内容 --------------- 時間A , 内容A 時間B , 内容B : :
普通にunion allすればおkじゃね?
テーブル名やフィールド名を、コード内に記号定数として置くならまた別かも…。
828 :
802 :2008/04/24(木) 18:36:34 ID:???
大文字パワーですか。うむむ。
>>812 なるほど。いずれ RIGHT JOIN が今の私に必要とするシーンがくるのかなぁ。
>>824 キーワードは大文字・守・でいきまふ。Java でなく C++ からの呼び出しなので視覚的にぱっと引きますね。趣味の域だけど先輩方のスタイル少しでも学んで自分の物にしていきたいっす。
今日も DB 作ってみては壊したり。ふぅ。
この分野にすげー向いてなさそう
DROP ふ FROM 語尾;
語尾がどうしたってふ?
832 :
NAME IS NULL :2008/04/24(木) 20:25:47 ID:Vw4Ukrq3
MySQL 5 name reg_date installed_appls taro 2008/04/11 excel taro 2008/04/11 word hanako 2008/04/11 excel hanako 2008/04/11 word hanako 2008/04/11 powerpoint jiro 2008/04/11 excel jiro 2008/04/11 word taro 2008/04/13 excel taro 2008/04/13 word hanako 2008/04/13 excel hanako 2008/04/13 word hanako 2008/04/13 powerpoint jiro 2008/04/13 excel jiro 2008/04/13 word jiro 2008/04/13 powerpoint taro 2008/04/14 excel taro 2008/04/14 word jiro 2008/04/14 excel jiro 2008/04/14 word 欲しい結果 name reg_date installed_appls hanako 2008/04/13 excel hanako 2008/04/13 word hanako 2008/04/13 powerpoint taro 2008/04/14 excel taro 2008/04/14 word jiro 2008/04/14 excel jiro 2008/04/14 word 説明は次へ
833 :
NAME IS NULL :2008/04/24(木) 20:27:06 ID:Vw4Ukrq3
毎日、会社内にあるパソコンよりサーバに インストール済ソフトの一覧を送るようにしております。 それにより上の元データが作れられていくわけですが ここより 「ユーザ毎に 最後の日付で インストールされていたソフト一覧」 を呼び出したいのですがあれこれ試してみようとしたのですが… うまい方法が思いつかず>< よろしくお願いいたします。。。
>>832 mysql触ったこと無いけどこれ通るかな?
実行確認はしてないのでよろ。
SELECT
A.NAME,
A.REG_DATE,
A.INSTALLED_APPLS
FROM TABLE A,
(
SELECT
B.NAME,
B.INSTALLED_APPLS,
MAX(B.REG_DATE) AS MAX_DATE
FROM TABLE B
GROUP BY
B.NAME,
B.INSTALLED_APPLS
)C
WHERE A.NAME = C.NAME
AND A.INSTALLED_APPLS = C.INSTALLED_APPLS
AND A.REG_DATE = C.MAX_DATE
ORDER BY
A.REG_DATE,
A.INSTALLED_APPLS,
A.NAME
勝手に改変してみた。 SELECT A.NAME, A.REG_DATE, A.INSTALLED_APPLS FROM TABLE A, ( SELECT B.NAME, MAX(B.REG_DATE) AS MAX_DATE FROM TABLE B GROUP BY B.NAME )C WHERE A.NAME = C.NAME AND A.REG_DATE = C.MAX_DATE ORDER BY A.NAME, A.REG_DATE, A.INSTALLED_APPLS なんとなくこっちを欲してそうに思った。 できればこの二つの違いが何かを考えてみて欲しいです。がんばれー。
838 :
802 :2008/04/25(金) 07:04:47 ID:???
>>836 >>837 質問主ではないけど、そのソースは凄く刺激ある。帰ったらじっくり眺めて動かしてみよ。FROM の処にさらに (SELECT ... )C と書けるのか。凄いなぁSQL。
数字コテとかいらんから。
>>839 まあいいじゃん。
せっかく興味がわいてるっぽいんだから、それでいいとおもう。
タダのサブクエリじゃねーか?すごいのか?
おちけつ
各々の状況によって、すごかったり、すごくなかったりするので、 あなたがすごいと思ってるものは他の誰かにとってはすごくない。 むしろしょぼすぎてため息すら出るかもしれない。 そう考えると、それ、すごいか?というレスは容易にできないよね。 単に、一見タダのサブクエリに見えるが実はすげえテクニック使ってんのか? と思ってしまってるのなら、そんな事は無くタダのサブクエリです、と回答しとく。
俺も最近色んなことで新技術にウットリしちまうことあるから分かるよ
オレは最近LINQにうっとりした。
あー、アプリ毎に最新日はもらえないのね
俺なんてお店のチカちゃんにうっとりだぜ
俺はお前がうっといです
ROLLBACK;
PostgreSQL固有のことかも知れないけど、 よろしくお願いします。 セッションという概念がわからないので教えてください。 CGIプログラムとしてRuby PostgreSQLを使用しています。 1. 変更するデータをチェック(SELECTで取り出しRuby上で判断) 2. 変更していいなら変更、変更がだめだったらROLL BACK 3. その中でnextval、currvalなんかも使ったり。 と、いうことをしています。 で、1と2をやるのにBEGIN、COMMIT、ROLLBACKを使おうと思うのですが これってPGConn.queryでSQLを発行してその結果をRubyでごりごりして また、queryでSQL発行して、COMMITしてもその間はアトミックに操作が行われることが保証されるのでしょうか。 ついでに3のnextval、currvalに関するセッションの寿命に関しても答えてくださると幸いです。
851 :
850 :2008/04/26(土) 21:14:25 ID:AyuoAKFV
sageちゃったんでage
>>850 セッションていうかトランザクションだな。
で、前者はYES。
後者は、nextvalで取り出したけど使わなかった番号は欠番になる。
(rollbackされない。)
検索して、何件ヒットしたかを調べるにはどうすればいいですか? SELECT * WHERE id=1 FROM table で、id=1のものは何個あるか?といった事が調べたいのですが。
855 :
854 :2008/04/27(日) 13:44:49 ID:B1ZiztAB
ID出し忘れました。
>>854 おーい、それだとSQL文がエラーでるよ。
SELECT * FROM table WHERE id=1;
SELECT、FROM、WHERE は順序は崩してはいけない。
858 :
NAME IS NULL :2008/04/27(日) 13:50:57 ID:B1ZiztAB
>>856 使ってみます。
ありがとうございます。
>>857 久しぶりに書いたんで、すっかり忘れてました。
ありがとうございました。
というかな、このレベルなら教科書なりヘルプなりを 見た方が早いぞ。
別に突っ込まれてないような・・・?
そうだな。アンカの先を見間違っていたorz スマソ。
863 :
NAME IS NULL :2008/04/27(日) 15:54:02 ID:Tqt++e11
MySQLスレに質問したけど過疎ってるみたいなんで。 すごい初歩の質問なんだけど、 select * from web where name ='2chan' and category = '2chan' and type = '2chan' って感じで、同一単語(2chan)を検索したいんだけど、 where以降を縮める方法ってないですか? PHPのifみたいにフィールド名括弧で括って (〜and〜)='2chan' てやってもだめだし・・・。 初歩すぎるのか探してもなかなか見つからない。
select * from web where name = '2chan' and name = category and category = type とは書けるけど、あんまり短くならんね。 select * from web where name + category + type = '2chan2chan2chan' とか?w
865 :
NAME IS NULL :2008/04/27(日) 16:23:34 ID:Tqt++e11
>>864 あー、やっぱないんですね。
できればlikeでも使用したいんですが・・・。
(name & category & type) = '2ch'
とか、なんでできないんだろ・・・。
結構ニーズあると思うんだけど。
別のカラムって事は別の意味を持っているのが大体の場合において 一般的で、そうなると、それぞれのカラムを同一条件で検索したいと いうことはあまり無いかなぁ? たとえば複数のbool型のカラムがあったとして、すべてtrueのものを 抽出する場合でも、やっぱり個別に書く方が分かりやすいと思う。 それぞれのカラムにキーワードが高々1回しか出てこないのであれば where name || category || type like '%2ch%2ch%2ch%' と書くことで記述方法におけるニーズを割と満たしていると思うけど テーブル設計を見直してみると別の解決ができるかもですよ。
867 :
866 :2008/04/27(日) 17:06:13 ID:???
と思ったけど、そのような条件を多用するのであれば、ファンクションを 作ることを検討してみては?
>>863 手元の資料では
select * from web where '2chan' = ALL(name,category,type);
でいけるはずだけど、MySQLでは無理なのかな?
ALLってのはOracle特有の文法だな。 標準SQLでは select * from web where (name, category, type) = ('2chan', '2chan', '2chan'); となら書けることになってるけど。
標準で定義されているALLって1カラム複数行に対して使うものだと思ってた。 オラクルが同じ名前で方言を作るとも考えにくいんだけど、どうなんでしょ?
MySQL で可能かはわからないが select * from web where '2chan' in (name , category , type);
>>871 それだと、name、category、type のどれか、じゃね?
>>871 それだと or になってしまう
↓と同じことになるよ
select * from web where name ='2chan' or category = '2chan' or type = '2chan'
それは仮にできたとしてもorになるんじゃないのか
3連発スマンtt
876 :
NAME IS NULL :2008/04/27(日) 18:15:13 ID:Tqt++e11
>>866 たとえば掲示板に検索フォームを設置し、
検索対象はタイトル・本文・記入者の3つ。
掲示板テーブルの title text name の3つのカラムを対象に
それぞれ同じ単語のwhere句を作成するってなこと結構ありませんか?
この場合
(title & text & name) like '%$search_word%'
こんな感じにできるのが当たり前だと思ってました。
877 :
869 :2008/04/27(日) 18:21:47 ID:???
>>870 ALLって標準SQLにもあったのか。
慌てて調べたけど
>>868 はやっぱOracle特有だった。
標準SQLではvaluesが要る。
select * from web where '2chan' = all (values name, category, type);
878 :
866 :2008/04/27(日) 18:30:49 ID:???
>>876 個人的には、タイトル、本文、記入者のいずれかにキーワードが
含まれている記事を抽出されるほうがうれしいかな。
「奈」という字が姓名両方に含まれる人よりも、姓、名のどちらかに
含まれる人を探したいというか。
もうちょっと状況が詳しく分かると、よりよい解決方法が出てくるかも
しれないです。
879 :
NAME IS NULL :2008/04/27(日) 18:45:46 ID:Tqt++e11
>>877 おお、これは・・・。likeにも使えますか?
>>878 すみません、&じゃなくてorですね。間違えてました。
(title or text or name) like '%$search_word%' こうですね。
あきらめて個々に書くのが正解なんでしょうか。
880 :
869 :2008/04/27(日) 18:53:47 ID:???
>>879 ああ、すまん、個人的な興味で調べただけで、
質問の答えを考えていたわけじゃないんだ。
で、
>>877 はlikeには使えない。
やりたいことへの答えとしては、素直に
title like '%$search_word%' or text like '%$search_word%' or name like '%$search_word%'
と書くべきだと思う。
882 :
868 :2008/04/27(日) 19:08:39 ID:???
>>877 情報ありがとうございます
valuesを追加しましたけど、MySQL5.0.45では
ERROR 1064 (42000): You have an error in your SQL syntax; でした
select * from web where '2chan' = ANY (values name, category, type);
も同じくだめでした
ALLの()の中身をサブクエリでなら使ったことがあるんですが、この手のはだめみたいですね
883 :
NAME IS NULL :2008/04/27(日) 19:13:32 ID:Tqt++e11
>>880 そうですかー。
ありそうでないですね。ありがとうございます。
見逃してましたが
>>871 さんのもかなりいい感じですね。
likeに対応してれば完璧なんですが・・・。うう。
その他答えてくださったみなさんも本当にありがとうございます。
884 :
866 :2008/04/27(日) 19:30:13 ID:???
>>879 え、、、orでいいのか。。。
じゃあ
where name || category || type like '%2ch%'
これでだめ?
885 :
NAME IS NULL :2008/04/27(日) 20:21:23 ID:Tqt++e11
>>884 それは出来ると思って前に試したんですけど、ダメでした。
文法的には有りなんでしょうか?
今試したんですけど、
title like '%$search_word%' or text like '%$search_word%' or name like '%$search_word%'
これと同等の結果は得られないみたいです。
886 :
866 :2008/04/27(日) 23:01:00 ID:???
ごめんなさい。MySQLにうとかったようで。。。 やりたかった事は各カラムを文字列連結してlikeしたかっただけです。 MySQLだと、 where concat(name, category, type) like '%2ch%' と書く必要があったようです。 PostgreSQLだと || が文字列結合になるので、その意識のまま 書いてました。
887 :
866 :2008/04/27(日) 23:05:28 ID:???
たびたびですが、concatはいずれかの引数がNULLであった場合にNULLを 返却するようですので、NULL可のカラムがある場合はすべてcoalesceで はさむことになると思います。 where concat(coalesce(name, ''), coalesce(category, ''), ... like '%2ch%' こうなると本末転倒になるかもしれないですね。。。
>>836 >>837 書き込み制限がありお返事があり申し訳ありませんでした><
サブクエリーってこういう場合に使うんですねぇ…とかなり勉強になりました^^;
ありがとうございますー。
今後、お教えいただいたことを応用できるよう勉強させてもらいます。
select * from テーブル where ID=1; というプログラムのうち、FROMとWHEREに*を指定する事はできないでしょうか? やってみると何も帰ってこなくなるので、恐らくエラーになっているのだと思うのですが・・・。
>>889 できるわけないだろ。
基本を勉強しろよ
ではwhereにlikeだけを指定することってできないんでしょうか? 検索プログラムを作っているのですが、全てのテーブル、フィールドから指定したキーワードを含む文字だけを抜き出す方法が分からないんです。
>>891 そういうのは、SQL でなくて、フルテキストとか使いましょう。
SQL でやりたいのであれば、すべてのテーブルのすべてのフィールドに対して
それぞれ指定する必要があります。
>>892 全てのテーブル、フィールドに対して指定するとのことですが、こういう事でしょうか?
select * from テーブル1,テーブル2,テーブル3,テーブル4, where ID=1;
>>893 それだとかけ算になっちゃうけどいいの?
あと、フィールドがひとつしか指定されてない。
>>894 検索するとテーブルはカンマ(,)で区切るとあったのですが、もしかして間違っているでしょうか?
フィールドは忘れていました。
>>895 検索って何? まずは、SQL の本でも読んで勉強することをおすすめするよ。
テーブル間の関係が記述されていないので、期待通りの結果はかえって
こないと思われ。
897 :
NAME IS NULL :2008/04/29(火) 19:20:23 ID:8694Hlr5
>>886 >>887 866さん返信が遅れてすみません。
具体的なアドバイスありがとうございます。
NULL可・不可を分ける必要があっても今後十分使えそうです。
非常に参考になりました。
ご丁寧な回答本当にありがとうございました。
>>855 亀&スレチですまんが、ID出すか出さないかって書き込む人が任意に選べるもんなの?
900 :
NAME IS NULL :2008/04/30(水) 06:55:34 ID:moNZ8oAl
若いな( ´ー`)y-~~
SQLServer2000を使用しています。 コード | 項目1 | 項目2 | 項目3 ────────────────────── 111 | ○ | ○ | ○ ────────────────────── 111 | | △ | ────────────────────── 111 | | | × ────────────────────── 222 | | ○ | ────────────────────── 222 | | | △ ────────────────────── とういうテーブルを コード | 項目1 | 項目2 | 項目3 ────────────────────── 111 | ○ | ○(改行)| ○(改行) | | △ | × ────────────────────── 222 | | ○ | △ ────────────────────── というように、コードでグループ化し、それ以外の項目は各値を改行で繋いで表示したいです。 どのようなSQLを書けば良いでしょうか?
>>902 SQLでなんとかするってレベルの話じゃねーぞ
普通にOrder byで前者の順で得たレコードを、
ホスト言語側で後者のように整形して表示してやればいい
どーしてもストアドだけでやりたいんなら、
ここでの質疑応答だけで解決すんのは無理
904 :
902 :2008/04/30(水) 15:53:55 ID:???
やっぱりそうですか。 実際に今はVisualStudio2005を使用していて、画面表示にはFlexGridを、印刷にはCrystalReportを用いています。 仰るとおりに画面側も帳票側も出力時に整形しています。 画面側では、セルのマージとかやっていますが、もうちょっとスマートに扱いたいなと思った次第です。 ありがとうございました。
PostgreSQL 8.18 を使用しております。 以下の問合わせ方法が実現できそうであれば、 ご教授よろしくお願いします。 <テーブルデータ> id | seq_id | room ----------------------- 1 | 1 | ○○ビル102 2 | 2 | △△ビル302 3 | 3 | ××ビル102 3 | 4 | ××ビル501 3 | 5 | ××ビル703 4 | 6 | □□ビル202 <欲しい結果> id | room1 | room2 | room3 ---------------------------------------- 1 | ○○ビル102 | 2 | △△ビル302 | 3 | ××ビル102 | ××ビル501 | ××ビル703 4 | □□ビル202 | 単純な問合わせしか分からないSQLの初心者です。 副問合わせ、自己結合、CASE式などを勉強しつつ 3日間程考えたのですが、応用が利かないタイプな上、 他のサンプルなどと合わせようとしても合いませんでした。 よろしくお願いします。
縦を横にする系のストアドファンクションがないか探して見るといいよ RDBMSごとに提供具合が異なるかと。
>>904 SQL以外の言語にも経験あるみたいだから、やりゃーできるんじゃねーの。
declare cursor fast_forward for select * from xxx order by コード asc から
fetch next しながら各項目の文字列をつないでいく。コードがブレークしたら insert。
それを table-valued function の中でやればいい。スマートと言うかは疑問だがw
TABLE1 No | D1 | C1 このレコードで TABLE2 No | D1 | New1 | C1 としいう形に作り直したいですが (New1 = NULL) 始めたばかりでSQL 文でうまく実現する方法が・・・ これまでやってみたこと SELECT No,'NULL,'D1,C2 FROM TABLE1; 希望する並びに(近い?)形で表示はできたのですが、TABLE2 に持っていく方法が断念です。Help
>>910 ヒントありがとうございます。できるという空気は感じましたが全体の文がつかめてないっす。今、その答えを聞くのは簡単だけど・・一日粘ってきます。ありがとうございます。
912 :
905 :2008/05/01(木) 00:57:07 ID:+1kXGQKN
>>906 ありがとうございます。
列が可変になると駄目なんですね…
勉強になりました。
>>907 ありがとうございます。
SQLでまともな問い合わせも出来ないので、
ストアドファンクションを考えても見ませんでしたが、
この機会に少し見てみることにします。
>>909 INSERT INTO TABLE2
SELECT
T1.No,
T1.D1,
null AS New1,
T1.C1
FROM TABLE1 T1
>>913 テーブルを新規に作っちゃうんですね。参考になりました。d
915 :
902 :2008/05/01(木) 09:59:15 ID:???
>>908 そのようにカーソルを使って Fetch Next しながら云々ももちろん考えました。
ただ、なんとか Select 文の工夫だけでできないものかと思っただけです。
ありがとうございました。
>>914 自分で TABLE1 と TABLE2 って名前変えてるんだから新規に作ると思うだろ常考
そのテーブルにカラム追加したいなら alter table 使え。
New1 を D1 と C1 の間に入れたいのかも知れないが、
RDBではカラムの順序にはデータ構造上の意味は何もない。
917 :
NAME IS NULL :2008/05/01(木) 13:49:11 ID:/NYPxvw/
SELECT id, curtime( ) FROM test ORDER BY RANK このようなSQLの実行に、すごく時間がかかった時は、 curtime()の値も変わるのでしょうか? 一度だけ実行されるのか、 何度も実行されるのか…という疑問です
>>913 今帰ってきました。ほしたら答えが・・・ありがとうございます。
といいつつも文の内容の十分な理解はできてません。
今、このソースを打ち込んでばっちしな結果なんですけどだまされた気分になっているは否めません。
しかし今日のこれは私にとってとても大きいです。調べよって言われるとそれまでだけど・・・
>>916 SQLite3 なんですが alter table ・・・あった。(というか最近のバージョンで実現?)
始めたばかりもあるのかカラムの並びちょっと気に掛かってました。それよりも INSERT INTO TABLE1 .. の後に VALUES しか知らなかったのでそれはそれで新鮮です。
919 :
NAME IS NULL :2008/05/02(金) 04:14:03 ID:gmzuFZbL
こんにちは、 phpからmysqlを操作しようとしているのですが、 Host is not allowed to connect to this MySQL server が表示されてしまい、ブラウザにテーブルがでてきません。 どなたか、アドバイスいただけますでしょうか。 宜しくお願いします。
ホストは許していません接続をこのSQLサーバー
>>919 1. サーバーの設定を見直す
2. スレ違い
922 :
NAME IS NULL :2008/05/02(金) 12:17:54 ID:6LOyzsRH
10分前にmySQLに始めて触りました。 コマンドライン操作にイライラ。 GUI操作するための、toolとかってありますか?
>>922 なんでMySQLスレに行かないんだろ。
MS-ACCESSでデータ変更はできると思うし、CSEで任意のSQL投げられるんじゃなかった?
>>922 ここはSQLのスレで、MySQL固有の話はスレ違い。
環境晒してMySQLのスレで聞いてみ、答えてもらえるかもよ。
925 :
922 :2008/05/02(金) 14:42:37 ID:???
なんという事でしょう。 MySQL == SQLはfalseだったのです。
ばかじゃねーの
>>922 GUIとまではいかないが、CSEを使えば多少はわかりやすいでしょう。
CSEで検索すればすぐに出てくる。
GUI操作=善、という発想の香具師はアフォ
というかSQLと関係ないなぁ
商品一覧を作成中です。(現状はMySQLを利用していますが、PostgreSQLに移植する可能性もあります。) 商品をオススメ順に並べられるようにオーダーキーを用意しています。 オーダーキーは数値型で、商品登録時にインクリメントして入れて、並べ替え画面で入れ替えています。 商品種別自体は200種類もありませんが、商品入れ替え(削除)が頻繁に予想されるので、 何年か使用するうちにと歯抜けだらけでオーダーキーが桁あふれする事が心配です。 そこでオーダーキーのリナンバーを考えているんですが、 1. 商品IDとオーダーキーを保持するテンポラリテーブルを用意する(オーダーキーはオートナンバー型) 2. 商品マスタからオーダーキー順に商品IDを挿入 3. テンポラリテーブルのに出来た新オーダーキーで商品マスタのオーダーキーを更新 4. テンポラリテーブルをドロップ と言う方法を考えたんですが、もっとシンプルな良い方法がありそうな気もします。 なにかもっと良い方法がありましたら教えていただけないでしょうか?
仮に年中無休で毎日全商品200種を入れ換えても3000年くらいは持つように思えるのだが?
SQLに限らず、むしろGUIが分からなくてイライラすること無い?w
おれもそうだw
create table tbl ( a varchar(10), b int ) で、b の値は基本的にテーブル内でユニークなんですが、まれに他の列の値と重複します。 b がユニークでない列を delete 一発ですべて削除できますか? たとえば b=999 が 2列あるとき 2列とも削除したいです。
基本的に、とか止めれ。Unique 制約つけれ。 delete from tbl where b in ( select b from tbl group by b having count(b) > 1) こんなんでどう?
列じゃなくて行だがな
いや、ユニークじゃないんだろ。 片方を残さずdeleteするってことはダブってinsertされるデータは許されないってことじゃないか?
939 :
935 :2008/05/06(火) 18:02:54 ID:???
ありがとうございます、うまくいきました。列じゃなくて行ですよね・・・。 havingを使ったことがなく、ましてそこに count関数を書けるとは知りませんでした。 テーブルのデータは自分が関与できない他システムから CSVファイルで渡ってきて、 それを bcpでロードしてます。unique制約つけるとデータ全体がロードされなくなります。
>>939 bcpってSQLServer?
よく知らんけどエラー許容数とかエラーファイルとか指定できないの?
質問です。 日付型データと数値データを繋げて、 さらにそれを数値データにしたいのですが、 (例→2008-05-07 と 01 で 2008050701) TO_NUMBER(TO_CHAR(日付データ) || TO_CHAR(数値データ)) としたら、「数値が無効です」とエラーが出ます。 何が問題なのかまったくわかりません。 どなたか教えて下さい、よろしくお願いします。
>>941 まずは、
SELECT TO_CHAR(日付データ)
SELECT TO_CHAR(数値データ)
としてみて、次に
SELECT TO_CHAR(日付データ) || TO_CHAR(数値データ)
としてみて、最後に TO_NUMBER() すれ。デバッグの基本じゃね?
943 :
941 :2008/05/07(水) 20:08:21 ID:???
>>942 レスありがとうございます。
色々あって、プログラミングの勉強開始1ヶ月で実務をやっていて、
基本すら知りませんでした。不勉強なせいでお時間取らせてしまい、すみません。
何が問題なのかわからない場合は、一度解体してそれぞれでやってみて、
どの部分に問題があるのか探す、という理解でよろしいでしょうか?
明日にでも、もう一度試してみます。
どうもありがとうございました!
(´-`).oO(cafe50?・・・)
データベースって経験浅い奴が関与すべきじゃないよなあ。
よく切れるナイフみたいなもんで、うまく使えば有用だがそうでないと・・・
>>944 死ね
大げさな
大げさ
うそ・おおげさ・まぎらわしい
JAVA
Jet Anal Vibrate Association
JAVAって何じゃば
以下のSQLで、T.TIME以上のI.TIMEの中で最も小さいI.TIMEの ものを指定したいのですが、できません。(右カッコがないと言われる) どうすればいいのか、アドバイスお願いします。 INSERT INTO &&TABLENAME.(NUMBER,CODE,KNUMBER,SCODE,KOSU,MONE) SELECT T.NUMBER ,I.CODE ,I.KNUMBER ,I.SCODE ,SUM(I.KOSU) ,SUM(I.MONE) FROM IPO I ,TAIN T WHERE I.CODE = T.CODE AND I.KNUMBER = T.KNUMBER AND I.TIME > T.TIME HAVING I.TIME = MIN(I.TIME > T.TIME) GROUP BY T.NUMBER ,I.KNUMBER ,I.SCODE
MIN(I.TIME > T.TIME)
ある分類別で集約したいのですが、可能ですか? 果物と肉類は 食品 その他は 非食品 として、それぞれの数を出したいのですが 分類 商品 果物 みかん 果物 りんご 果物 みかん 肉類 サーロイン 肉類 サーロイン 肉類 牛たん 家具 ソファー 家具 ベッド 文具 鉛筆
MINの中に比較演算子を使ってはいけないということでしょうか? では、どうすればいいんでしょう…。 お手上げです。
>>956 hogehoge = I.TIME > T.TIME
MIN(hogehoge)
でどう?
>>955 ・食品
SELECT COUNT(*) FROM table
WHERE 分類 = '果物' OR 分類 = '肉類'
・非食品(果物でも肉類でもないもの)
SELECT COUNT(*) FROM table
WHERE 分類 != '果物' AND 分類 != '肉類'
>>957 ありがとうございます、やってみます。
hogehoge = i.time > t.timeってのは
普通どこで指定しておくものなんですか?
960 :
NAME IS NULL :2008/05/10(土) 11:57:45 ID:72o5h6vw
>>959 selectにあってgroup byにないカラムがあったので、てきとー
INSERT INTO &&TABLENAME.(NUMBER, CODE, KNUMBER, SCODE, KOSU, MONE)
WITH TBL AS
(
SELECT T.NUMBER, I.CODE, I.KNUMBER, I.SCODE, I.TIME, I.KOSU, I.MONE
FROM IPO I
INNER JOIN TAIN T ON I.CODE = T.CODE AND I.KNUMBER = T.KNUMBER AND I.TIME > T.TIME
)
SELECT NUMBER, CODE, KNUMBER, SCODE, SUM(KOSU), SUM(MONE)
FROM TBL TBL1
WHERE TIME = (SELECT MIN(TBL2.TIME)
FROM TBL TBL2
WHERE TBL2.NUMBER = TBL1.NUMBER
AND TBL2.CODE = TBL1.CODE
AND TBL2.KNUMBER = TBL1.KNUMBER
AND TBL2.SCODE = TBL1.SCODE
GROUP BY TBL2.NUMBER, TBL2.CODE, TBL2.KNUMBER, TBL2.SCODE)
GROUP BY NUMBER, CODE, KNUMBER, SCODE, TIME
ダメだな、おれ
共通テーブル式使ってるし、相関クエリ使ってるし、動かしてないし。。。
スマン、あげてまった orz
よくある質問 (問) 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 ;
よくある質問 (問) 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 ;
>>962 ちょうど欲しいと思ってた
・MySQL 4.0.27
ただやってみたらselectの"("あたりでエラーになる
select A.ID, A.DATE, A.DATA
from test A inner join
(select ID, max(DATE) as MAX_DATE
from test
group by ID
) B
on A.ID = B.ID
and A.DATE = B.MAX_DATE
MySQLのメッセージ: ドキュメント
#1064 - 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 'select ID , max( DATE ) as MAX_DATE from test group by ID )
なんでか教えてくれorz
>>964 MySQLで副問合せが使えるのは4.1以降
966 :
962 :2008/05/13(火) 22:29:34 ID:???
>>965 サンクス
一応自分で考えてみるが、余裕があったら代替案教えてくれ
967 :
965 :2008/05/13(火) 23:05:24 ID:???
>>966 俺は一文でやるのは無理だと思う。
他の誰か、頼んだ!
テンポラリテーブル?
969 :
962 :2008/05/13(火) 23:12:42 ID:???
だよな。。。いろいろ調べた結果 create temporary table B select ID, max(DATE) as MAX_DATE from test group by ID; select A.ID, A.DATE, A.DATA from test A inner join B on A.ID = B.ID and A.DATE = B.MAX_DATE; でいいかな? あと、これperlで使おうと思ってるんだが $sth = $db->prepare(1文目); $sth->execute; $sth = $db->prepare(2文目); $sth->execute; という風に分ける必要ある?一回でできないかな?
つか、ストアド使えねーのけ?
971 :
962 :2008/05/13(火) 23:18:59 ID:???
ストアドプロシージャ? 今初めて聞いた言葉だったんで調べたらMySQLは5.0以降に標準SQL準拠でサポートってwikipediaに書いてあった なんで使えないかなぁー
質問です。 NVLの逆がしたいんですが、どうすればいいでしょうか? 指定した項目がNULLならそのままNULLとして、 NULL以外であれば特定の値に変換したい、というわけです。 oracleです。
>>974 ちょうど質問後に必死でググッてそこに到達しました。
NVL2の方がスマートっぽいですね。
ありがとうございました。
>>976 OracleはVARCHAR2やNVL2のようにOracle独自ではあるが、
使い勝手のいい型が[SQL92]2でそろってる。
978 :
NAME IS NULL :2008/05/15(木) 22:30:00 ID:gOggTcL2
うちの社員誰もわからなかったので質問します! ・ORACLE10g使用 TABLE1 : IDがPK -------------------- ID | MONEY -------------------- 1 | 1000 2 | 2000 3 | 2000 -------------------- TABLE2 : KEYがPK -------------------- KEY | ID | SALES -------------------- 1 | 1 | 500 2 | 1 | 200 3 | 3 | 100 -------------------- TABLE1のMONEYから、TABLE1のID=TABLE2のID、のカラム全てのSALES合計値を引いた値が 10以上とか100未満とかを検索したい。 検索結果の10番目から20番目のみを取得するなどの条件を付加する予定。 ORDERを使用する予定。 以上を踏まえたSQL文をかいてみましたが SELECT * FROM ( SELECT ROUNUM RN, A.* FROM ( SELECT x.ID, x.MONEY FROM TABLE1 x WHERE ( x.MONEY - (SELECT SUM(u.SALES) FROM TABLE2.u WHERE u.ID = x.ID) >= '100' ) ) A ) これだと取得できないのです! SELECT x.ID, x.MONEY FROM TABLE1 x WHERE ( x.MONEY - (SELECT SUM(u.SALES) FROM TABLE2.u WHERE u.ID = x.ID) >= '100' ) だけだと取得できてるのですが・・・ なぜだめなのかおしえてください!
>>978 今やってみたけどどっちも予想通りの結果になるけど?
(ROUNUM とか TABLE2.u とかのタイプミスは除いて。)
RN ID MONEY
---------- ---------- ----------
1 1 1000
2 3 2000
「取得できない」ってのは期待した結果に対してどう違うの?
980 :
NAME IS NULL :2008/05/16(金) 00:07:33 ID:8cLWGMeg
>>979 まじですか!!
なんか定義されてませんみたいなエラーが出たんですが、明日もう一度試してみます!
テストありがとうございます!
981 :
NAME IS NULL :2008/05/16(金) 00:11:51 ID:8cLWGMeg
>>979 あれ、今見たら結果が想定した値ではないです!
RN ID MONEY
---------- ---------- ----------
1 1 1000
2 2 2000
3 3 2000
が帰ると思ってたんですが
SELECT SUM(u.SALES) FROM TABLE2 u WHERE u.ID = x.ID
って取得できなかったら 0 を返すんじゃなかったでしたっけ
NULLはNULLだろ
>>983 乙
質問なんだけど1つのテーブルに登録できるレコード数って制限ある?
それともHDDの容量が許す限り?
確認方法とかあったら教えてください。
・MySQL 4.0.27 さくらのレンタルサーバでphpMyAdmin 2.11.2.1
>>984 調べてないけど42億レコードぐらいまでは大丈夫そうに思うけれど。
DBMSごとに物理サイズ制限があるからそっちのほうが先にきそうな。
986 :
984 :2008/05/17(土) 00:09:52 ID:???
42億まで大丈夫とマニュアルに書いてありながら、じつは21億超えると いろいろ不具合が出るなんて落とし穴があるかもしれないから気をつけな。 Postgresの昔のバージョンでこれやられた。
ホスティングの容量制限の方が先にくるだろ常考 ともあれ、スレ違いだな
>>978 TABLE1のID全ての値が欲しいならLEFT JOIN使わないと。
MySQL 4.0.27 レコードが挿入された順に並び替えることは不可能? 挿入された日時のフィールドはないですが。。。 普通にSELECTして順番になってるかと思ったらそうでもなかった 多分途中で削除とかしてるからか?? もし、今からその機能追加する場合は INTでauto_incrementで大丈夫ですか? こっちも途中削除されたら抜ける気が。。。 抜けても抜けっぱなしなら問題なさそうですが そこんとこどうなんですか? それとも無難にTIMESTAMPか
Order By を指定せずに並び順を期待しちゃダメ。 これ、SQL の基本中の基本。
>>990 一般的なRDBMSは、ORDER BYがない場合の並び順の実装はかなり異なる。
データの挿入順に何か指標になる列を作るべき。
>>990 オレならIDを持たせて、insertするときにテーブルに存在するIDのMAX+1を新規レコードのIDにする。
削除すると歯抜けにはなるが、順序はこれで保障される。
他にいい案があったらよろしく。
>>993 普通にAutoIncrement列でOK
>>993 auto_incrementやTIMESTAMPを否定して自分の案を主張するなら
それらの欠点を挙げてからだと思うけど。
ちなみに俺は
>>993 の案を含めて、どれでもいいと思う。
もちろん多少の向き不向きはあるけど、そこまで要件が書かれていないので。
AutoIncrementって更新可だっけ?
997 :
990 :2008/05/18(日) 16:55:59 ID:???
>>991-996 ありがとうございまっす
auto_incrementって抜けっぱなしになってくれるんですね^^/
ありがたい。
登録された順で並び替えれさえすればいいので
auto_incrementでやってみます
ume
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。