1 :
NAME IS NULL :
2011/03/05(土) 15:12:10.68 ID:c4C/uG2A このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。
SQLという言語はISOによって標準化されていますが
この標準を100%実装したDBMSは存在せず、
また、DBMSによっては標準でない独自の構文が
追加されていることもあります。
質問するときはDBMS名を必ず付記してください。
【質問テンプレ】
・DBMS名とバージョン
・テーブルデータ
・欲しい結果
・説明
前スレ:
SQL質疑応答スレ 10問目
http://hibari.2ch.net/test/read.cgi/db/1274791771/
SQLで迷路を作りたいです。 どうすればいいですか?
最近SQL 基礎文法 (?) 最速マスターなる記事を見かけたからあれを参考にしる
よくある質問1 (問) ID | DATE | DATA --+----------+----- 1 | 2007-11-11 | aaa 2 | 2007-11-11 | bbb 1 | 2007-11-10 | ccc 3 | 2007-11-12 | ddd 3 | 2007-11-11 | eee 4 | 2007-11-10 | fff 1 | 2007-11-12 | ggg このようなテーブルから、下記のように 1 | 2007-11-12 | ggg 3 | 2007-11-12 | ddd 2 | 2007-11-11 | bbb 4 | 2007-11-10 | fff 各idに対して最新の1件だけ抽出するSQLの書き方を教えてください。 (答) select A.ID, A.DATE, A.DATA from TableName A inner join (select ID, max(DATE) as MAX_DATE from TableName group by ID ) B on A.ID = B.ID and A.DATE = B.MAX_DATE ;
よくある質問2 (問) key data ---------------- 1 a 1 a 1 b 1 b 1 a 2 b 2 a 2 a というテーブルから key a b -------------------- 1 3 2 2 2 1 というExcelのピボットの様なデータを取得したいのですが、どういうSQLになりますか? a,bというのは固定なので、仮にcというデータがあっても無視して構いません。 (答) SELECT key, SUM(CASE data WHEN 'a' THEN 1 END) AS a, SUM(CASE data WHEN 'b' THEN 1 END) AS b FROM table GROUP BY key ORDER BY key ;
よくある質問3 (問) ID HOGE 01 A 01 B 01 C 02 A 03 B HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか (答1) SELECT id FROM TableName WHERE hoge in ('A','B','C') GROUP BY id HAVING count(DISTINCT hoge) = 3 ; (答2) select * from TableName T1 where not exists (select * from (values 'A', 'B', 'C') T2 (HOGE) where not exists (select * from TableName T3 where T1.ID = T3.ID and T2.HOGE = T3.HOGE ) ) ; ※valuesの部分(Table Value Constructor)はDBMSによって文法がかなり違うので注意
よくある質問5 (問) 年月(YYYYMM)を指定し、その年月に対応する年月日を取得したい 例:201006を指定したら、以下の結果を得たい 20100601 20100602 ・ ・ ・ 20100630 (答) SQLでは存在しないデータを生成することはできません。 この問いの場合は素直にカレンダーテーブルを用意しましょう。 どうしてもやりたければ以下のような方法もなくはないですが、 再帰問合せの本来の使い方ではありません。 やめておくことを強くお奨めします。 (PostgreSQLのgenerate_series()関数なら辛うじてセーフかもしれませんが 賛否の分かれるところでしょう。) with TEMP (NUM) as ( select 1 from dual union all select NUM + 1 from TEMP where NUM < 31 ) select to_char(to_date('201006', 'YYYYMM') + NUM - 1, 'YYYYMMDD') from TEMP where to_date('201006', 'YYYYMM') + NUM - 1 < add_months(to_date('201006', 'YYYYMM'), 1) ; ※上記はOracleの場合です。(11gR2以降) ※再帰問合せをサポートするDBMSならこれを適当に改変すれば動きますが どのみちお奨めしません。
12 :
NAME IS NULL :2011/03/05(土) 23:47:35.71 ID:STgNFvKX
以下のようなテーブルがあるとします。 [テーブル名:経費TBL] 会社 , 部署 , 年度 , 月 , 経費 ------------------------------- AAA , AAA01 , 2009 , 1 , 10000 AAA , AAA01 , 2009 , 1 , 20000 AAA , AAA01 , 2009 , 2 , 30000 AAA , AAA01 , 2009 , 3 , 40000 BBB , AAA01 , 2009 , 4 , 50000 BBB , AAA01 , 2010 , 1 , 60000 CCC , AAA01 , 2010 , 1 , 70000 CCC , AAA01 , 2010 , 1 , 80000 ここから以下のような、 会社別、部署別の集計データを作成したいとします。 会社 , 部署 , 200901経費計 , 200902経費計 , … , 201012経費計 この時、経費計列の条件指定はどうしたら良いのでしょうか?
>>12 一般的には
SELECT 会社, 部署, 年度, 月, SUM(経費) AS 経費計 FROM 経費TBL
GROUP BY 会社, 部署, 年度, 月
とでもやって、表の転置はアプリ側でやった方がよいと思う。
基本的に表の中の値(2009とか1とか)から列の名前(200901経費計)を
自動的に作ることは出来ないんだよね、標準SQLでは。
どうしてもSQLでやりたいときは、列の名前を全部手動で与えれば
こんな感じで出来る。
SELECT 会社, 部署,
SUM(CASE 年度=2009 AND 月=1 THEN 経費 ELSE 0 END) AS 200901経費計,
SUM(CASE 年度=2009 AND 月=2 THEN 経費 ELSE 0 END) AS 200902経費計,
...
FROM 経費TBL
GROUP BY 会社, 部署
>>12 select 会社,部署,
(select sum(経費) from 経費TBL where 会社=t.会社 and 部署=t.部署 and 年度=2009 and 月= 1) as 200901経費計,
(select sum(経費) from 経費TBL where 会社=t.会社 and 部署=t.部署 and 年度=2009 and 月= 2) as 200902経費計,
… ,
(select sum(経費) from 経費TBL where 会社=t.会社 and 部署=t.部署 and 年度=2010 and 月=12) as 201012経費計
from 経費TBL t
select id, info_date from t_information order by info_date desc; というクエリで、 +----+---------------------+ | id | info_date | +----+---------------------+ | 18 | 2011-03-03 17:00:00 | | 17 | 2011-03-03 15:00:00 | | 16 | 2011-03-01 10:00:00 | | 4 | 2011-01-13 14:00:00 | | 3 | 2011-01-13 07:00:00 | | 2 | 2011-01-13 03:00:00 | | 1 | 2011-01-13 00:00:00 | | 15 | 2011-01-12 00:00:00 | +----+---------------------+ というデータの場合に info_dateを基準に目的idの次のidを取得したいです。 例えば目的idが15とすると、1を取得したいです。 mysqlです。 よろしくおねがいします。
>>15 info_date がユニークでなかったら
どうなるのだろう。
>>15 とりあえず
select id from t_information where info_date=(
select min(info_date) from t_information where info_date > (
select info_date from t_information where id=目的id))
みたいなSQLで行けるような気がする
mysqlってオフセットるようなことできなかったっけ?
SQLの列の数可変はできないとの内容が
>>9 にありましたが、
ネットゲームのユーザー情報を管理するDBで、
テーブルに友達ユーザーのID情報(好きなだけ登録できる)を持たせようとした場合に、うまいやり方はないでしょうか?
つまり、以下のようにしたいわけですが…
create table users (
id varchar(255) primary key,
pass varchar(255),
name varchar(255),
friendId varchar(255)[], ← 複数人(数は不定)を登録したい
...以下続く...
);
私にはVARCHARで長い文字列を用意して、そこにIDを区切り文字";"とかの文字列で持たせるくらいしか思い浮かばないのですが、
あちこちでこういうパターンは生じていると思うので、何か定石があれば教えていただきたく存じます。
19 :
18 :2011/03/08(火) 21:24:23.51 ID:9nwKXqsM
失礼しました。DBMSはApache Derbyを利用しています。
friendId、外に持てばいいんじゃないの? ユーザ情報のテーブルに一緒に入れる必要はない
friendテーブル(user_idとfriendIdの組み合わせ)を作るのが定石
>>20 ,21
配列使えないかなとか、userごとにローカルfriendテーブルを作ったりできないのかなあとか、
そっちの方向でいろいろ調べておりました。
>friendテーブル(user_idとfriendIdの組み合わせ)を作るのが定石
この方法で行こうと思います。
どうもありがとうございました。
DBの勉強もしないでいきなりスキーマ設計始めるんだな・・・ 「思い浮かばない」じゃなくて、まずちゃんと教科書読もうよ。 どんな本にも必ず出てくるごくごく基本的な例なんだから。 「パターン」なんて格好いい話じゃなくて、プログラミングだと 長々とmain関数に全ての処理書いちゃったり変数が全部グローバル だったりする、そんぐらい基礎を無視している恥ずかしい話。
>配列使えないかなとか、userごとにローカルfriendテーブルを >作ったりできないのかなあとか ますます不安だ。
作りたい物に向かって進めばええねん
>>24 DBMSを限定していいのなら配列もありかもしれないし、
「userごとにローカルfriendテーブル」というのは言い回しこそ変だが、複合プライマリキーがそういう見方も出来はする
ので、別にまるで的外れな展開でもないよね。
ただ、
> 長い文字列を用意して、そこにIDを区切り文字";"とかの文字列で持たせる
これだけはだめだ。一番かかりやすいワナ。
不安感を覚えるならここに対して。
>>26 「userごとにローカルfriendテーブルを作ったり」はユーザごとに
create table firends_of_user123 ...みたいなテーブルを作るもの
だと解釈した。
配列にしても仮に有りであってもそれは「たまたま」であって理解
が伴っているとは思えん。バクチと一緒。
作りたいものに向かって進めば良いんだけれども、あまりに徒手空拳
だと一度落ち着いて基本も確認するべきだとも言いたくなる。
雰囲気的に「趣味でネットゲーム作ろうとしてるSQL初心者」だろうから、 試行錯誤で勉強すればいいんじゃね? いくらなんでも業務ではないだろ。 いずれにせよ、ちゃんとした書籍を一冊読むのが結果として 近道だとは思うけど。
本を1冊読まなくても、正規化についての知識を得ればテーブルレイアウトに失敗することはなくなるんじゃない?
しかしそのスレ、質問スレじゃなくて「語るスレ」だからなぁ。 一家言ありそうな連中が語り合っているばかりで、初心者が気軽に質問できるような 雰囲気じゃないという…。
プログラム板だと本物のガチ初心者スレがあるんだけどね。
勝手にルール作んなカス
>>18 皆さんがSQLのレベルの話でないと指摘されて
いるようにテーブル設計自体を見直すべきですね。
第一感として、つぎのようなバラバラの設計が
思い浮かぶようになれば、まずはよしです。
users_pass table
---------------
id | pass
users_name table
---------------
id | name
users_friend table
----------------
id | friend
以下必要な項目があればどんどんテーブルを
つくっていきます。
>>36 だって、そのレスにSQL一個も出てこないでしょ。
>>37 最初の質問の期待を裏切っているのだから、
>>36 で設計し直しの例を示し、その上で、
フィールドのタイプ等を決めてから create table
さらに出来上がったテーブルを join する方法を
示す。
質問に対する答え方はそういう順序でいいんじゃないか。
テキストサイズの長さ取得できないの? where text<10文字以下 みたいに 教えて
mysqlなら char_lengthで取得できる その前にDBMSの種類ぐらい書け、ヴぉけ
text = '' or text like '_' or text like '__' or ... or text like '_________'
my @a=$res->search({'char_length(body)'=>\'> 2'}); できましたありがとう ゴミクズ41 MySQLだよかす
よかったなハゲ
メタボ40子ね
なにこのほのぼのした罵倒し合い。タコ
そろそろやめよう。
SQLのIRCってないんですか? 全部質問にこたえてくれるIRC
49 :
NAME IS NULL :2011/03/10(木) 00:39:43.52 ID:Iqkyr0Hg
うずらに聞け。
50 :
NAME IS NULL :2011/03/10(木) 01:17:34.05 ID:g+CcDNnm
ORACLEなんですけど 内部結合なら INNER JOINとWHERE句とは全く同じですか? 外部結合の場合は、WHERE句の+付きとかでも出来ますけど 遅いとかその他デメリットとかありますでしょうか。
>>50 論理的には全く同じ。
実装的に異なるかは実際に実行計画をとって比較。
>>50 今後他のDBMS使う機会があるならWHERE句とか+なんかは使わないほうが幸せになれる。
え、 select * from a, b where a.id = b.id ってオラクル限定なの
いや全然。他のRDBMSでも普通に使える。 52が言うところの「幸せになれる」理由も興味あるところだけど。
+はともかくWHERE句は使うじゃろ WHERE句とON句は意味が違う
>>50 外部結合でwhereに結合条件をかくと、結合の順序を指定できないため
実行計画によって、結果が不定となることがある
と、どこかで見た
実例もどこかで見たんだが、俺にはその例が書けない
結果が不定って 実行するたびに結果が違うってこと? そんなDB使うなよw
+は方言なんで使わなくて良いのなら排除して良いのでは。 WHEREはよく分からん。WHEREも使うなってもしかして外部結合に 限った話をしているのかな。
WHERE句は外部結合のときに意味があるんですがな
内部結合のときや結合無しのときだって意味があるでしょう。
う〜ん、すまん、そうくるか ON句とは意味が違うんだよってことを言いたかったんじゃ
元々の質問は内部結合に関してなのでひとまず外部結合はおいておいて、 INNER JOINを外してON句に書かれていた条件をWHEREに移動して 違う評価結果が出てくる例はあるのだろうか。 名前参照のスコープ以外に特に違いは無いような気がするのだが。
WHERE句を評価する前にFROM句が評価される ONはFROM句に属するからWHERE句より先に評価される 内部結合では結果的には同じだが、意味は違うじゃろ 外部結合で試してみ すぐできるじゃろ?
結果が同じなのに意味が違う?それこそ意味不明。
結合する段階で、結合対象からはずす のと 結合したあとで、選択行からはずす 意味はちがうだろ 結果はどちらも同じく最終的な選択対象から外されるだけだが ただし、普通はオプティマイザが実行方法を決定するので 実際に内部の動作が指定した通りとは限らないが
実行方法を指定しているのに実際の動作は違うとか。 なんでそんな無理がある解釈しなきゃならんのだ。
SQLのSELECT文は宣言型だと何度言ったら。 SELECT文書いていて「実行方法を指定している」なんて思っている 方がおかしい。
10gのサンプルDBで試したが、 select * from EMPLOYEES A inner join JOB_HISTORY B on A.EMPLOYEE_ID = B.EMPLOYEE_ID select * from EMPLOYEES A, JOB_HISTORY B WHERE A.EMPLOYEE_ID = B.EMPLOYEE_ID 一字一句同じ実行計画が選ばれて当然結果も同じなんだが。 SELECT STATEMENT TABLE ACCESS BY INDEX ROWID JOB_HISTORY NESTED LOOPS TABLE ACCESS FULL EMPLOYEES INDEX RANGE SCAN JHIST_EMPLOYEE_IX "B"."EMPLOYEE_ID" = "A"."EMPLOYEE_ID" select * from EMPLOYEES A left outer join JOB_HISTORY B on A.EMPLOYEE_ID = B.EMPLOYEE_ID select * from EMPLOYEES A, JOB_HISTORY B WHERE A.EMPLOYEE_ID = B.EMPLOYEE_ID(+) 一字一句同じ実行計画が選ばれて当然結果も同じなんだが。 SELECT STATEMENT NESTED LOOPS OUTER TABLE ACCESS FULL EMPLOYEES TABLE ACCESS BY INDEX ROWID JOB_HISTORY INDEX RANGE SCAN JHIST_EMPLOYEE_IX "A"."EMPLOYEE_ID" = "B"."EMPLOYEE_ID"(+)
select * from EMPLOYEES A left outer join JOB_HISTORY B on A.EMPLOYEE_ID = B.EMPLOYEE_ID select * from EMPLOYEES A, JOB_HISTORY B WHERE A.EMPLOYEE_ID = B.EMPLOYEE_ID(+) 同じ意味のSQLだから同じで当然 select * from EMPLOYEES A left outer join JOB_HISTORY B on A.EMPLOYEE_ID = B.EMPLOYEE_ID and 'XXX' = B.XXX select * from EMPLOYEES A left outer join JOB_HISTORY B on A.EMPLOYEE_ID = B.EMPLOYEE_ID where 'XXX' = B.XXX もしくは select * from EMPLOYEES A, JOB_HISTORY B where A.EMPLOYEE_ID = B.EMPLOYEE_ID(+) and 'XXX' = B.XXX(+) select * from EMPLOYEES A, JOB_HISTORY B where A.EMPLOYEE_ID = B.EMPLOYEE_ID(+) and 'XXX' = B.XXX の違いだわさ
select * from a, b, c where a=b and b=c と書くよりも select * from a, b, c where a=b and b=c and c=a と書くほうがよいという話はあったが、 onとは異なるって話とはまた別だよね
別でしょ ORACLEで言えばルールベースの頃の話じゃね? 最近のコストベースはかしこい(本当か?)らしいから 上の書き方でもヨロシクやってくれるんじゃあるまいか どの道、実行計画を見て気にいらなければヒントだな
>>70 つまりon句からwhere句に結合条件を引っ張り出す時は外部結合の時は
必要なところに(+)を付けないと等価なクエリにならないって事でしょう?
そりゃそうだ。
>>69 もちゃんとそれをやっているから等価になっている
わけで。
>>70 の例だと1番目と3番目、2番目と4番目が等価。
残る謎は
>>52 のなぜWHERE句を使わない方が「幸せになれる」のかと
いう話と
>>56 の例。
それは……52と56に聞かなきゃわからないw
75 :
56 :2011/03/11(金) 11:14:57.41 ID:???
テーブルA,B,Cを外部結合する場合に AにBを結合したものにCを結合するのと、BとCを結合したものにAを結合するのとでは 結果が違うことがある って話だったはず で、from A,B,Cでは、どっち先に結合するかはSQLでは保障されていない joinは必要ならカッコつけて結合順序を指定できる、って話
76 :
NAME IS NULL :2011/03/15(火) 00:35:37.13 ID:Asew4UZz
副問い合わせ?を一回ですませたい OracleですがMySQLでもいいです SELECT * FROM hoge WHERE fuga > (SELECT fuga+5 FROM hoge WHERE id=1 ) AND fuga < (SELECT fuga+10 FROM hoge WHERE id=1 ) ↑をBETWEENにすると SELECT * FROM hoge WHERE fuga BETWEEN ( SELECT fuga+5 FROM hoge WHERE id=1 ) and ( SELECT fuga+10 FROM hoge WHERE id=1 ) となると思うのですが、これを SELECT * FROM hoge WHERE fuga BETWEEN ( SELECT fuga+5, fuga+10 FROM hoge WHERE id=1 ) みたいに簡単に書けないでしょうか。 上ふたつの書き方だと2回副問い合わせが走ってそうでおそくなる気がします。
>>76 実際にサブクエリが何回走るかはオプティマイザ次第
SELECT fuga+5 とかするより(SELECT fuga ...) + 5 とかやるほうが
オプティマイザが最適化しやすい気がする
どうしてもってなら、ホストアプリなりストアドなりで
fugaを取得するクエリと目的行を取得するクエリにわけたら?
その下のSQLが行けたとしても、最悪hogeの行数回サブクエリ走るって理解してるか?
(さすがにそこまでアホなオプティマイザは今は無いだろうけど)
要するに、 「hogeテーブルからfugaの値がid=1な行のfugaの値+5より大きくて +10よりは小さい行を選択」 という事かな。であればこんな感じ。 SELECT * FROM hoge A, (SELECT fuga FROM hoge WHERE id=1) B WHERE B.fuga + 5 < A.fuga AND B.fuga + 10 > A.fuga
あ、BETWEENか。であればこんな感じ。 SELECT * FROM hoge A, (SELECT fuga FROM hoge WHERE id=1) B WHERE A.fuga BETWEEN B.fuga + 5 AND B.fuga + 10
同じデータを保存したくないんですが
どうやればいいでしょうか?
Catalystにfind_or_new find_or_createっていうメソッドがあるんですが
それでHTMLタグの比較を行って重複してなければ保存したいんですが
</B><FONT size="2" >あほ </FONT>
</B><FONT size="2" >あほ </FONT>っていうのを比較して これは重複してるから保存かけたくないです
ですが、なんか長いタグとかでやると
"とか'とか>か、わかりませんが
DBIx::Class::Row::insert(): DBI Exception:
DBD::mysql::st execute failed: Duplicate entry
'<FONT COLOR="#FF6699">????????‡</FONT> <span class="mastermsg"> '
for key 'body' [for Statement "INSERT INTO chat ( body, date, ip,
name) VALUES ( ?, ?, ?, ? )" with ParamValues:
0="<FONT COLOR="#FF6699">????????‡</FONT>
<span class="mastermsg"> ?????“???Welcome to ????°―?\??????£????????† <a href="
http://www.okiraku-chat.com/vururu.shtml " target="_blank">
??―????????£??????????????£??U?????U???</a></span><br><span class="brawser">Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YTB730; GTB6.5; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
</span>
", 1="2011-03-19 22:46", 2="27.86.33.100", 3="?????†???"] at /var/www/Hello/script/../lib/Hello/Controller/Hello.pm line 93
っ手エラーがでます 比較してるときに"とかでエスケープされずに
" "aiue" " みたいになるからエラーがでてるんでしょうか?教えてください
SQL関係ない。
わからなくて死にそうです…教えてください
最初の1回目は保存出きるんです ですが2回め保存かけようとすると 上のエラーがでます やっぱり重複してないの比較するときエラーが出てるみたいです教えてください
スレ違いだって言ってんだろハゲ
教えてください
死ねハゲ
教えてやれよ かわいそう
ここは自分がわからないことがあると 死ねハゲとかいって逃げるんですか??? かすすぎますね^-^
教えてください 支援ありがとうございます忍者さん
嫌デス
うずらっていうやつはuzullaっていうひとですか?
92 :
NAME IS NULL :2011/03/23(水) 22:34:06.26 ID:SgTw27Um
環境はoracle9iです。 ■テーブルの構成 |年度|月|部署コード|商品コード|金額| ■テーブルの内容 |2010|01|AAA|001|1000| |2010|02|AAA|001|2000| |2010|01|AAA|001|3000| |2010|01|AAA|002|3000| |2010|02|BBB|003|4000| |2010|01|CCC|001|5000| |2010|03|CCC|001|6000| 上記のようなテーブルがあり、 これを年度,月,部署コード,商品コードでサマリした値を表示したいです。 と、ここまでなら上の4つでGROUP BYしてあげれば良いのですが、 そこに年度,部署コード,商品コードでサマリした 「累計金額」列を加える必要があります。(イメージは下記のとおりです。) ■抽出結果の構成 |年度|月|部署コード|商品コード|金額|累計金額| ■抽出結果の内容 |2010|01|AAA|001|4000|6000| |2010|02|AAA|001|2000|6000| |2010|02|BBB|003|4000|4000| |2010|01|CCC|001|5000|11000| |2010|03|CCC|001|6000|11000| GROUP BYと別の集計単位で列を作ることが可能か、 可能であればどのようなSQLを書くべきか、 というところを教えてください。
単純に考えるとサマリと元テーブルを結合すれば良いと思うんだけど、 それじゃない何かが欲しいってことだろうか。 ありそうといえばありそうで。
>>92 それ累計じゃなくてただの合計だと思うが、それでいいなら
それぞれ合計したものを結合するか、相関サブクエリで合計だけ求める
試してないけどこんな感じ
select t1.年度,t1.月,t1.部署コード,t1.商品コード,t1.金額,t2.累計金額 from (
select 年度,月,部署コード,商品コード,sum(金額) as 金額 from テーブル group by 年度,月,部署コード,商品コード) t1
join (
select 年度,部署コード,商品コード,sum(金額) as 累計金額 from テーブル group by 年度,部署コード,商品コード) t2
on t1.年度=t2.年度 and t1.部署コード=t2.部署コード and t1.商品コード=t2.商品コード
select 年度,月,部署コード,商品コード,sum(金額) as 金額,(
select sum(金額) from テーブル where 年度=t.年度 and 部署コード=t.部署コード and 商品コード=t.商品コード) as 累計金額
from テーブル t
ホントに累計ほしいなら、下のSQLでwhereに月<=t.月とかの条件付ければ行けるかと
>>92 素直に月別サマリと年度別サマリを求めて結合するのが良いと思うよ。
SELECT
A.年度, A.月, A.部署コード, A.商品コード, A.金額, B.累計金額
FROM
(SELECT 年度, 月, 部署コード, 商品コード, SUM(金額) AS 金額
FROM テーブル GROUP BY 年度, 月, 部署コード, 商品コード) A
INNER JOIN
(SELECT 年度, 部署コード, 商品コード, SUM(金額) AS 累計金額
FROM テーブル GROUP BY 年度, 部署コード, 商品コード) B
ON
A.年度 = B.年度 AND
A.部署コード = B.部署コード AND
A.商品コード = B.商品コード
>>93-95 ありがとうございます。
今環境が無いのですぐには試せませんが、
頂いた回答を元に後ほど試してみます!
97 :
NAME IS NULL :2011/03/27(日) 22:10:56.12 ID:hPnYPgA5
select * from table1 where col1 in (select colx, coly from table2); 的な書き方は無い? ↓ってするしかない? select * from table1 where col1 in (select colx from table2) or col1 in (select coly from table2) ;
select * from table1 where col1 in ( select colx from table2 union select coly from table2) とか inやめてexistsで相関サブクエリとかでもいけそう
existsだとこうかな。 select * from table1 where exists(select * from table2 where colx = col1 or coly = col2)
あ、col2はcol1の間違い (なかなかレベル上がらんな)
>>92 最近これ読んで勉強した俺が答えてやる
http://www.oracle.com/technetwork/jp/articles/otnj-sql-image3-1-323602-ja.html select 年度,月,部署コード,商品コード,
sum(金額),
sum(sum(金額)) over(partition by 年度,部署コード,商品コード)
from
group by 年度,月,部署コード,商品コード
>>101 SQLもここまでくると、もうおしまい。
よくある操作を最適化しやすい形で提供するってのはよいことだと思うけどなぁ。 個人的には配列型よりはいいと思う。
select aaa, sum(bbb) as total from hoge group by aaa having sum(bbb) > 10 というSQLがあるんですがsum(bbb)はひとつにできないものでしょうか? 例えば select aaa, sum(bbb) as total from hoge group by aaa having total > 10 と書ければいいのですが
ルール
ストアドプロシージャについて質問させてください。 簡単な結果を返すクエリ SELECT A,B,C FROM TEST といったクエリの結果を戻り値として返すストアドを作成したいのですが どのように書けば良いのかわかりません。 単一の列のみを返す方法ならわかったのですが、複数列を返す方法が 分からないといった状態です。
DBが何なのかぐらい書けよ…
レコード型
109 :
106 :2011/03/31(木) 08:49:46.44 ID:???
すいません。DBはOracle11gです。
以下のカラムでselect 文でid == 1、id2の最大値を取得したい場合どのように記述すればよいでしょうか? sql初心者でもうしわけありません id1(int), id2(int), val(text)
max
select id1,max(id2) from table where id1 = 1 group by id
ん?group byいる?
いらない
いる。正確にはgroup by id1だけど。
いらんじゃろ
id1も表示させようとするといるのでは? 1に決まってるから、 SELECT 1, max(id2) にしときゃいらん。
お!そういうことか
SQL初心者で申し訳ありませんが、以下のテーブルでid1を元に、val1とval2のデータを取得したいのですが どのようにselectをすればよいでしょうか? ・tabel1 int id1 int id2 text val1 ・table2 int id2 text val2
SELECT table1.id1, table1.val1, table2.val2 FROM table1 JOIN table2 ON table1.id2 = table2.id2 WHERE id1 = xxx とか? ON = は ON USING でもいいし、id1がtable1にあって2に無いものも出したいなら JOIN は LEFT OUTER JOIN にするとか
121 :
119 :2011/04/17(日) 18:04:27.65 ID:4pqUJmc9
>>120 ありがとうございますm(_ _)m
ためしてみます♪
さすがにこれは「教科書読め」レベルだろ・・・
教科書って何読めばいいの・・・?
使ってるRDBMSのマニュアル。
RDBMSってなんですか・・・?
>>125 単語くらいググれ。何のためにネット繋いでんだ。
128 :
126 :2011/04/18(月) 03:41:01.30 ID:???
>>127 なんでフレーズ検索が出来て、検索の基本が出来ないんだ……釣りじゃなかったらわけ分からんorz
まずお前は「何を」調べたいんだっつの。「RDMSってなんですか」を調べたいんじゃないだろ。『単語を調べろ』っつってんのになんで「RDMSってなんですか」を調べるんだよ。日本語的にもワケわかんねーよ。
もーSQLの質問ですらねぇし。
すみません、あなたが何を怒っているのかわかりません。 多分私のぐぐり方が悪いということでしょうか。 正しいぐぐり方ってどうやって調べればいいでしょうか。 「単語を調べろ」で検索?
あなたの日本語がわかりません 日本語で検索すれば良いですか?
律儀につられているなぁ
釣りじゃないという前提に立っても、初心者には判らないというかピンと来ない考え方は有るだろうな。 単に表の集合だけなら日常的に経験するが、リレーションなんて日常生活では意識しないだろうし。 あるいは新人がそこまでレベルが低下している、とか。
おまえつまらないから帰っていいよ
お言葉に甘えて帰って参りました。
136 :
NAME IS NULL :2011/04/18(月) 23:08:35.83 ID:0ZRRhV5X
ID
お世話になっています。 どのようなSQLになるか教えてください。 テーブルA テーブルB テーブルC E111,001,AR E111,001,AR E111,001,AR E111,001,AY E111,001,AY E111,001,AY E111,002,AR E111,003,AR E111,004,AR 上記のような同じキー項目(ID,番号,コード)を持つ3つのテーブルがあるとき、 E111,001,AR,E111,001,AR,E111,001,AR E111,001,AY,E111,001,AY,E111,001,AY E111,002,AR,'','','','','','' '','','',E111,003,AR,'','','' '','','','','','',E111,004,AR の形でレコードを取得するにはどのようなSQLになりますか? お願いします。
日本語でOK
>>137 試してないけど
select a.ID,a.番号,a.コード,b.ID,b.番号,b.コード,c.ID,c.番号,c.コード
from (
select ID,番号,コード from テーブルA union
select ID,番号,コード from テーブルB union
select ID,番号,コード from テーブルC ) t
left join テーブルA a on a.ID=t.ID and a.番号=t.番号 and a.コード=t.コード
left join テーブルB b on b.ID=t.ID and b.番号=t.番号 and b.コード=t.コード
left join テーブルC c on c.ID=t.ID and c.番号=t.番号 and c.コード=t.コード
で行けるかな
NULLじゃなくて''じゃないとダメだってなら
使ってるDBMSにそれ用の関数があるかと
SELECT 料理表.料理名 FROM 料理表, 分量表, 商品表 WHERE 料理表.料理ID = 分量表.料理ID AND 分量表.商品ID = 商品表.商品ID AND 商品表.商品名 = 'じゃがいも' これってどういう意味ですか? 料理表.料理ID の後に二つ 分量表.料理ID AND 分量表.商品ID = 商品表.商品ID AND 商品表.商品名 = 'じゃがいも' があるのですが、教えてくださいお願いします。
>>140 商品表に'じゃがいも'があるとして話だけど、
分量表と料理表にちゃんと登録されてるかなぁ。
ANDの意味が分からないのかな? WHERE (料理表.料理ID = 分量表.料理ID) AND (分量表.商品ID = 商品表.商品ID) AND (商品表.商品名 = 'じゃがいも')
143 :
141 :2011/04/19(火) 11:02:47.73 ID:???
ごめん。まちがえた。 商品表に'じゃがいも'があるとして話だけど、 分量表にも情報があって、料理表に載ってるじゃがいもを使う料理はなんだろう。 ですね。
144 :
140 :2011/04/19(火) 11:08:04.01 ID:???
>>143 まだ日本語おかしいから。「あるとして話だけど」って何
>>146 たしかに「の」が抜けてたね。それからシングルクォーツも外して。
りょーかい
多対多ってなんですか? ちょっと実感としてわきません わかりやすく教えてください
n対n
>>137 select * from テーブルA a full outer join テーブルB b on a.id = b.id and a.番号 = b.番号 and a.コード = b.コード
full outer join テーブルC c on a.id = c.id and a.番号 = c.番号 and a.コード = c.コード
153 :
NAME IS NULL :2011/04/21(木) 12:58:42.62 ID:Jk9Xx7Ye
超初心者ですいません。 postgreSQLで追記の書き方がわかりません。 項目(koumoku1)に「hogehoge」に「fugafuga」を加えようと update set koumoku1='fugafuga' where id='12345'; としたところ、 koumoku1が上書きされてしまい「fugafuga」となりました。 koumoku1に追記でhogehogefugafugaとするにはどのように したらよいでしょうか?
SET koumoku1 = koumoku1||'fugafuga' でどうか?
つーか、追記じゃなくて「文字の連結」とかで探せば すぐ見つかるはず。
かなの長音とハイフンぐらい使い分けろ デリカシーない奴はシステム開発に向いてない
余計なお世話だな
MySQLをインストールしてGUIで中身を編集しようと思ったんですが、 接続画面でユーザ名とパスワードとホスト名とポート番号を聞かれました。 どれも設定した記憶がないんですが、初期設定はなんなのでしょうか?
スレ違い
スレ違いかもしれませんが、他に良さ気なスレがなかったのでこちらで お尋ねします。SQLの実行速度についてなのですが 【やりたいこと】項目が ID,FLG (IDがインデックス)のテーブルで全てのFLGに1を入れたい場合 【知りたいこと】10万レコード中、99千件は既にFLGは1で、1千件が0で更新対象の場合 WHERE条件で絞り込んだ方がよいのか、絞り込まない方がよいのか、どちらが良いのでしょうか。
DBMSにもよるのかもしれないけど、変更対象レコードは少ない方がいいかと。
10万のうち1000しか更新しないなら俺なら絞る 9万9千件が更新対象でテーブル単位でロックして良いなら全件更新するかもしれんが
>>161 インデックスを解除して全件更新して、それから
インデックスの振りなおしでどうかということかな?
165 :
161 :2011/04/26(火) 22:26:45.17 ID:???
レスありがとうございました。 更新対象が少なそうなら絞るということでしょうか。 この「少なそう」で判断を迷うところです。 >164 インデックスは更新対象と違う項目に設定してあるので関係ないと 思うのですが・・・。違うかな。
とりあえずアナライザにでもかけたら? インデックスはってるんだから絞った方が速いと思うけど。
迷ったら絞れ 迷わないくらい常に範囲が大きい時くらいだな全件は
168 :
NAME IS NULL :2011/04/27(水) 11:41:16.89 ID:BkZlFd0B
SQLServer2008での質問です。 カーソルを宣言して、データを1行毎にリードしているのですが。 CURSOR宣言のSELECTにORDER BYをつけると、SELECT されたデータが2倍リードされます。 (SELECT結果は3行なのに6回FETCHループする) ORDER BYを外すと、3回ループに直るのですが、わけがわからないよ。 MSの不具合かなと思っているのですが、何か情報知っている方 いらっしゃいますか?よろしくお願いします。
>>165 同時実効性とかリソース消費とか考えないなら正直どうでもいい
どうでもいいといえば他人事なので正直どうでもいい
IDとFLGだけで10万件のテーブルでそ 全件更新して問題になるほど時間がかかるのかね
>>168 そんなことあるわけないと思うが
ソースさらしてSQL Serverのスレで聞け
>>171 誰かが1レコードでもロックしてたら終わりませんな
>>161 その条件ってのが、フラグの値みたいにそのレコード内で判断できてしまうものなら
絞らない理由はないだろう。普通は更新してログが書かれるコストの方が大きい。
一般的にディスクアクセス(特に書き込み)に時間がかかるわけだから絞るべきだが FLGにはインデックス張ってないんだろ?絞るのに時間がかかるかもな。
どっちにしろfull scanだとして、条件判断のコストより更新のコストの方が 大きいって話だろ。
情報が少ないが、ID FLGのみのテーブルで、FLGにインデックスを張ったとして、それが使われるとは到底思えないな。
where FLG = 0 ってことだからインデックスは使われるんじゃないかな
とりうる値はどうも0か1だけなんでしょ? そんな状態でインデックスを利用するDBMSなんてあるの?
とりうる値が何かはDBMSの知るところではないだろう インデックスを利用するかどうかはwhereの構文次第なんだから
うそだろ。本気じゃないよな。 インデックス使用コストを考慮しないオプティマイザがあるってこと?
ちょっと待て。今回の場合インデックスを利用する効果が無いと言いたいのか? 効果があるならDBMSも使うだろう。
インデックスの張り方さえ間違えなければいいと思う
二値フラグだったらそれこそビットマップインデックスとかじゃないと意味ないよなあ
そもそもFLGにインデックス張られてるとは書いてないが
>>178 実際の値が0と1で、とりうる範囲はもっと広いかもしれん
とりうる値が二つしかないような型で普通のインデックス張ったら
使われない可能性の方が高いと思うけど
>>179 今のオプティマイザはほとんどで、実際の値の分布をみる
>>180 ルールベースって考え方があってな
そういう動作やそういうモードがあるものもある
インデックスはったら検索が遅くなったなんてこともあったりする
>>181 10万のうちの1千だから使う効果はあるかもしれん
0/1の項目なんで無いかもしれん
結局は実行計画みないとわからん
なんにしても1千件検索のコストより9万9千件更新のコストの方が高いだろうと
IDとFlGだけなテーブルで10万件なんてフルスキャンしてもしれてる
そのために無駄な9万9千件のロックとログを許容する気には俺はならん
>>184 FLGにインデックスってのは
>>176 が仮定として言い出したことだから
> 今のオプティマイザはほとんどで、実際の値の分布をみる
そのオプティマイザとやらは、どのタイミングで実行されるの?
select * from table where FLG = 0 ってSQLが渡された時点?
optimize とかの命令を実施したとき?
あるいは常時FLGフィールドの値を監視していてindexを使うかどうかをあらかじめ決めてるのか?
クエリ実行前に統計情報を参照して実行計画を立てるのが多いと思う それが遅いだろってなる場合もあるので、プリペアも提供されてる場合が多いと思う
その統計情報で実際の値の分布を確認してるってことか
10万件舐めて10万件更新するのと、10万件舐めて10万件条件チェックして
1000件更新するのとでどっちが速いかってことだろ?
>>161 はインデックスが使われるかどうかを聞いてるわけじゃねーし。
もろもろを考慮すると、全件更新するのはダメってことだろ
190 :
NAME IS NULL :2011/04/30(土) 14:17:30.96 ID:K0JOb8yC
SQLiteでの事ですが、 id INTEGER RIMARY KEY AUTOINCREMENTから 編集不可能を取ったような項目は作れないでしょうか?
それを編集したいっていう動機がアレな場合が多いので、 ちゃんと理由も書いた方がいいかも
>>190 AUTOINCREMENT取ればいいんじゃね?
>>192 autoincrementされないんじゃね
194 :
NAME IS NULL :2011/05/01(日) 17:21:51.09 ID:c2D3mSjs
2chみたいな掲示板のアーカイブへの割り込み処理について質問です 例えば、レス番号1の投稿とレス番号2の投稿の間にあとから別の投稿を割り込ませたいとき、 番号のリフレッシュはどう処理したら良いでしょうか DBのカラムは スレッドのID/レス番号/投稿本文/投稿日時 という単純なものです 割り込みさせる記事が割り込み後に何番になるかは取得できるものとして、割り込み前の該当番号以降を全部+1させればいいわけですが、 単純にそれぞれupdateさせる方法だと数百回ループさせる可能性もあり得るので、もっと賢い方法はないかと悩んでいます mysql5を使っています 素人質問ですみません、アドバイスお願いします
どの段階での数百回ループを気にしているの?DB内部?それともアプリ?
196 :
NAME IS NULL :2011/05/02(月) 01:21:03.13 ID:av79Q5lS
>>195 アプリです
DBだけでループ処理ってできるんですか?
なにか僕の知らないmysql関数で一発で解決できたりしないかなと期待してるんですが…
それとも数百回のクエリなんて心配する必要ないですか?
そんなことないですよね…
>>196 普通に スレッドのID=スレッドのID+1 とやろうとすると
スレッドのIDが主キーだと重複したりするかもな。
198 :
197 :2011/05/02(月) 01:37:03.23 ID:???
おっと間違えた スレッドのIDが主キーでレス番号を変えるのか だったらレス番号=レス番号+1でいいような。
頻繁に発生するならテーブル設計をリンクリストみたいにしないとだめだろうね
mysqlだとupdateにorder byが使えるので
update テーブル set レス番号 = レス番号 + 1
where スレッドID = 対象スレッドID and レス番号 >= 割り込ませたいレス番号
order by レス番号 desc
参考:
http://dev.mysql.com/doc/refman/5.1/ja/update.html 一般的にやるなら、
1 レス番号の最大値を取得
2 更新対象のレス番号に最大レス番号 + 1を加える
3 対象レコードのレス番号から最大レス番号を引く
という3クエリになるのかな。
201 :
NAME IS NULL :2011/05/02(月) 12:30:51.24 ID:3MBlDbNK
てst
SQL SERVER 2008R2で質問です。 日付型系のSQLを書く際に Where YMD >= 'yyyy/mm/dd' And YMD <'yyyy/mm/dd' (YMDの列はDateやDateTime型で、実際にはyyyy/mm/ddには数値が入ります) このような場合、恐らく自動的にSQL SERVERが文字列を時刻に変換していると思います。 もし正式に書くとしたら CONVERT(datetime, 'yyyy/mm/dd', 111) このような形式でいいのでしょうか?それとも他に書き方があるのでしょうか? ACCESSとかだと#で囲んだら日付系とかの意味だった気がしますが、そのようなものはないのでしょうか? よろしくお願いします。
ないんじゃないかなぁ。あったかなぁ。 postgresqlだと '2011/5/2'::date という形で書けはするけれど標準じゃない気がする
>>200 そのorder byはどんな意味があるんだ?
普通そのupdateはorder byなしで通る
SQL文はアトミックに実行されるのが原則なので
その文の実行結果が制約に違反していなければ、更新の過程は考えなくていい
>>202 SQL Server固有の話はできればそのスレで
# mm/dd/yyyy # でできる
詳しくは日付リテラルあたりで検索しろ
PostgreSQLでもキー重複って言われた
RDBMSとして求められる実装は
>>204 のいうとおりなんだろうか
>>205 そのページみたけど、たしかにmysqlだとエラーがでるっぽいこと書いてるな
単一文の実行過程を考えて指示しないとエラーになるとかそれどうなのよと
>>206 SQL Serverは通った
PostgreSQLで、updateにorder by書いて回避とかできるのか?
>>208 ないからめんどくさいよ。
今回のはMySQLって最初から提示されてたから、order byつけた。
211 :
194 :2011/05/03(火) 21:57:51.76 ID:Z/iLu+ky
答えてくれた皆さんありがとうございました
パソコン使えない環境だったのでお礼遅れました、すみません。
>>200 さんの答えのorder by が理解できなかったんですが、それも他の人が
質問してくれててホント助かりました。
今までこんなorder by書いたことなかったです、勉強になりました。ありがとうございました
パソコン使えなくたって携帯からでも書き込みできるんだから言い訳にならんよ
SQL SERVER 2008R2で質問です。 ストアドプロシージャの引数に、ストアドファンクションの戻り値を使いたいのですが、 1文で記述するとエラーになります。 > EXEC @RC=ストアドプロシージャ名 1, 2, ストアドファンクション名(3) ← これだとエラー いったん、変数に入れてから渡せばうまくいくのですが、これを1文で書くのは無理なのでしょうか? > DECLARE @f float > > @f = ストアドファンクション名(3) > EXEC @RC=ストアドプロシージャ名 1, 2, @f ← これだとOK
スレ違い。確かダメなはず。
217 :
NAME IS NULL :2011/05/11(水) 11:51:55.06 ID:PqUfcrDV
タグのDBテーブルでの取り扱いと、タグとキーワード検索の関係を知りたいです たとえば本の情報を登録する以下のようなテーブル(t_book)があるとき、 id(int auto_increment 主キー)|bookname(text)|author(text)|description(text)|tag tagカラムはどんな型をとるのが正しいですか? イメージだと、複数のタグ(推理小説、時代小説、日本の作家、外国の作家、児童向け…)みたいな 複数のチェックボックスをチェック後送信するので、以下の2つの項目を満たしたいです 1)複数の値を入れられる型が良いです 2)ユーザーがタグを任意に追加できるようにしたいので、それにも対応したい SET型かなと思ったんですが、当初指定した値しか駄目っぽいので違うような気がします どんな形にして、その後のinsert, updateにはどう対応したら良いんでしょうか。 長くなりそうなので、続きます
218 :
217 :2011/05/11(水) 12:04:46.42 ID:PqUfcrDV
もう一つ、「タグとキーワード検索の関係」について質問させてください
>>217 のt_bookに登録するタグが専用のテーブル(t_tag)にリストされていて以下みたいな構造の時、
id(int, auto_increment, 主キー)|tag(text)
1|推理小説
2|時代小説
3|日本の作家
t_bookに登録するタグの値は、1,2,3..のidになるのが普通かなと思ったんですが、
それだと、サイト利用者のキーワード検索で「時代小説」のキーワードに引っかからない気がします
(最初の質問のtagカラムの形によるかもしれませんが)
こういう時はどうやって対処するんでしょうか。
1)キーワードをt_tagに検索する
2)あったら、そのidを取得
3)そのidをキーにt_bookを検索する。同時にキーワードそのものでt_book.descriptionも検索
こんな風に2回クエリするんでしょうか?
もしキーワードが2つ3つセットされてたら、ループまわして4回・6回クエリするんですか?
mysql5なんですが、素人なので想像できるのはこれが限界です。
もっと良いやり方あるんでしょうか。
そもそもt_book、t_tagの構造がおかしかったりしたら、それも指摘してもらえると嬉しいです
>>218 なんだか十分に判っていらっしゃるという感じがする。
私なら、t_bookからタグ情報は切り離し、
t_book_tagテーブル
----------------------------------
id (t_bookのid) | t_id (t_tagテーブルのid)
としますが。これならtagの見え方が重なっても大丈夫ですよね。
検索については、
>>218 のようなことにどうしてもなると思う。
220 :
217 :2011/05/11(水) 16:04:03.38 ID:???
>>219 おお! 各アイテムのタグ情報専用のテーブルを作るんですか!
全く思いつかなかったです、配列にしていれるのかなとか
配列を処理する関数がsqlにあるのかなとかド嵌りするところでした
ありがとうございました
>>220 配列が欲しいと思ったらテーブルを増やすサインだよ
222 :
217 :2011/05/11(水) 16:54:46.13 ID:???
>>221 なるほど、、本当にためになりました
どうもありがとう
本当にだめになりました
SQLで質問です。以下のSQLがどうしても上手くいきません。 (エラーはT.HINBANがORA-00904:無効な識別子です) SELECT ( SELECT T2.KEKKA FROM (SELECT 'OK' AS KEKKA FROM DUAL WHERE T.HINBAN = 'AAAAA') T2 ) FROM (SELECT 'AAAAA' AS HINBAN FROM DUAL) T 以下のようにすると上手くいくのですが、相関サブクエリする際の ネストの制限等があるのでしょうか? SELECT ( SELECT T2.KEKKA FROM (SELECT 'OK' AS KEKKA FROM DUAL ) T2 WHERE T.HINBAN = 'AAAAA' ) FROM (SELECT 'AAAAA' AS HINBAN FROM DUAL) T 可能ならば、前者の書き方でやりたいと考えています。 どなたかご教授いただければ幸いです。
省き方がおかしいから別の記述を提案できない状態になってるなぁ。 本題のT.HINBANがそこで使えない理由はわからないので、ごめん。
誰かエスパーはいないのか?
エスパーが欲しい場面だろうか
229 :
NAME IS NULL :2011/05/12(木) 23:17:45.84 ID:9xSjJwu3
unionとunion allの違いがわかりません
重複するかしないか
union jackとhi jackの違いがわかりません
233 :
224 :2011/05/13(金) 10:00:52.20 ID:???
>>225 >>226 分かりにくくて申し訳ない。
SELECTの部分のサブクエリは可変で変わるのだけれど、
その中の取得条件として、T.HINBANを使用したいという状態。
以下、書き直してみた・・・・・
234 :
224 :2011/05/13(金) 10:02:53.31 ID:???
●エラー SELECT ( SELECT T2.HINMEI FROM ( SELECT ST.HINMEI FROM (SELECT 'AAAAA' AS HINBAN, 'BBB' AS HINMEI FROM DUAL) ST WHERE T.HINBAN = ST.HINBAN /*可能ならここでデータを絞りたいがエラー(実際はJOINの条件)*/ ) T2 /*実際は複雑なサブクエリ*/ ) FROM (SELECT 'AAAAA' AS HINBAN FROM DUAL) T
235 :
224 :2011/05/13(金) 10:07:23.12 ID:???
●これなら一応動く SELECT ( SELECT T2.HINMEI FROM ( SELECT ST.HINBAN ,ST.HINMEI FROM (SELECT 'AAAAA' AS HINBAN, 'BBB' AS HINMEI FROM DUAL) ST ) T2 /*実際は複雑なサブクエリ*/ WHERE T.HINBAN = T2.HINBAN /*これならエラーは出ないが、パフォーマンスが落ちる*/ ) FROM (SELECT 'AAAAA' AS HINBAN FROM DUAL) T
いいたいことは元からわかるんだけど、元々のやりたいことがわからない テーブルで例出せないかな。 'AAAAA'は同じものなの?
まず日本語で必要なテーブル、列、条件を書いてみては。 そのSQLからだとわからん。
↓ではダメなの? SELECT ST.HINMEI FROM (SELECT 'AAAAA' AS HINBAN, 'BBB' AS HINMEI FROM DUAL) ST WHERE ST.HINBAN = (SELECT 'AAAAA' AS HINBAN FROM DUAL)
239 :
224 :2011/05/13(金) 18:39:18.13 ID:???
>>236 >>237 >>238 説明べたで申し訳ない。自分の説明の分かりにくさに絶望したorz
やりたいこととしては、
@ある複数のテーブルから条件で可変になるサブクエリで値を集計する必要がある。
→SELECTの部分のサブクエリ
T2にTもjoinしてそれをselectするだけでいけるんじゃねえのか 普通にjoinして絞れば良いだけだと思うんだがな
241 :
224 :2011/05/13(金) 19:37:57.41 ID:???
>>240 可変じゃなければそれでOKなんだけど・・・・・orz
242 :
224 :2011/05/13(金) 19:40:54.76 ID:???
と思ってたら、一応汚い方法だけど自己解決。 SELECT ( SELECT ( SELECT ST.HINMEI FROM (SELECT 'AAAAA' AS HINBAN, 'BBB' AS HINMEI FROM DUAL) ST WHERE T.HINBAN = ST.HINBAN /*なぜか、SELECTではエラーにならない*/ ) /*実際は複雑なサブクエリ*/ FROM DUAL ) FROM (SELECT 'AAAAA' AS HINBAN FROM DUAL) T
結局何をしたかったか伝えないまま終わるんだろうなぁ。
244 :
224 :2011/05/13(金) 21:51:45.78 ID:???
>>243 一応したかったことは、
@ある複数のテーブルから条件で可変になるサブクエリで値を集計する必要がある。
→実際のSQLではSELECTに指定してあるサブクエリがまるまる置き換える
Aその複数のテーブルにHINBANがあり、取得する対象のHINBANは、サブクエリの外で取得済みの品番
B
>>234 に書いた、FROMに指定したサブクエリの中のWHEREに条件を指定すると
エラーになり、上手く絞り込むことが出来なかった。
Cサブクエリを書く場所をSELECTにしたところ、希望通りの絞込みが出来た。
現状は、なぜFROMに指定したサブクエリの中のWHEREに条件を指定するとエラーになったのかが理解できない。
245 :
226 :2011/05/13(金) 22:30:58.94 ID:???
相変わらず、主題であるそのエラーの理由は俺もわからないけれど
どうも効率のよくなさそうに見えるその形にこだわる理由がわからないんだ。
>>236-238 >>240 なんかも、もっといい書き方があるんじゃないの?という意図が含まれてる気がする。
引き継いだ仕事のSQL文がこんなんだったら泣く。
だなぁ。 これだけ見ると無駄なことしてるにおいがしまくりで、とっととリファクタリングするわ
やりたいことを明確に表現できないってことは 本人にもやりたいことがちゃんとわかってないってことだな もともとのエラーは相関名の有効範囲の問題だけど そもそもselectをネストさせる必要性があるのかと
私はやりたいことを明確に説明している。 理解できないあなた方の脳(能)に問題があるのでは。
のどかな春でございます
煽りじゃないけど、本当に論理的に説明できてると思っているなら、もう一度文章を読み直してほしい。 普段の生活でも自分のいいたいことが理解されにくいことってないか? 少なくとも、テーブル定義と可変の条件を具体的に示すべきだろ。
本人なの?
253 :
NAME IS NULL :2011/05/14(土) 23:26:02.43 ID:JzTAMo2N
>>249 サブクエリの部分は検索条件が変わるので、サブクエリの箇所だけ
検索条件にあったクエリにその都度変更して、それ以外のクエリに関しては変更したくない。
なので、HINBANを取得するクエリはサブクエリの中には書きたくない。
ということなのかな?
だとすると、これじゃだめか?
Oracle Expressで実行
SQL> WITH T AS
2 (SELECT 'AAAAA' AS HINBAN FROM DUAL)
3 SELECT
4 T2.KEKKA
5 FROM
6 (SELECT 'OK' AS KEKKA
7 FROM DUAL,T
8 WHERE T.HINBAN = 'AAAAA') T2
9 /
KEKK
----
OK
SQL>
オライリージャパン SQLクックブックの34Pの下の方、間違いじゃないですか?
ここは市販書籍のサポートサイトではありません 質問があるなら疑問部分を具体的に引用して示してください
カラムA, B, Cがあり、次のような順序で抽出したいと考えています。 A B C ○ ○ ○ ○ ○ × ○ × × × ○ × × × ○ どのようにORDER BYを設定すればよいか、よろしければ教えて頂きたいと思います。 よろしくおねがいしますm(__)m
どんな順序だよw アタマの悪いオレでも理解できるように わかりやすく説明してください
258 :
256 :2011/05/16(月) 08:36:01.28 ID:???
すみません。 カラムA、B、Cがbool型だとして、 ABCすべてtrue ABがtrue Aのみtrue Bのみtrue Cのみtrue の順で抽出したいと考えています 最悪UNIONしようかと考えてますが、ORDER BYでいけるならそっちの方がすっきりするので、 教えて頂ければと思います。
order byでcase式を使えばいけるでそ
true<falseの順で普通にORDER BY書けば
まさかORDER BYで複数カラム使用できないとか思ってないよね
262 :
224 :2011/05/16(月) 09:50:16.03 ID:???
>>245-253 自宅のプロバイダからの書き込みが制限されていて返事が遅くなって申し訳ないです。
皆さん分かりにくい質問にお付き合いいただいてありがとうございました。
今度から質問するときは意図が伝わるよう、気をつけて質問したいと思います。
263 :
256 :2011/05/16(月) 10:20:29.40 ID:???
>>259 accessなのでcaseが使えないようです><
order by A, B, C でどうよ accessでbooleanにorder by使えるか知らんが
>>263 IIFで似たようなことはできる。
最悪標準モジュールに関数かいちゃえ
>>265 「最悪標準モジュール」って聞いたことないですけど、何でしょうか。
スレ違い。Accessスレでどうぞ。
268 :
256 :2011/05/17(火) 07:56:06.36 ID:???
>>260-261 普通に3つ並べて指定しただけだとうまくいかないなと思ってたんですが、
nullが混じってると並び順がおかしくなるようでした
>>265 IIF使ってnull対応したらうまくいきました
ありがとうございました
情報小出しにするなよ・・・nullがあるなんてw
ヌルっていやらしいよな。
ナルだと恐れ多いしな
ニュル
すっげぇお前の(ソースの)中 null null してんな
カップ麺にソースをぶち込むといいらいいよ
SQLite3です。 ある時点から、行の内容が変わったかどうか調べられるようにしたいです。 専用識別子列を作って(たとえばridとする)、 triggerを使い、 create trigger t1 before update on tbl begin update tbl set rid=random() where id=old.id; end; などとして、ridが変更されていないか比較する事は思いついたのですが、 若干処理が冗長な気もします。 なにか他により良い方法はありませんか? ※2^-64 の確率で重複するのは無視していいです
2^-64 の確率って何ですか
>>276 random()
が64bit整数で返すから、書き換えたのに、比較した際に同じ数値となってしまう確率ってことです
>>275 ridが変更されたかどうかはどうやって確認するの?
ridじゃなくて更新日時をセットすればいいんじゃない?
今までに見たことがない特殊な処理はたいてい間違いで、 ありふれた普通の処理が正しい事が多い。 これは俺様にしか思いつけないすごい処理だ、というのは間違いで 誰がやってもそうなるよね、というのが正しいことが多い。
あまり使われない機能であっても正しく仕様通りに利用するのであれば 間違いとか正しいとかは無いと思うが。むしろ正しい。
282 :
274 :2011/05/20(金) 00:42:47.25 ID:???
>>278-279 何で日時じゃダメだと思ったんでしょう…
それで全然おっけーっスね!!
ありがとうございました!!
283 :
275 :2011/05/20(金) 00:44:09.76 ID:???
>>284 情報ありがとうございます。是非参考にさせていただきます。
sql初心者で申し訳ありません。2つの要素でソートをしたい場合どのようにすればよいでしょうか? point01(int)、point02(int)があります。point01でソートを行い、point01が同じ場合point02でさらにソートをしなければいけません。
>>286 select *
from table
order by point01, point02;
288 :
NAME IS NULL :2011/05/25(水) 10:11:33.88 ID:hGVORej1
sqlite v3.6.23.1で、 comment (text) ,postedtime (int) という形式にて掲示板を作っているのですが、 「最新の5コメント、但し、24時間以内の投稿については最大50個まで」を求めたくて SELECT comment FROM mm ORDER BY postedtime DESC LIMIT 50 UNION SELECT comment FROM mm WHERE postedtime > $nowtime - 3600*24 ORDER BY ptime DESC LIMIT 50 としてみたのですが($nowtimeには今の時間を入れてます)、 1st ORDER BY term does not match in the result set というエラーが出ます。 (union前後のクエリそれぞれ単独ではエラーは出ません) 欲しい結果を求めるにはどのように書けばいいのでしょうか?
↑すみません 1)1行目の LIMIT 50 は LIMIT 5 の間違いです。 2)FROM mm の mm はこちらで作ったテーブル名です。適当に無視してください。
すみません。 2行目ORDER BY ptime は ORDER BY postedtime の間違いです。。
>>288 UNION 前後のクエリをそれぞれ括弧でくくる。
292 :
288 :2011/05/25(水) 10:44:21.18 ID:???
ありがとうございます。 括ってみたら、syntax error near "(" というエラーが出てしまいました・・・うーん
すみません。 SELECT comment の comment はこちらで作ったフィールド名です。適当に無視してください。
>>292 unionがうまく動作してないようだから、まずは単純なSQLをunionで連結して実行してみな
295 :
288 :2011/05/25(水) 15:19:00.58 ID:???
SELECT comment FROM mm WHERE postedtime < ある時間 UNION SELECT comment FROM mm WHERE postedtime > ある時間 これだと意図通りうまくいきました。 UNIONの前後のクエリを括弧でくくると先ほどの syntax error が出ます。 order by を入れると(前半、後半、どちらに入れても)288で書いたエラーが出て駄目みたいです・・・ sqliteの仕様かな?だとしたらしょうがないですね。
>>295 この書式はどう?
(select 〜) union (select 〜) order by 〜
怒られてる理由くらい
>>288 にも書いてあるし、そのくらいわかってるんじゃないの?
> order by を入れると(前半、後半、どちらに入れても)288で書いたエラーが出て駄目みたいです・・・ どう見ても分かってないだろ
上手くいかないので質問させてください。 ACCESS2007を使っています。 年フィールドと月フィールドを用いて「年度」の件数を抽出したいのですが、 以下のクエリでは月部分が干渉してか上手く抽出出来ません。 22年4月〜23年3月 といった結果を出したいのですがどうしたらよいでしょうか? SELECT 年 FROM Table1 WHERE (年>21 AND 月>3) AND (年<23 AND 月<4)
friend(id int, friend_id int, lv int) data(id int, datatext text, lv int default 0); friend.id=data.idになります。 friend.friend_idのキーにしてdata.lv <= friend.lvのデータをselectしたいのですが、方法がわかりません・・ ユーザ間のレベルで公開できるデータにフィルタをかけることをしたいと思います。 SQL使い始めて2週間の素人です。よろしくお願いしますm(_ _)m
302 :
291 :2011/05/25(水) 20:27:30.48 ID:???
>>292 初っぱなに(があってダメなのなら、
SELECT * FROM (
(サブクエリ) UNION (サブクエリ)
)AS T1;
とかしてみたらどぉ?
>>300 (年*100 + 月) between 2204 and 2303 、とか?
>>301 select data.* from friend left join data using (id) where data.lv <= friend.lv;
>>300 SELECT 年 FROM Table1 WHERE (年=22 AND 月>3) OR (年=23 AND 月<4);
>>301 意味がわかりそうで、よーわからんかった。
305 :
300 :2011/05/25(水) 20:42:15.13 ID:???
>>303 すみません、情報の提示が少なかったです。
年、月フィールド共にIntで、22年の抽出には年号フィールドというのがあり、
そちらで平成のフラグを立てます。
その場合、平成XX年YY月という形で行を拾うことが出来ます。
date型ではないため、恐らく頂いたレスのクエリでは上手くいかないっぽいです。
307 :
300 :2011/05/25(水) 21:44:24.95 ID:???
>>306 あ、ごめんなさい。こっちが勝手に勘違いしてました。
頂いたコード、動きました。ありがとうございます。
得られたデータの精査が必要ですがいける予感。感謝ですっ
308 :
288 :2011/05/25(水) 22:29:09.15 ID:???
>>296 (288の前) union (288の後ろ) order by postedtime desc;
で syntax error near "(" でした。括弧がないと 288 で出たエラーがでます。
>>297-298 エラーの意味はなんとなくはわかってたのですが、実際どう書けばいいのかがよくわかりません。
そのページは見てなかったので、考えてみます。
ありがとうございました。
309 :
288 :2011/05/25(水) 22:32:25.62 ID:???
最後に、 (288の前 union 288の後ろ) order by postedtime desc も syntax error near "("でした。
310 :
288 :2011/05/25(水) 22:51:05.41 ID:???
ごめんなさいもうひとつ。 ordey by postedtime なのに postedtime をセレクトしてないって意味かと思って、 2ヶ所のselect comment を select * に代えてみたいのですがやはりエラーでした。
>>310 そもそもどういう結果がほしいのかわからん。
>>311 欲しい結果は288に書いてあります。
ちなみに
>>297 で指摘されてるorder by は最後に一個だけ、だとすると、
「最新の5コメント」ってのが抜き出せないんですよね・・
313 :
288 :2011/05/25(水) 23:04:12.28 ID:???
「最新の5コメント、但し、24時間以内の投稿については最大50個まで」 の意図は(クエリの質問で必要かはわかりませんが一応答えると)、 「最新5個は(投稿日時がどんなに古くても)必ず表示する。 でも、書き込みが短期間に多数投稿された場合は最新50個まで表示したい」です。
だから288の説明が不十分、ってことを言ってるわけだが。 どこに最新の5コメントがあるのかもわからん。 とりあえず、Unionの後ろだけにして、あとはアプリで処理すれば? それが嫌なら(よくわからん仕様だけど)テンポラリテーブルに入れるとか。
315 :
288 :2011/05/25(水) 23:14:48.82 ID:???
あ、すみません。
>>288-290 としないとわからなかったですね。
改めて書き直すと
SELECT comment FROM db名 ORDER BY postedtime DESC LIMIT 5
UNION
SELECT comment FROM db名 WHERE postedtime > $nowtime - 3600*24 ORDER BY postedtime DESC LIMIT 50
です。最新の5コメントはunionの前部分です。
テンポラリテーブルについては考えていませんでした。考えてみます。ありがとう。
316 :
315 :2011/05/25(水) 23:31:44.01 ID:???
>>302 すみません見逃してました。
SELECT * FROM ( (315の前) union (315の後ろ) ) AS T1; だと
execute error : near "UNION": syntax errorDBD::SQLite::st execute failed:
というエラーでした。
あとは自分で考えてみます。
>>314 今はperl側で処理して実現はしてるんですけど、クエリで書きたくて質問しました。
では。
最新の50件抜いてきて、アプリで制御するのが早(速)そうではあるけれど。
あ、、、直前のレスも読めない大バカ野郎でごめんなさい。
だよね。
>>316 SELECT *
FROM (
SELECT 'comment1' as comment, 2 as postedtime
UNION ALL
SELECT 'comment2' as comment, 1 as postedtime ORDER BY postedtime DESC LIMIT 50
)
ORDER BY postedtime
321 :
320 :2011/05/25(水) 23:58:38.94 ID:???
ごめん下書き送信しちゃった これ使えないから無視して
SELECT * FROM (SELECT * FROM t WHERE 1=1/* 適当 */ ORDER BY postedtime DESC LIMIT 5) UNION SELECT * FROM (SELECT * FROM t ORDER BY postedtime DESC LIMIT 50) ORDER BY postedtime DESC こうかな? SQLite って (SELECT 1 as a) UNION (SELECT 2 as a); な書き方できないのね
>>322 ありがとうできました!
こう書けばいいのか・・・正解を見ればなるほどと思うのですがかけませんでした。
SELECT * FROM (315の前をSELECT * に変更したもの)
UNION
SELECT * FROM (315の後をSELECT * に変更したもの) ORDER BY postedtime DESC
ですね!ありがとうございました!
NAME FRUIT NUM TARO banana 10 TARO orange 4 TARO tomato 3 TARO grape 2 TARO apple 1 TARO melon 1 TARO mango 1 HANAKO tomato 30 HANAKO orange 21 HANAKO apple 2 HANAKO banana 1 GEN mango 12 GEN grape 6 GEN orange 4 GEN banana 1 GEN apple 1 というテーブルで、各人間の持つ果物のうち上位3種類を取得したいのですが、 どうすればよろしいでしょうか? 欲しい結果 NAME FRUIT NUM TARO banana 10 TARO orange 4 TARO tomato 3 HANAKO tomato 30 HANAKO orange 21 HANAKO apple 2 GEN mango 12 GEN grape 6 GEN orange 4 SQLserver2008です。よろしくお願いいたします。
えーっとねー、教えな〜い
>>324 select NAME,FRUIT,NUM from テーブル t
where
(select COUNT(*) from テーブル where NAME=t.NAME and NUM>t.NUM) < 3
>>326 それでどうやってできるのかわからないので解説してください。
>>327 各人間の持つ果物の上位3種類に絞り込んでる
まず順位付け select NAME,FRUIT,NUM,(select COUNT(*) from テーブル where NAME=t.NAME and NUM>t.NUM) as 順位 from テーブル t 上位3つ(これはエラー) select NAME,FRUIT,NUM,(select COUNT(*) from テーブル where NAME=t.NAME and NUM>t.NUM) as 順位 from テーブル t where 順位<3 エラーを解消するためにwhereに同じサブクエリ書く where (select COUNT(*) from テーブル where NAME=t.NAME and NUM>t.NUM)<3 で、結果リストに順位はいらないからselectから消すと出来上がり
330 :
324 :2011/05/26(木) 22:07:12.28 ID:???
>>326 ,329
丁寧な説明までありがとうございます。
参考にさせていただきます。
ほう、これはお見事。
primary keyの指定ですが、 列名に id int primary key と指定するのと 後から id int, primary key(id) と指定するのではどうも中身が違うっぽいんですが 別物なんでしょうか?
>>329 select COUNT(*) from テーブル where NAME=t.NAME and NUM>t.NUM
が何をやっているのかよくわかりません。(特にwhere句)
もう少し詳しく解説していただけないでしょうか。
うぜー、自分で試せよ。
自分と同じ名前で、自分よりNUMが大きいものの 件数を取得する NUMで順位付けするってことは、言いかえれば自分より大きいNUMが何行あるか この考え方がわかればあとは 単一値を取得するサブクエリ 相関サブクエリ の組み合わせ
>>335-336 相関サブクエリというんですか。勉強になります。
ありがとうございました。
PRIMARY KEYのIDをAUTO_INCREMENTで10000からはじめて、 50個適当にいれたら10050までになりますが、 ここで10000のIDをアップデートして20000にしたところ、 次のIDが20001からになりました。 一意は保たれていますがなんか不気味なので、 IDのアップデートを不可能(しかし削除は可能で他の列のアップデート可能) にしたいのですが、どういうSQLを書けばいいでしょうか?
339 :
NAME IS NULL :2011/05/27(金) 15:25:27.24 ID:SbaXSLRz
create table a ( id int primary key ); create table b ( id int, foreign key (id) references a(id) on update cascade on delete restrict ); insert into a (id) values (1); insert into b (id) values (1); update a set id=10 where id=1; select id from b; とやっても1になります。10にするにはどうしたらいいでしょうか? 逆(updateの対象をbにしてselectの対象をa)にしても変化はありませんでした。 使い方間違ってますか?
>>339 何のDBMS使ってるかは知らないけど、
まさかMySQLでストレージエンジンがMyISAMってオチじゃあないでしょね?
342 :
339 :2011/05/27(金) 18:00:31.58 ID:SbaXSLRz
>>341 ありがとうございます。
bのほうにはなぜかInnoDB指定できなかったのですが、
もう1度やりなおしたらうまくできました。
MySQLだと値もちゃんと変わってくれました。
ただ本命で使いたいSQLite3だとうまくいきません。
SQLite3の場合、PRAGMA foreign_keys = ON;を最初に指定、
型をintからintegerにしてテーブル名がaとbだとうまく作れなかったので
他の名前にしてますが、それ以外は同じです。
>>342 This pragma is a no-op within a transaction; foreign key constraint enforcement may only be enabled or disabled when there is no pending BEGIN or SAVEPOINT.
これにはひっかかってない?
344 :
342 :2011/05/27(金) 19:04:02.75 ID:SbaXSLRz
>>343 すみません。よくわかりませんでした。
実はPHPでSQLite3データベースを上記クエリで作成後、
FirefoxアドオンのSQlite Managerでアップデート処理をしていたのですが、
アップデート処理もPHP側で行ったら更新されていました。
不安が残りますが、一応できました。
>>344 それなら
>>343 っぽい気がする。
でも、後付けだらけだから、あなたがどんなに不安がろうとも原因は突き止められないと思う。ごめんね。
oracleで同じレコード結果を2行ずつ欲しいのだけど 同じ条件のSQL文をunion allする以外に方法ないですかね。 unionすると処理時間が単純に倍になりそうなので何とかしたいのですが 出力するときに2レコードずつ吐く、みたいなのは無理でしょうか。
>>346 union all 以外というなら
select ... from テーブル, (select 1 union select 2); とか?
早くはないと思う。
つーかアプリ側で何とかならんのか?
なんで2行必要なのかが理解できない. 本当に必要ならアプリで対処すればいい話だし.
MySQL 5.1 テーブル: no comment id(テーブル名:baka) 1 aaaaa unko 2 bbbbb tinko 3 ccccc unko 4 ddddd unko : 欲しい結果: no comment id count(*) 3 cccc unko 2 idがunkoのものの数を集計したく、 select *,count(*) from baka group by id where id = "unko"; でそれは可能なんですが、selectで取れる他の結果(commentとか)は、noが3のものを表示したいんです 上のクエリだと、ソート順で一番最後のものが「*」として出てしまいます どのように書けばできますでしょうか
>>349 欲しい結果は
3 ccccc unko 3
じゃないのか?
単純に考えると
SELECT * ,(SELECT COUNT(*) FROM baka WHERE id = 'unko') AS cnt FROM baka WHERE no = 3;
no=3と同じidを持つ行数とかなら
SELECT * ,(SELECT COUNT(*) FROM baka WHERE id = T1.id) AS cnt FROM baka AS T1 WHERE no = 3;
tinkoとかunkoとか下品な言葉を使うのは止めてください。
SQL ド初心者です table msg (msg_id int,send_user_id int, recv_user_id, msg text) table user (user_id int, user_name) send_user_id = user_id、recv_user_id = user_id の場合、 msg_idでselectしてsend、recvのユーザ名を取得したいのですがどのように書けばよいですか?
select s.user_name, r.user_name from msg join user s on (msg.send_user_id = s.user_id) join user r on (msg.recv_user_id = r.user_id) where msg_id = ...
354 :
NAME IS NULL :2011/06/03(金) 02:10:55.68 ID:OML0BTFg
table person( id,firstname,lastname,birthday) こんな感じのテーブルで、firstname,lastname,birthdayが同じ人を抽出したい場合、 どうすればよいのでしょうか?
select * from person p1 where exists (select * from person p2 where p1.id <> p2.id and p1.firstname = p2.firstname and p1.lastname = p2.lastname and p1.birthday = p2.birthday) とか select distinct p1.* from person p1 join person p2 where p1.id <> p2.id and p1.firstname = p2.firstname and p1.lastname = p2.lastname and p1.birthday = p2.birthday かなぁ
ありがとうございます。p1.id <> p2.idを思いつきませんでした。
p1.id !=! p2.id と p1.id =!= p2.id とはどう違うのでしょうか?
358 :
NAME IS NULL :2011/06/04(土) 23:38:44.88 ID:5WkPYOfy
初心者ですみません。 DB はアクセスです。 フィールドが日付,職員番号,仕事001,…仕事150と非常に多いDB で、 仕事001から仕事150の合計を得たいのですが、 簡潔な記述の仕方はありますか? Select 職員番号,日付,仕事001+…+仕事150 As 仕事合計 Where … というSQL を短く書きたいのですが。
ないです。
>>358 SQLは短くなりませんがプログラム側で工夫すれば簡潔になります
361 :
358 :2011/06/05(日) 07:07:28.61 ID:Z87yhScI
>359,360 レスありがとうございます。 やはりないんですね。残念。 Excel VBA からADO 接続しているので、 Select * Where …で抽出してVBA 側で集計しますね。
そんなテーブル設計にするほうがどうかしてる 仕事151以降を考慮する必要がない理由でもあるのかと
363 :
NAME IS NULL :2011/06/05(日) 21:05:46.32 ID:4AM1UX7A
SQL Plus を今まで使っていたのですが、 最近、MySQLを使う必要が出てきたのですが、 SQLの実行に適した便利なソフトはありますでしょうか?
スレ違い。
SQLスレでSQLの質問がスレ違いとはこれ如何に。
このスレは 「こういうことをやりたいんだけどSQLでどう書くの?」 「こういうSQLを書いたんだけどうまく動きません><」 などの質問を受け付けるスレです。 テンプレくらい嫁ハゲ
>>358 そんなクソテーブル、ビューをかませて見ないふりをしろ
>>366 そんなことテンプレのどこに書いてあるんだよハゲがw
table hoge (id00 int, id01 int) の場合id00からid01の最大値を求めたいのですがどのようにすればよいですか? 初心者です
371 :
370 :2011/06/06(月) 09:44:53.11 ID:???
補足 同じid00の中で最大値となるid01を求めるということです。
select id00,max(id01) from hoge group by id00
select max(id01) from hoge where id00 = xxx
374 :
370 :2011/06/06(月) 16:11:47.54 ID:???
>> 372,373 ありがとうございます。 正しく出力されましたm(_ _)m
レビューの平均を出したいと考えています こんなSQLです。 SELECT *,AVG(rating) AS average FROM review WHERE game_id = 1 このSQLですと、game_idでグループ化?されてしまいます。 そうならずに全てのgame_id = 1のデータを取得するにはどうすれば良いでしょうか?
テーブル構造がわからん。そこから説明プリーズ
>>375 複文を使わないならSQL2回発行すれば。
378 :
NAME IS NULL :2011/06/06(月) 23:34:43.26 ID:QJwN+Qol
>>375 SELECT
review2.*
,(
SELECT
review1.AVG(rating)
FROM
review AS review1
WHERE
review1.game_id = review2.game_id
) AS average
FROM
review AS review2
WHERE
review2.game_id = 1
こんな感じでできませんか?
当方初心者なため、うまく表現できない部分もありますが ご了承ください。 現在、DBを利用したウェブシステムを制作しています。 HTMLで制作したフォームより地名を入力するのですがその際 西川口・蕨 が何故か登録できません 西川口 と「・蕨」が省略されて登録されてしまいます。 ・ ←半角の中黒が問題かと思いましたが、例えば 所沢・狭山 は問題ありません、蕨・西川口も大丈夫でした。 色々試してみましたが ・蕨 上記の組み合わせが問題があるようです。 ググってもみましたが分からずじまいでした 解決方法があれば教えてください、よろしくお願い致します。
スレ違い。どうせ文字コードがらみとかそんなんだろうけど。
>>379 文字コードをUTF-8に統一してください
UTF-8は気持ち悪いので嫌いです。 日本人ならJISを使うべきなのではないでしょうか。
使えばいいじゃん。
私が使うかどうかではなく、皆さんの意見と賛同を求めているのです。
日本人に限らず好きなコードを使えばいいと思うが
386 :
NAME IS NULL :2011/06/11(土) 21:02:30.55 ID:mqQF5mSt
int(8)とmediumint(8)って何か違うんですか? Mysqlのテーブル作成文にあったんですが。
388 :
NAME IS NULL :2011/06/12(日) 15:15:02.22 ID:Koxl3/cZ
テーブルFOOにカラムHOGEが存在しない場合、timestamp型のカラムHOGEを追加し、 存在する場合は無視するSQLはどのように記述すればよいでしょうか? MySQL 5.0.77です。
追加、って何よ?
Mysql 5.1.49です。
Datatank.Datas
Id,Owner,Data,Flag
------------------
1,3,'foobar',TRUE
2,3,'hoge',FALSE
3,2,'moko',TRUE
Datatank.Owners
Id,Name,Mail
--------------------
1,'Negi','
[email protected] '
2,'Yod','
[email protected] '
3,'vav','
[email protected] '
のようなテーブル二種を想定します。
DatasテーブルのFlagが真の場合(ex.Id=1)、
そのレコードのOwner(3)をOwnerテーブルから検索してMail(vvvv@...)をリストするにはどうしたら良いでしょうか。
391 :
NAME IS NULL :2011/06/12(日) 15:28:42.12 ID:Koxl3/cZ
ALTER TABLE FOO ADD HOGE TIMESTAMP; で #1060 - Duplicate column name 'HOGE' となってしまうのです。 これを回避するためにIF NOT EXISTS指定できないかなとか 事前にカラムの有無を確認できないかなとか検証したものの うまく動かないため質問しました。
>>390 Datas.Owner と Owners.Idで結合すればいいだけだろ。
>>391 標準的なSQLじゃたぶん無理。普通にストアドとかでやれば?
>>391 そういう、結果が実行時に決定されるような動的なDDLは普通やらんけどな。
どうしてもやりたいならシステムカタログを見て追加するかしないか判断する。
ただHOGEを追加しただけなら、とにかく実行してエラーをキャッチして
無視してもいいんじゃねえの?
SQLでモンハンのスキルシミュ作ろうかなと思うんだけど、どうSQL書けばいいのかな?
はじめましてよろしくお願い致します。 現在商品サイトをつくろうとしてる新参でございます。 MYSQL+perlにて、商品データベースを構築し、順次カテゴリ別に商品を表示し、また別個に商品ページを生成する CGIまではなんとか形にすることが出来ました。 次のステップとしてサイト内検索を行いたいと思っているのですが、 その場合、商品データベースとは別にデータベースを構築し、サイトのHTMLなりからタグをはずした 文字データ、検索ID、リンク先を各カラムとしたテーブルをつくろうと考えております。 実際、こういう風に検索するやりかたは妥当なのでしょうか?他にもっと良いやり方はありますでしょうか? よろしくお願い致します。
設計スレにいきなはれ
・商品データベースを構築 ・別個に商品ページを生成するCGI ときて、 ・商品データベースとは別にデータベースを構築し、サイトのHTMLなりからタグをはずした文字データ となる流れに驚いたのでレスした次第です。
>>397 ちょっとのぞいてみます
>>398 そうですね・・・、変ですよね・・・
ただ、現在サイトの構築の流れがデータベースの構築、商品ページ製作、FLASHコンテンツ製作、カートCGI製作、商品管理GUI製作と並行してまして、飽きっぽいのでちょこちょこいろんなとこから手を付けてる次第です
どのみち手をつけるとこなのでこういう手法が一般的なのか伺った次第です
MySQLでtableAがあり、startというdatetime型のフィールドがあります。 すべてのレコードのstartを3日だけ後ろにずらしたいのですが、SQLだとどんな感じになりますでしょうか?
下記のようなユーザーに対する取得ポイントと、消費したポイントのテーブルがあり、 それらの合計を各ユーザー毎にまとめたいのですが、どうしたらいいでしょうか? [取得テーブル t1] id | user_id | point --+-------+----- 1 | 1 | 30 2 | 2 | 10 3 | 3 | 50 4 | 1 | 20 5 | 2 | 10 6 | 3 | 50 [消費テーブル t2] id | user_id | used_point --+-------+----- 1 | 1 | -10 2 | 2 | -10 3 | 4 | -50 4 | 1 | -20 5 | 4 | -10 <欲しい結果> user_id | point -------+----- 1 | 20 2 | 10 3 | 100 4 | -60 DBMSはMySQLです。 お願いしますm(_ _)m
403 :
NAME IS NULL :2011/06/14(火) 06:27:16.80 ID:xRChXcfU
下記のようなユーザーに対する取得ポイントと、消費したポイントのテーブルがあり、 それらの合計を各ユーザー毎にまとめたいのですが、どうしたらいいでしょうか? [取得テーブル t1] id | user_id | point --+-------+----- 1 | 1 | 30 2 | 2 | 10 3 | 3 | 50 4 | 1 | 20 5 | 2 | 10 6 | 3 | 50 [消費テーブル t2] id | user_id | used_point --+-------+----- 1 | 1 | -10 2 | 2 | -10 3 | 4 | -50 4 | 1 | -20 5 | 4 | -10 <欲しい結果> user_id | point -------+----- 1 | 20 2 | 10 3 | 100 4 | -60 DBMSはMySQLです。 お願いしますm(_ _)m
404 :
NAME IS NULL :2011/06/14(火) 06:28:16.56 ID:xRChXcfU
二重投稿してしまいました。ごめんなさい・・・
select user_id, sum(point) from ( select user_id, point from t1 union all select user_id, used_point from t2) t group by user_id
406 :
NAME IS NULL :2011/06/14(火) 08:38:32.30 ID:xRChXcfU
俺ならGroup byしてからJoinして、取得合計と利用合計をそれぞれ出すかな。
mysql ver5.0.77を使用しています utf-8で書かれたperlプログラムからアクセスし、文字データを登録していますが、なぜか文字化けします。 データベースのデフォルトの設定もutf-8なのになぜこんなことが起きるのでしょうか?
別物でしたか、失礼しました
MySQL 5.1.46 ≪item≫ ───────── id name category ───────── 1 Name1 2 2 Name2 1 3 Name3 1 4 Name4 6 5 Name5 4 6 Name6 8 7 Name7 2 8 Name8 2 ───────── item 内のデータについて、 category が 2 のものだけ category の値を 7 に振り替えたいと思い UPDATE item SET category = 7 WHERE category = 2 を発行したのですが、うまく動作しません。 こういう場合にうまくいく方法を教えてください。
>>411 [FROM テーブル名] がないからじゃないの?
UPDATE item SET category = 7
FROM item
WHERE category = 2
UPDATEやDELETEの場合まず同じWHERE条件のSELECT文を
つくって確認してからのほうがよい。
SELECT *
FROM item
WHERE category = 2
413 :
411 :2011/06/17(金) 09:44:36.54 ID:???
>>412 それを試したところうまくいかなかったのですが、
原因を調べていた所、変数の部分に問題がある事が判明しました。
UPDATEに関しては UPDATE table SET a = b WHERE x = y で合っていたようです。
コマンドから構文を打った所、問題なく更新されていました。
お手数おかけしました。
>>412 update に from table なんているのかよ
415 :
412 :2011/06/17(金) 21:47:18.29 ID:???
update文にfrom句が使えるのなんてSQL Serverぐらいじゃなかったっけ?
PostgreSQLもつかえるよ。便利だよね
どういう風に使うの?
>>418 UPDATE
**
SET
** = SELECT ** FROM **
って感じ。
それ
>>412 の書き方(update table 〜 from table)と関係ないじゃん
update対象のレコードの選択に他テーブルの条件を入れたい場合 通常は相関サブクエリを使う必要があるが、from句が使えるとそのまま joinできる、ってことだったかな。
サンクス、確かに便利そうだね。
setにも他のテーブルの内容が使える
MySQLです。 テーブル: User | Id | Nickname | Name | Sirname | Mailaddress +----+----------+-----------+---------+---------------+ | 1 | Binchou | Binchoutan |NULL | foobar| | 2 |brablabra-- | 3 |Mokutan | Mokutan |NULL|foobar| Response | Id | IssueId | UserId | MentionId | TStamp | Body | AlterBody | IPAddress | HostName | Deleted | UA | +----+---------+--------+-----------+---------------------+------------------+-----------+-----------+-----------+---------+------+ | 1 | 2 | 1 | 3 | 2011-06-21 23:12:01 | First TEST HERE! | Altered | localhost | Localhost | 0 | SQL | これらから、Response.Id,Issue.Id,User.Nickname(from Response.UserId),User.Nickname(from Response.MentionId) を得ようと思っています(つまりId->Nicknameの辞書解決)が、二つ以上のレコードを同じテーブルから結合する方法がわかりません。 別名をつけるとネットに書いてあったのですがいまいち書き方が分かりません。 御教授ください。
SELECT tres.Id, tres.IssueId, tu1.Nickname AS nn1, tu2.Nickname AS nn2 FROM Response AS tres, User AS tu1, User AS tu2 WHERE tres.Id = 1 AND tu1.Id = tres.UserId AND tu2.Id = tres.MentionId
>>425 ありがとうございます。
助かりました。
MySQL5を使っています。 テーブル登録のさい、 int(5)とかvarchar(20)とか書きますが、 これは最大値を指定しているわけですよね? 最小値はどうやって指定するのでしょうか? 例えば20文字までだけど、最低4文字以上にしてほしいといった、 パスワードみたいなものを保存する場合どうしたらいいでしょうか? プログラム側でもちろんチェックしますが、DB側でも2重にチェックしたいです。
>>427 一般的なRDBMSの機能としてcheck制約ってのがあって、簡単なチェックなら普通はそれで行う
check制約がサポートされてないDB(MySQLもたぶんそう)や、
check制約で制限できないような複雑な条件なら、トリガでチェックする
トリガもサポートされていないようなDBMSならDB側でチェックするのは無理じゃないかな
429 :
NAME IS NULL :2011/06/29(水) 20:26:05.65 ID:t/wutmkT
・DB2 v9.5 ・テーブルの内容 ■テーブル成績 名前,教科コード,点数 ========== Aさん,1,50 Aさん,2,70 Bさん,3,80 ■テーブル教科 教科コード,教科名 ========== 1,数学 2,国語 3,社会 ・欲しい結果 Aさん,数学,50 Aさん,国語,70 Aさん,社会,0 Bさん,数学,0 Bさん,国語,0 Bさん,社会,80 ・説明 どう結合したら目的の結果が得られるかわかりません。 おしえてくださいますでしょうか。
Bさんの数学と国語はどこから持ってくるんだよ・・・
あ。ないやつは 0 でいいのか。そしたら Outer join でいいな。
432 :
429 :2011/06/29(水) 22:53:00.14 ID:t/wutmkT
そうです。無いものは0点で結構です。 もちろん、Outer Joinは試してみました。 Full Outer Joinですかね。 select 名前, 教科, 点数 from 成績 Full Outer Join 教科 on 成績.教科コード = 教科.教科コード みたいな。しかし、0点となる行がどうしても生成できません。
433 :
429 :2011/06/29(水) 22:58:05.89 ID:???
あ、無いものは、0点というかNULLで結構です。
distinct 名前、なテーブル成績とテーブル教科を単純結合して、それとテーブル成績を外部結合すればいい。
生徒マスタみたいなマスタがないんで、まずそれを成績テーブルから生成 それと教科の直積をとって、そのうえで成績を外部結合、でできるはず select t.名前,教科.教科名,成績.点数 from (select distinct 名前 from 成績 ) t cross join 教科 left join 成績 on 成績.名前=t.名前 and 成績.教科コード=教科.教科コード こんな感じで行けるかと
436 :
429 :2011/06/30(木) 00:06:15.85 ID:???
!ありがとうございます。 それだ、cross join です。 助かりました。
[ユーザー] id | name --+------- 1 | hage 2 | fuge … … [タグ] user_id | name --+-------+----- 1 | 1 | A 2 | 1 | F 3 | 1 | G 4 | 2 | A 5 | 2 | H … … というテーブルから、 [ [ 1, hage, [ A, F, G, ], ], [ 2, fuge, [ A, H, ], ], ] こんな形で、多次元配列な結果を得たいんですが、 ループでユーザーテーブルのレコード数だけSQL発行するしかないんでしょうか? レコード数に比例して時間がかかってよくないので、速く処理する方法はないでしょうか?
ユーザーに対してタグが0のときは[]になるの?
>>437 それSQLの問題じゃないし
使ってる言語のスレ行け
SQLが使えればコントロールブレイク処理はいらなくなったと思ったら、
Beanに詰め替えるときに使うね。
なんかあほらしい処理のような気もするけど。
コントロールブレイク処理はいつも最後の行でブレイクするかどうかで悩むな。
>>437 は[タグ]にユーザーごとの明細番号があれば降順に並べて1のときにブレイクする
で簡単だけどね。
id 1 2 3 5 9 10 ... のようなテーブルがあって、id を "1-3,5,9-10" のように取り出すことはできますか? GROUP_CONCAT で1つずつカンマで連結するこはできるのですが。
プログラム側でやれば簡単だろ
>>437 XML オプションというものがあってだな。
言語でXML食えばいいだろ。
Alter で ADD, CHANGE, DROP などを表す用語というのはありますか? DDL, DCL, DMLみたいな。カラムとかクエリーとか。 ちなみに、SHOWはDMLでいいんでしょうか?
>>444 何が聞きたいのかいまいち解らん
DDL,DCL,DMLってのはSQL文の種類を表す用語なんだが
ADDとかは文じゃないぞ
Alter何とか文はたぶんほとんどDDLだと思うけど
SHOWはSQLですらないぞ
>>445 聞き方が悪くてすみません。
Alterで使うADD、CHANGE、DROPについて、まとめて表す単語があるのか聞きたかったのです。
なさそうだとは思ったんですが。
SHOWの話は、上とは関係なく、SHOWが何に含まれるのか聞きたかったんです。
SHOWはSQL文じゃなかったんですね。
CURD
CRUD?
CLOUD
COLD!
MySQL, PostgreSQL, SQLite, Oracleなど、を総称しようと思うとなんという表現がいいでしょうか? 製品でProductかな?と思ったのですが、他によい表現方法はありますか?
RDB
rdbms
DB
など・・・他にもあるのならDBMS
456 :
NAME IS NULL :2011/07/03(日) 13:29:14.92 ID:1qP9M50H
1つのテーブルの全てのカラムから特定のワードを検索する処理はどうかけばいいでしょうか?
ひとつのカラムに対するやつをすべてのカラムに対して書けばいいです。 つーか、全文検索でやる話なので、SQL向きじゃないです。
>>456 どんな状況でそんなクエリが必要になるのか
459 :
NAME IS NULL :2011/07/03(日) 23:27:29.95 ID:09fD2WDi
次の条件を満たす任意対象のデータベースを設計してみてください。 @ジョイン可能な3つのスキーマを含むこと. Aそれぞれのスキーマに対して1つ以上の関数従属性を持つこと. その結果を以下のような構成で報告する。 1.データベース設計 1.1 ER図 1.2 スキーマ定義とドメイン制約 1.3 各リレーション別に関数従属性,多値従属性(関数従属性以外) 1.4 各リレーション別に候補キーの算出 1.5 各リレーション別に第3正規形判定と分解 1.6 各リレーション別に外部キーの説明 2.データベース応用(select文とその意味) 2.1 応用その1(1つの表のみを用いる応用) 2.2 応用その2(2つの表をジョイン(等号結合)して用いる応用) 2.3 応用その3(3つの表をジョイン(等号結合)して用いる応用) 2.4 応用その4(group-byを用いる応用) 2.5 応用その5(havingを用いる応用
>>459 「設計してみてください」ってそれ質問じゃないよね
>>459 何しに来たかは知らないが、宿題か?
趣旨が良くわからないのだが。
趣旨は質問です。
ていうか、
>>459 読んで理解できない人は余計な回答してくれないくていいです。
消えな
設計スレへどうぞ。
スレ違いにも気がつかずにどうどうと
>>463 みたいなこと
書くのってどうなんだw
>>466 どこのスレだろうと質問の内容から即座にどんな人間か判断できるな
いや、回答の内容から回答者のレベルがすぐに判断できます。
次の方どうぞー。
前の方、戻っていらっしゃい。
hoge varchar と hoge varchar default null ってどう違いがあるんですか?
DBMSによるかもしれんが、実用上同じ 明示的にデフォルト値を指定してるかどうかだけ
473 :
471 :2011/07/05(火) 23:33:12.86 ID:???
ありがとうございます よく明示的に書いてる人がいるので不思議でしたが 差はないんですね
自分で default null って書いてなくても Mysqlの show create table なんかで見ると勝手に default null って書かれてることあるな。 そういうのをコピペしたのかもね。
すばらしい親切設計
476 :
NAME IS NULL :2011/07/06(水) 16:03:36.49 ID:aHtztaXF
はじめまして。 SQL SERVER 2008 R2 のビューの機能を用いてSQL文を生成しようとしています。 しかし、 複雑なテーブルを関連付けているからか、ビュー上で生成SQL文を実行をしたときに、 「SQLの実行エラーです。 … エラーソース:.Net SqlClient Data Provider … エラーメッセージ :タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 というエラーになってしまいます。 どこかで、この「タイムアウト時間」を延長することはできませんでしょうか。 または、このエラーを回避する方法はありませんでしょうか。 検索で調べてみましたが、見つけることができませんでした。 よろしくお願いいたします。 ちなみに、サーバーはレンタルサーバーのSQLを使用しています。
timeoutが原因じゃないときにtimeoutを伸ばすと時間の無駄だよ
・DBMS名とバージョン SQL一般 ・テーブルデータ 回覧データ ・欲しい結果 職員のべ数が、ビット数を越えても耐えうる構造 ・説明 回覧データを職員が確認したかどうかを、回覧データ側へ記載しようと int(64bit)型で、ビットをオンオフする方法を考えましたが これでは、職員の延べ人数が64人を越える可能性に対応できません こういう情報は、一般的にどのように扱いますでしょうか? - [職員ID] [回覧データID] の別テーブル? - 文字列をビット代わりに利用?
int(64)型を二つで128人に対応
>- [職員ID] [回覧データID] の別テーブル? こっちだろ。 特に、職員『のべ』数なんて言うなら。 回覧ID(適切な型) 職員ID(適切な型) 既読/未読 (booleanか極力小さい整数) (付けたければ)日付 つかこれ、設計スレの領分じゃない?
全校学生健康診断表で 身長の高い人50人を選ぶ場合 select 学生ID, 学生名, 学生身長 from 健康診断表 order by 学生身長 desc limit 50 とかでいいと思いますが その次の50人を選ぶ場合はどうしたらいいのでしょうか?
それでいいなら offset 使えばいい。 まあ大雑把でいいんだよね?
って RDBMSによるのか、、 何使ってるか書くか、当該のマニュアル見るかだな。 同じ数値の人が境界線上にあった場合、状況によっては、、とかあるけどな
全校学生健康診断表で 胸囲の大きい女子50人を選ぶ場合 select 女子ID, 女子名, 女子胸囲 from 健康診断表 order by 女子胸囲 desc limit 50 とかでいいと思いますが ペチャパイの50人を選ぶ場合はどうしたらいいのでしょうか?
descしなきゃいいだろ。
ペチャパイdesってるんじゃねえよ
胸囲だけで選んじゃ駄目だと思うの。 カップが大事。
select 女子ID, 女子名, 女子胸囲-女子アンダー as 女子カップ from 健康診断表 order by 女子カップ desc limit 50
491 :
NAME IS NULL :2011/07/08(金) 09:43:21.14 ID:nVms0sQv
まずは情報取得のための検査、ぜひお手伝いさせて頂きたい
仮にでぶちゃんだとしても胸囲でかい娘は胸もある
カップの小さいブタはただのブタ
カップでかくてもやっぱブタ
適度の大きさがベスト
ブタはいりません
おまえらときたら…
俺は豚大好きだからもらっとく
ブタは美味いよね
ブタの美味い食し方 @ブタの脳髄の酢味噌和え Aブタの睾丸の天麩羅 Bブタの脾臓の卵巣詰め燻製
select username from userinfo where userid=10; select eventid, event, eventdate from logtable where userid=10; みたいな2つのSQLを使って今結果を取得しています。 上のselectは1つしか取り出していませんが、 こういう場合でも結合を行ってから取り出したほうがいいのでしょうか? 今の場合結果は、 name 山田 eventid 1, event "山田がログインしました", eventdate "2011-07-09 20:00:00" eventid 2, event "山田がログアウトしました", eventdate "2011-07-09 20::30:00" こんな感じですが結合したら、 username "山田", eventid 1, event "山田がログインしました", eventdate "2011-07-09 20:00:00" username "山田", eventid 2, event "山田がログアウトしました", eventdate "2011-07-09 20::30:00" になり、usernameは1個しか必要ないので、プログラム側では、 1回目のループのみusernameを取り出すような処理が必要になってきます。 こういうケースでもSQLを1回ですましたほうがいいのでしょうか? もしすましたほうがいい場合、どんなSQLを出せばいいでしょうか? 結合はいっぱいあってよくわかりません。
>>501 username を取得するのはログイン処理(または継続セッション処理)のときなので
基本的にページごとに必ず取得するのが普通。
logtable を参照るのはログ情報を表示するページだけなので、username の取得と同時に行う必要はない。
結合したければすればいいが。
select 〜 form userinfo left join logtable where userid=10;
503 :
501 :2011/07/10(日) 21:27:42.13 ID:???
>>502 レスありがとうございます。
今回の場合、ユーザの行動追跡に管理者がログを見る場合を想定しています。
どのみちどちらでもよいということでしょうか?
left joinということは結合する場合外部結合ですね。
この場合はinner joinでもいいよ。
・DBMS名とバージョン SQLite ・DBに入っているテーブルデータ ID DATA 1 aaa 2 bbb 3 ccc 4 ddd 5 ccc 手持ちのデータ aaa、bbb、ddd ・欲しい結果 テーブルデータと手持ちのデータを比較して、 手持ちのデータに存在しないデータを持つテーブルデータの行(ID3とID5)を削除したいのですが、 どこのように書けばよいでしょうか
not in じゃだめなん?
>>506 ありがとうございます。NOT INでできそうです。勉強不足でした・・・
SqlServeの datetime型に 生年月日が入っています。 これを今年の誕生日にするにはどうすればいいでしょうか。 2/29は3/1にするとして。
俺ならアプリ側でやるわ。
510 :
508 :2011/07/12(火) 11:12:50.12 ID:???
めんどくさくて遅い気がするので、mmddの計算列かなぁ。 今日と比べれば 2/29も 3/1処理でよければいいし。
>>10 みたいなことがしたいのですけど、カレンダーテーブルって
日付だけ、だーって100年分くらいあるテーブルがあればいいんでしょうか?
いいけど本当に100年分必要なの?
カレンダーテーブル作って何に使うの? 日付生成するだけならプログラム側でやれ。
データにはまだ20年分くらいしかないので、必要ないといえば必要ないのでしょうが なんとなく、3万とか4万くらいなら平気かなーと甘い考えで・・・ その辺含めて普通どうするのか、お聞きしたいです
休日DBがほしい
休日DB何に使うの? 日付生成するだけならプログラム側でやれ。
祝日なら国ごと、地域ごとに違うし、 毎年日付が変わることもあるから DBに入れとくといいかもな。
generate_series()みたいなのがどのDBでも使えればいいのにね 海外でもこの手の話は再帰使ってお茶を濁してる
520 :
NAME IS NULL :2011/07/12(火) 17:33:41.54 ID:qRLbKdSL
SQLiteを使っています。 顧客A(顧客idは100)さんの最新の購入物を表示したいのですが、 select 顧客.顧客名, 購入物.顧客名 from 顧客 natural join 購入物 where 顧客id=100 order by 購入日 desc limit 1; っていま書いていますが、無駄が多い気がします。 これを手直していただきたいのですが、よろしくお願いします。
>>520 > select 顧客.顧客名, 購入物.顧客名
顧客名しか表示してないじゃねぇかw
522 :
520 :2011/07/12(火) 17:36:14.82 ID:???
すみませんミスりました 購入物ではなく購入履歴ですね。 select 顧客.顧客名, 購入履歴.商品名 from 顧客 natural join 購入履歴 where 顧客id=100 order by 購入日 desc limit 1; こんなかんじです。
>>522 それでいいんじゃね?
つーかテーブル構造もわからんのに答えられるかボケw
524 :
520 :2011/07/12(火) 17:42:35.19 ID:???
>>523 そうですね。すみません。
顧客テーブルには顧客に関する色々な情報が入っています。ざっと10個ぐらい。
顧客id,名前,住所,電話番号とかそんなかんじのものです。
購入履歴テーブルには識別できるように顧客idと他には履歴id,商品名,購入個数,購入日がunixタイム形式で入っています。
limitはいるの?
というか、同じ日に2つ以上買った場合1件表示でいいの?
おまいらやさしいな
532 :
忍法帖【Lv=19,xxxPT】 :2011/07/13(水) 16:47:31.08 ID:KfBk5ER8
データベースはSQLiteです。 selectした値からさらに何か処理をしたものを表示したいです。 例えば select number from xxx where hoge='piyo' で xxx.number 1 2 3 という3つの結果が返ってくるとして、 さらにこの返ってきた結果たちを引数の一部として関数を適用した値を取得したいです。 例えばString型の引数をとるmoge()という関数があったとして、 moge('foo1'); moge('foo2'); moge('foo3'); (1〜3のところは取得した結果) を適用した結果を取得したいです。 上記のxxx.numberの結果を取得後に、 個別にselect moge('fooN')すれば結果は得られますが、1発で出来ないでしょうか? 難しそうですがよろしくお願いします。
533 :
忍法帖【Lv=19,xxxPT】 532 :2011/07/13(水) 19:07:00.56 ID:KfBk5ER8
文字列結合で自己解決しました。 スレ汚しすみません。
535 :
NAME IS NULL :2011/07/13(水) 21:13:37.00 ID:r6hg4PNa
関連性がないけど取得したデータ型が同じ2つのSELECT文を結合させるにはどうしたらいいでしょうか? SELECT 1 SELECT int_column AS A, timestamp_column AS B FROM table1 A B 10 2011-07-11 SELECT 2 SELECT int_column AS A timestamp_column AS B FROM table2 A B 5 2011-07-10 10 2011-07-13 これをA-Bの順番にソートして A B 5 2011-07-10 10 2011-07-11 10 2011-07-13 こんな感じの1つのテーブルにしたいのですが、よろしくお願いします。
union すればいいだけだと思うが...。
537 :
535 :2011/07/13(水) 23:00:40.51 ID:???
>>536 おーありがとうございます。
お陰様でできました。
unionとはまたイカス名前ですね
select *, tableid=1 from test みたいに全てのカラムに加えてtableid=1を加えたものを取得したいのですが どういうSQLかけばいいのでしょう? *はidとnameが入ってるとしたらこんな感じのものを期待してます ++++++++++++++++++++ + id + name + .tableid .+ ++++++++++++++++++++ + 1 .+ .加藤 + 1 + ++++++++++++++++++++ + 2 .+ .伊藤 + 1 + ++++++++++++++++++++ + 3 .+ .佐藤 + 1 + ++++++++++++++++++++
select *,1 as tableid from test でいけるんじゃないかな
540 :
538 :2011/07/14(木) 01:19:36.93 ID:???
>>539 お早いレスありがとうございます
早速試したところ正常に動作しました
どうもありがとうございました
>>540 SQLで無駄なことするなよ、そんなのプログラム側で対応すべき事だろうに。
俺はSQLで出来ることはSQLでやれって教わったけどね
断片だけみて断言する神経は理解できない
>>542 いや、1 as tableid なんて明らかに無駄だろw
場合による
>>547 は
>>546 の返事?じゃないよな
だってプログラムじゃ無理・無駄が多すぎてバカな実装になる
>>545 のレスだよ。アンカー付けるか書き込む前にリロードすべきだったな
>>546 無駄だと言ってるのは例示された「1 as tableid」に限定してる
>>543 の伏線があるなかで無駄wとか釣られるのは明らかにわかってないだろ
例示は例に過ぎないわけで実際の中身がどうかなんてわからないだろうに
プログラムから使うとか一切書いてないのにプログラム側で対応するとか 自分のテリトリーに持ってきすぎ インラインビューとかもプログラムするのかね
Aテーブルの同じidの情報unkをBテーブルの情報で上書きしたいときとか select * from (select id, unk, 0 as tid from a union select id, unk 1 as tid from b order by tid) group by id とかやっちゃうけどおかしいですか?
>>554 order byの意味するところがわからない
>>555 ごめんなさい
group byするのはunkでした
ちょっと待ってください とてもわかりにくかったので 実際にテーブル用意してみます
create table aaa ( id integer not null, test text not null, test2 integer not null, unique (id,test) ); create table bbb ( id integer not null, test text not null, test2 integer not null unique (id,test) ); aaa id test test2 10 aaa 100 10 bbb 200 10 ccc 100 10 ddd 100 bbb id test test2 10 aaa 200 10 bbb 100 ほしい結果 id test test2 10 aaa 200 10 bbb 100 10 ccc 100 10 ddd 100
>>558 は
select * from(select id, test, test2, 0 as tb from aaa union select id, test, test2, 1 as tb from bbb order by tb) group by test
でとれます
自分でもかなりトリッキーかなとは思ってるのですが
よくないですかね?
MySQL限定? もし仕事でやっているんだとしたら、ちゃんと基本から勉強しといたほうがいいぞ。
561 :
558 :2011/07/14(木) 23:42:25.72 ID:???
>>560 MySQLとSQLiteで動いてほしいです
>もし仕事でやっているんだとしたら、ちゃんと基本から勉強しといたほうがいいぞ。
そうですねーとりあえず山超えたらゆっくり勉強したいです
aaaとbbbを別々にとってプログラム側でマージしたほうが楽な気が・・・
テーブルのカラムにあるものがなかったら新規INSERT、 あったらUPDATEみたいなことをしたいのですができますでしょうか?
普通ストアドでやる話。
>>563 テーブルのカラム(キー値)にあるものがあったら、キー値以外全部を更新ということかな。
そう考えないと必要とする情報のバランスが悪いけど。
完全変態
SQL最適化テクニックでSELECTで*は使わないと書いてありましたが、 VIEWテーブルにして全部欲しいデータを入れてる場合でも、 *は使わないで全部のカラムをいちいち指定したほうがいいのでしょうか?
聞くとこ間違えたけど・・・きっと親切な人が教えてくれるっ
>>658 そのテクニックの意味するところは「必要な分だけ取り出しましょう」て事なので、
全部ほしいなら SELECT * でも良いと思う。
将来、別の用途でテーブルのカラムが増えたときに云々、ってこともあるけど
そこまで神経質になる必要はない気がする。
スルーパス出ました
>>568 そういうテクニックが書いてある本には、なぜそうした方がいいか理由も
書いてないかな?どんなテクニックにも利点と欠点があるわけで、
自分の用途に合わせて選べばいい。
そういうことを説明してない「テクニック」は迷信と思っておいてよい。
ソースもみてないけど、*を解釈する処理がはさまってたら、直指定の方が早いんじゃないかな
プリコンパイルするかしないかとか、そういう条件でも変わるから一概には言えない。 ただ、どっちの書き方でもカタログは参照するから、差があったとしても微々たるもの だと思うけどね。 特定のDBMSの特定のバージョンでそういう特性がある、とかいうことならわかるが。
表示したい順にビューのカラムを定義すること。みたいなルールを付けてるなら 全部のカラムを書いておいたいいかもね そんな制約は後任には伝わらないし風化したころに問題になる
delete * from hoge; delete id from hoge; どっちが速いですか? カラムにはid以外に50個くらい別の項目があるとします
知るかハゲ
そんなSQL通るのはどのDBMSだ?またMySQLか?
標準SQLではDELETEとFROMの間には何も書けない
50個?正規化しがいのある糞テーブルだなぁ おらわくわくすっぞ
drop table hoge; するといいよ
drop database hage; するともっといいよ
やめろってwww
format c: ……ゲフンゲフン
>>585 さん
それを実行したところパソコンが壊れました
弁償してください
それは壊れてはいないはずです
DB特化OSでも作るか
なつかしのRawIron
590 :
NAME IS NULL :2011/07/17(日) 20:34:48.49 ID:gGThCf1h
sqliteで条件絞り込みに日付関数を使っています。 where strftime('%s','now') > 43200 and strftime('%s','now') < 43200 みたいな感じで、関数の返り値は現在時刻のunixタイムです。 見ての通り2回同じのを呼び出しています。 where strftime('%s','now') as a > 50000 and a < 50000 asが変数代わりに使えるのか変数なのかはよくわかりませんが、 上記のようなことをしてみましたがだめでした。 何か方法、もしくはもっとベターな書き方はないでしょうか?
select strftime('%s','now') as a from hoge where a > 50000 and a < 50000
>>591 ありがとうございます。そしてすみません。
実際には、入ってるカラムと比較しています。
where `time` > strftime('%s','now') - 50000 and `time` < strftime('%s','now') + 50000
select strftime('%s','now') - 50000 as a strftime('%s','now') + 50000 as b from hoge where `time` > a and `time` < b
下記のようなデータがあるとき、投票回数が3以上に該当する投票者の レコードを全て除いた結果が欲しいのですがどのようにしたらよいでしょうか? 投票者 ,投票回数, 誰に投票したか ------------------------------- A , 1 , D B , 1 , E B , 2 , F B , 3 , G C , 2 , H C , 2 , I (3以上に該当する投票者Bのレコードを除く) A , 1 , D C , 2 , H C , 2 , I
投票回数3を持つ投票者を抽出して、それを除けばいい。
595ですがすみません重要なカラムを省いていました。 その投票者を省くのはそのアンケートNoだけに限定したいのです アンケートNo ,投票者 ,投票回数, 誰に投票したか ------------------------------- 1 , A , 1 , D 1 , B , 1 , E 1 , B , 2 , F 1 , B , 3 , G 1 , C , 2 , H 1 , C , 2 , I 2 , A , 1 , D 2 , B , 1 , E 2 , C , 1 , H 2 , C , 2 , I 2 , C , 3 , J 欲しいデータ 1 , A , 1 , D 1 , C , 2 , H 1 , C , 2 , I 2 , A , 1 , D 2 , B , 1 , E
投票回数3のアンケートNo、投票者を抽出して、それを除けばいい。
600 :
NAME IS NULL :2011/07/22(金) 18:59:08.14 ID:J72+2xNa
DBMS:MySQL バージョン:5.5.8 Aというカテゴリテーブルがあり、Bという商品テーブルがあったとして Aのカテゴリテーブルには、2000件、Bの商品データには、300000件登録されている。 お互いのテーブルを紐付けたいのですが、商品データは、いくつかのカテゴリに紐付く場合は、 「多対多」となるので、中間テーブルを作ろうと考えたのですが、もし1商品につき3つのカテゴリに 紐づくという場合は、30万×3=90万件のレコードを作成しないといけなくなります。 商品テーブルからカテゴリテーブルを検索する場合は、90万件のデータから検索するという場合と、 商品テーブルの1フィールドにカテゴリデータをカンマ区切りで入れた場合、どちらの方が検索は、 早いでしょうか? ご教授の程宜しくお願い致します。
スレ違い。
SQL Server2008 以下のテーブル「値段」から id | 食品 | 値段合計 | 値段1 | 値段2 | 値段3 ________________________ 1 | 肉 | 500 | 500 | 1 | 魚 | 300 | | 300 1 | 卵 | 200 | 100 | 50 | 50 2 | 肉 | 350 | 250 | 100 2 | 魚 | 400 | 150 | 250 以下の結果を得て、新しくテーブル「値段合計」を作りたいです。 id |値段id合計|肉値段合計|肉値段1|肉値段2|肉値段3|魚値段合計|魚値段1|魚値段2|魚値段3|卵値段合計|卵値段1|卵値段2|卵値段3| _________________________________________________________________________________________________________________________________ 1 | 1000 | 500 | 500 | | | 300 | | 300 | | 200 | 100 | 50 | 50 | 2 | 750 | 350 | 250 | 100 | | 400 | 150 | 250 肉、魚、卵はそれぞれのidに一行しかなく、 肉と魚は必ずありますが、卵はあるとは限りません。 シンプル縦横問題はわかったのですが、複雑になると一挙にわからなくなりました。。 ご教示お願い致します。
カラムが決まってるなら、CASEで該当カラムだけ抜いて、IDでSUMすればいい。
604 :
602 :2011/07/22(金) 19:16:14.60 ID:???
>>603 ありがとうございます。ぼんやりとイメージは湧いたのですが、
当方は予想以上のシロウトで、具体的なSQL文が浮かびません。。
教えて頂けると助かります。
CASE WHEN 食品='肉' THEN 値段1 ELSE 0 END AS 肉値段1 ってのを横に作っていけばOK。
606 :
602 :2011/07/22(金) 19:26:23.43 ID:???
>>605 おおお。ありがとうございます。
やはり自分が考えたのとは少し違いました。。
実行してみます。
607 :
602 :2011/07/22(金) 20:02:09.89 ID:???
SELECT ID, sum(値段合計) as 値段id合計, CASE WHEN 食品 = '肉' THEN 値段1 ELSE 0 END AS 肉値段1, CASE WHEN 食品 = '肉' THEN 値段2 ELSE 0 END AS 肉値段1, CASE WHEN 食品 = '肉' THEN 値段3 ELSE 0 END AS 肉値段2, CASE WHEN 食品 = '魚' THEN 値段1 ELSE 0 END AS 魚値段1, CASE WHEN 食品 = '魚' THEN 値段2 ELSE 0 END AS 魚値段2, CASE WHEN 食品 = '魚' THEN 値段3 ELSE 0 END AS 魚値段3, CASE WHEN 食品 = '卵' THEN 値段1 ELSE 0 END AS 卵値段1, CASE WHEN 食品 = '卵' THEN 値段2 ELSE 0 END AS 卵値段2, CASE WHEN 食品 = '卵' THEN 値段3 ELSE 0 END AS 卵値段3 INTO 値段合計 FROM 値段 GROUP BY ID; として実行したところ、 「メッセージ 102、レベル 15、状態 1、行 3 ' ' 付近に不適切な構文があります。」 と言われました。。 一体どのように直したらいいのでしょうか?
なんか色々間違ってる。
609 :
602 :2011/07/22(金) 20:17:54.34 ID:???
色々。。。 すみません、普段は全くSQLには縁がないのでサッパリ。。
>>602 select
t.id,(select SUM(値段合計) from 値段 where id=t.id)as 値段id合計 ,
肉.値段合計 as 肉値段合計,肉.値段1 as 肉値段1,肉.値段2 as 肉値段2, 肉.値段3 as 肉値段3,
魚.値段合計 as 魚値段合計,魚.値段1 as 魚値段1,魚.値段2 as 魚値段2, 魚.値段3 as 魚値段3,
卵.値段合計 as 卵値段合計,卵.値段1 as 卵値段1,卵.値段2 as 卵値段2, 卵.値段3 as 卵値段3
from
(select distinct id from 値段) as t
inner join 値段 as 肉 on 肉.id=t.id and 肉.食品='肉'
inner join 値段 as 魚 on 魚.id=t.id and 魚.食品='魚'
left join 値段 as 卵 on 卵.id=t.id and 卵.食品='卵'
>>603 のいうCASEの使いどころが俺には解らん
肉,魚,卵をビュー作っとけばもうちょっとすっきりするかと思って、CTEで書きなおしてみた with 肉(id,肉値段合計,肉値段1,肉値段2,肉値段3) as (select id,値段合計,値段1,値段2,値段3 from 値段 where 食品='肉'), 魚(id,魚値段合計,魚値段1,魚値段2,魚値段3) as (select id,値段合計,値段1,値段2,値段3 from 値段 where 食品='魚'), 卵(id,卵値段合計,卵値段1,卵値段2,卵値段3) as (select id,値段合計,値段1,値段2,値段3 from 値段 where 食品='卵'), 値段合計(id,値段id合計) as (select id,SUM(値段合計) as 値段id合計 from 値段 group by id ) -- クエリスタート select 値段合計.id,値段id合計, 肉値段合計,肉値段1,肉値段2,肉値段3, 魚値段合計,魚値段1,魚値段2,魚値段3, 卵値段合計,卵値段1,卵値段2,卵値段3 from 値段合計 inner join 肉 on 肉.id=値段合計.id inner join 魚 on 魚.id=値段合計.id left join 卵 on 卵.id=値段合計.id あんまり変わらんか
>>610 caseを使えば、joinがいらなくなる。
613 :
602 :2011/07/22(金) 21:55:29.22 ID:???
わわ。ありがとうございます(ノД`) 早速やってみます。
CASE WHEN 食品 = '肉' THEN 値段1 ELSE 0 END AS 肉値段1, CASE WHEN 食品 = '肉' THEN 値段2 ELSE 0 END AS 肉値段1, CASE WHEN 食品 = '肉' THEN 値段3 ELSE 0 END AS 肉値段2, 肉値段1が2つあるから駄目なんじゃないの?
615 :
NAME IS NULL :2011/07/23(土) 22:45:13.77 ID:CIIpEaJq
ふるあうたーじょいん とはどういう意味?
完全外部結合、じゃね?
MySQLを使っています、よろしくお願いします。 たとえですがkaimonoというテーブルをつくり、名前・品物・値段という項目を作りました 名前 品物 値段 佐藤 味噌 500 田中 米 1000 鈴木 水 200 佐藤の味噌の値段(500)を、値段の列にすべて適応させて500と変更するにはどうしたらよいでしょうか。 今回は500としたのですが、実際は数値が変動していていくらなのかわからない状態です
>>617 UPDATE kaimono SET 値段=500 WHERE 名前='佐藤' AND 品物='味噌';
いくらなのかわからない値に変更するのは、ちょっと無理があるだろ・・・。
>>618-619 ありがとうございます、すみませんたとえが悪かったです。
正確にはtwitterと連動させてある人物から受ける「好意」を数値化したものです。もう一度改めさせてください。
名前 品物 好意値
佐藤 味噌 X
田中 米 Y
鈴木 水 Z
となっていて、好意の値は聞くまでいくつかわかりません。
佐藤さんが自分に向けられた好意(X)を聞く分には問題がなくちゃんとXを返すのですが、
佐藤さんが、「鈴木さんのことをどう思ってる?」と聞いたときに、どうしても鈴木さんのZという数値ではなく、
自分のXという値を返してしまって、参照がうまくいきませんでした。
自分で考えたのは、もう一列「仮」というのをつくり、鈴木さんのZの値をこの列すべてに書き込めたら、
佐藤さんが自分の「仮」を参照すればZとなるのでどうだろうとやってみたのですが、
列に書き込むのがまったくうまくいきませんでした
621 :
NAME IS NULL :2011/07/24(日) 04:31:06.98 ID:2of7b51i
質問させてください、mysql5を使っています 今月のweb+dbマガジンを見たら、for文の中でsqlを実行してはいけないという 記述があり、where in文で代用するよう書いてありました (サンプルのsqlはselect文でした) それは良いのですが、自分が今書いてるクエリがfor文の中で insertを実行するものです。 ※こんな簡単なものです for($i=0;$i<10;$i++){ $name = "名前".$i; insert into $table (id, name) values(0, $name); } for文のループ内で実行するinsertも ループ中のselectをwhere inで代用したように ループの外に出して書き換えられるんでしょうか? 思いつきません、どうしたら良いんでしょうか。よろしくお願いします
SQLじゃなくてPHPの質問はスレ違いじゃないかの? forの中でSQL生成して、SQLの実行自体はforの外で一発実行にしときゃいいでしょ。 $sql = "insert into $table values "; for(......) { $name = "名前".$i; $sql .= "(0, $name),"; } $sql = preg_replace("/,$/", "", $sql); MySQL呼び出し($sql)
>>620 田中さんのことをどう思ってるか聞かれたらどうする気?
やりたいことをちゃんとまとめてDB設計やり直してからまた来てね
設計はスレ違いだからここでは聞かないでね
>>621 insertのまとめて挿入は(selectと組み合わせる以外)標準的なSQLではできません
その本がどういう風に書いてあったかは知りませんが、たぶん本意があなたに伝わってないと思われます
624 :
621 :2011/07/24(日) 10:12:15.11 ID:???
すみません、確かに考えてみればsql自体の質問じゃなかったですね
何か自分の知らないSQL構文で解決できるのかと思いました
>>622 ありがとうございます
正直どうしてそれで複数回クエリできるのかもわからないですが
PHPふくめて勉強してみます
>>623 ありがとうございました
根本的に知っているSQLのパターンややり方の数が少ないみたいです
勉強します、ありがとうございました
INSERTやDELETEをやっぱり辞める、とか、やっぱり辞めたのは無しにしたいとか そういう機能ってありますか? Savepointを使うとrollbackはできるみたいだけどrollbackをやっぱ辞めはできないみたいで そうすると、アプリの方で別テーブルとかに全部のDMLを残しておいてrollback後にDMLを実行し直すとか思いついたんですが、もっと賢い方法ないですかね
スレ違い。
【質問テンプレ】
・DBMS名とバージョン :MySql 5.1.41
・テーブルデータ
users(ユーザ)
id (PK) password name
photos(写真データ)
id (PK) user_id (FK references users.id) title (INDEX) file_name
tags(タグ)
id (PK) name (INDEX) photo_id registered_date (INDEX)
・欲しい結果
photosの情報を登録タグを含めて指定件数取得する
・説明
自分のウェブアプリでタグ機能を付けたいと思い
以下のURLのベストアンサーの手法を参考にしました
http://q.hatena.ne.jp/1152280193 タグを専用のテーブルに保存するという手法は分かるのですが、
写真のデータを登録されているタグを含めて指定件数分表示したい場合、
Select文はどう書けばいいのでしょうか
SELECT *FROM photos LEFT JOIN tags ON photos.id = tags.photo_id LIMIT 0 , 30
と言うふうに書いてみたのですが
これだと例えばタグが3つ登録されている写真をセレクトすると一つの写真データに対して3行の結果が帰ってきます
仮に一つの写真データに必ず3つタグが登録されていると仮定すると
LIMIT 0 , 30で30件取得したいと思っても実際には10件分の情報しか得られません
photosの情報を登録タグを含めて指定件数取得する方法をどなたか御存知でしたら教えて下さい
よろしくお願いします。
>>625 どこまでロールバックさせるかは判断できるのだから処理のリトライすればいいだろ
Limit 30でPhotosから抽出した結果とJoinすればいいんじゃね?
>>629 す、すいませんそれどうやればいいんでしょうか
サブクエリーですか
質問させてください、お願いします。 【質問テンプレ】 ・DBMS MYSQL ver 5.5.13 今SNSサイトを作成しています。 他人の書いたレビューに「賛成」や「反対」のボタンを押して その数を該当レビューに表示させる機能を作ろうとしています。 一つのレビューに対しては一人一回のみ「賛成」か「反対」を押せるようにしたいです。 現在は一つのレビューに対し一人が何回でも「賛成」、「反対」を押せます。 今あるテーブルはtbReviewというテーブルで、 この機能に関係しそうなフィールドは 該当レビューのシーケンス番号、 該当レビューを書いたユーザのシーケンス番号 「賛成」を押された数 「反対」をおされた数です。 どんなテーブルをつくれば目的の機能を作れますか? よろしくお願いします。
スレ違い。テーブル設計スレへどうぞ。
select文にたいしてトランザクションを処理を行っています ドライバが異常終了した場合などは例外処理ブロックにいくのですが このときrollbackをするのかcommitをするのかわかりません updateやinsert処理ならrollbackなんでしょうが selectの場合でもrollbackを行うのでしょうか? それともcommitでいいのでしょうか?
>>634 意味分からんが正常ならcommitしておけ
>>634 selectにトランザクションする意味あるのか?
異常時にrollbackするかcommitするかで結果に何か違いがあるのか?
何を気にしているのかわからん
>>634 トランザクション開始
select
insert or update
select
insert or update
コミット
こうゆう事なら分るけど
トランザクション開始
select
select
コミット
これなら意味ないと思う
638 :
634 :2011/07/26(火) 19:42:20.52 ID:???
レスありがとうございます
大量のselectをする場合にはトランザクションをする意味はあります
rollbackするかcommitするかで結果におそらく違いはありません
一般的にデータの整合性を保つために行う
updateやinsert時なんかのトランザクション処理ではないため
rollbackはしなくてもいいとは思いますが
ロックを解放するためにcommitかrollbackの処理は必要なはずです
ですがどちらを使うのが正しいのか分からなかったので質問しました
>>637 さんのケースでいう後者のケースになります
select文には異常がなく通常問題が起きないはずですが
起きないはずの問題を想定した例外処理ですので
コミット前に問題が起きたときにロールバックかコミット
どちらをしようかという質問でした
>>634 俺なら異常処理に入ってるならROLLBACKするが
>>637 そのDBのデフォルトではない分離レベルで2回のSELECT実行するなら
SELECTだけでもトランザクションにする意味はある
>>638 ロックを獲得してるかどうかは分離レベルによる
問題が起きてるのに結果が同じだからといってCOMMITしようというのは理解できん
将来そのトランザクションに更新系入ったら、例外処理でCOMMITからROLLBACKするように変更するのか?
>>639 でほぼ正解だと思うけどデフォルトの分離レベルは関係ないな。
デフォルトかどうかに関わらずRepeatable Read以上の分離レベルのときは
SELECTのみでもトランザクションにする意味がある。
ちなみに逆に言えばRead Committed以下の分離レベルのときは SELECTのみならトランザクションにする意味はない。
質問です。XML形式のデータが格納された列に対して内部検索を行う場合にXQueryを使う方法が 一番コストがかからないのでしょうか?他に検索できる方法があるのでしょうか?よろしくお願いいたします。 (例) 自分で調べたXML内部を検索する方法 SELECT * FROM table WHERE cloumn.value( ' (/root/value)[1] ' , ' varchar(40) ' ) LIKE 'テスト%'
643 :
NAME IS NULL :2011/07/28(木) 01:01:41.01 ID:0714/P0J
1つのテーブルのみをselectして返ってくる結果って PKでソートされてることを期待してはいけないのでしょうか? 低レベルな質問ですみませんが、教えてください
>>643 そりゃそうだ
仮にPK順に格納されていたとしても参照順序は保証されない
そのためにorder by句が存在するんじゃないか
特定のDBMSを使ってて、それが保証されてる、とかならアリだろ。 DBMS変えたときに死ねるけどw
バージョン変えただけでも、死なないって保障は無いよな。
>>643 そんな心配するならなぜORDER BYを使わないの?
使ったら負けかな、と思っている
じゃあ使うなよ
>>643 外部キーなどの関わりがない、
1つのテーブルのみをselectした場合に、
DBMSはPKのことなんか全く考慮しない。だから、
PKの何らかの処理のためにインデックスが張って
あっても、使わないから効力を発揮しない。
PK指定は基本的には重複検査のためのもの。
651 :
650 :2011/07/28(木) 14:05:08.79 ID:???
とは書いたものの、やはり、 PKの範囲をwhere句で書いていて、かつ、タプルが 多い場合には、使うね。でも順序は保証されない。
なんのために order by があると思ってるんだ
使ったら負けかな、と思っている
じゃあ使うなよ
SQL使う時点で負け
プログラムでソートだなw
実際問題Ajaxとかでページング込みでテーブル表示とかしてると javascript側でソートすると効率悪すぎるんだよな
ソートまでAjaxでやらなくていいだろ サーバー側でソートした結果を返せよ
いやあなたたちAjaxって何かわかってないでしょ
>>659 ずいぶん多くの見えない敵と戦っているようだね
え・・・?だって言ってることがおかしいんだもの。 AjaxはJavaScriptでサーバから非同期でデータをとってくる技術ですよ。
jqueryのテーブルはソート機能付きのがあるから、ソートはそれでもいいかも その場合、IDでデフォルトでソートしててほしいか、order by つけてムダに遅くしたくないかは、ケースバイケースかなあ
Ajaxで直接DBMSにアクセスするのか、って話。
早い話設計し直せ
当然phpとかでhtmlのテーブルに流すんだろうけど 実際、絞り込み後のデータ数が1000くらいまでなら、なんとかjqueryで実用になるんじゃないかな ためしてないけど
id id2 hoge 1 1 a 2 1 b 3 1 c 4 1 d 5 2 a 6 2 b こんなテーブルにselect * from test group by id2とやると 4 1 d 6 2 b が出ますが最初に登録した 1 1 a 5 2 b と出したいのですがどうしたらいいでしょうか?
登録日時フィールドを追加
>>667 登録日時フィールドはなくてもidが若い番号が出るようにすればいいんじゃね?
やり方わからんけど
Desc とかつけてもでめか?
670 :
666 :2011/07/30(土) 05:16:47.13 ID:???
レスありがとうございます
>>667 出来れば不要なフィールドは追加したくないです
>>668 同じくやり方がわからないです
>>669 group byのあとにやっても出てきたものがソートされてしまうので無理みたいです
複文を使わなくちゃ無理なのか
673 :
666 :2011/07/30(土) 06:29:48.75 ID:???
>>671 余計なフィールドは入れたくないのですみません。
>>672 サブクエリーも今色々試してますが、いまいちうまくとれません。
もうちょっと頑張ってみます。
>>673 select * from test group by id2
規格で言うとこれエラーだろ。
エラーじゃないし
where句で where a=(select a from bar where foo.a=bar.a) and b=(select b from bar where foo.b=bar.b) をもっと短く(select1回で)書けないでしょうか?
>>676 select a from bar where foo.a=bar.a
って出てくるのは結局 foo.a と同じ値だよな
select b from bar where foo.b=bar.b
も同様に foo.b
ってことは元のSQLは
select 〜 form foo where a=foo.a and b=foo.b
と同じだよな。意味あるのか?このSQL
678 :
676 :2011/07/30(土) 07:34:27.43 ID:???
>>677 文を分かりやすくするためにそう書いただけで実際は中に関数が入ってます
a=(select func_a(a) as a from bar where foo.a=bar.a) and b=(select func_b(b) as b from bar where foo.b=bar.b)
インデックスを作ると検索が速くなるということですが、なぜ作るだけで速くなるのですか? SELECT * FROM foo WHERE xxx USE インデックス名; とかしなくていいのですか。
(´・ω・)スマソ ・DBMS名とバージョン PostgreSQL 9.0.4 ・テーブルデータ 一般的データ ・欲しい結果 検索結果 ・説明 検索を速くする方法を知りたい
>>678 select func_a(a) as a from bar where foo.a=bar.a
だって結局
select func_a(foo.a)
と同じじゃないのか?
>>680 スレ違い。「オプティマイザ」とか「実行計画」とかでググれ。
>>683 何をいってるんだおまいは
select max(a)ってやったら1つしかでてこねえだろ
え?
func_aがmaxだったらどうなんだってことだよ 理解できないのか・・・
func_a(foo.a) != func_b(bar.b) だと思ってるのか・・・。
>>688 俺は
>>683 ではないが
func_aがmaxだろうとなんだろうと、where foo.a=bar.a なんだから
func_a(foo.a)とfunc_a(bar.a)は同じ値を返すんじゃないか、って言ってるんだが
引数の、値以外の情報にアクセスできるような拡張された関数を持つDBMSなら
違う結果返すのも可能かもしれんが...
結合条件がいまいちはっきりしないんで無理かも知れんが
普通にfooとbarをjoinしてwhereで絞るだけで行けるような気がするんだが
普通に考えたら同じ値を返すよな・・・。
>>689 お前の主張もよくわからんな
関数も引数も違うもの比べてどうするんだ
select max(a) from foo; select a from foo where a=(select max(a) from bar where foo.a=bar.a); は同じ結果が返ってくるのか?
>>692 ごめんごめん。間違えた。正しくは↓。
○ func_a(foo.a) != func_a(bar.a) だと思ってるのか・・・。
つうか返ってこないから別のもの要求してんだろうにお前らときたら・・・
結合条件わからなきゃなんとも言えない
これにつきる
>>676 的には
where a=(select a from bar where foo.a=bar.a and foo.b=bar.b)
こんな感じに書けるよ!みたいな答え期待してたんだろ
もちろん上のじゃ期待したものにならないだろうが
いや、
>>676 の期待は
where (a,b)=(select a,b from ... )じゃないか
たしかこんな風に書けるDBMSがあったような気がする
>>693 それ帰ってくる行数がちがうし
もとのSQLで示されてるサブクエリは、単一値を返す必要があるから
当然そういう前提での議論だと思うが
>もとのSQLで示されてるサブクエリは、単一値を返す必要があるから あれだけをみて単一値なんて言い切れないと思うが
699 :
676 :2011/07/30(土) 11:04:41.49 ID:???
すみません話をややこしくしてしまったようで
やってることは自己結合?っていうんでしょうか
fooとbarは同じテーブルをさしています
select * from foo as barという感じです
select * from foo where a=func_a(a) and b=func_b(b)
ってかければ一番いいんですけどこの関数はselectじゃないと使えないので
select * from foo as barにして
>>678 のようになっています
それで取得される値はfunc_aの段階では複数あるのでfunc_bで1つに絞る感じになっています
こんな説明で大丈夫でしょうか?
>>699 質問の意図がやっとわかった。
その関数がwhere句で使えないのが悪い。
701 :
676 :2011/07/30(土) 11:15:24.13 ID:???
>>700 ありがとうございます
最初の方法でやることにします
つかselectでないと使えない関数とか聞いたことないんだが どんなDBMS使っててどんな関数なんだ、それ
>>699 普通に考えると
select *
from (select *,func_a(a) as fa,func_b(b) as fb from foo) t
where a=fa and b=fb
とかでできそうな気がするが
havingもselectも同じようなもんだけどな
集計関数を条件に使うためにhavingがあるんだが 同じようなものってどういう意味なんだ? 元の質問は、selectしか使えない=条件にできないから、ややこしいSQL書いてるって話だぞ それが集計関数なのかどうかしらんが まあ元質問者がhavingしらないって可能性もあるがな
updateとinsertみたいな関係だろ 同じようなもの
ある項目についてbit演算したいのですがどう書けばよいですか? select a, b, c from tablea where (b & 6) <> 0 or (c & 5) <> 0; みたいな感じに書きたいのですがエラーになります
havingはmin(x)で該当するものがあっても 取得されるのがそのレコードではない場合もあるし order by xしてからhavingできない限り同じ結果には成り得ない
b&0の結果になるカラム名あるの?
ワロス
ビット演算って標準的なSQLでサポートされてるのか?
sqliteレベルでもサポートされてたぞ
>>709 とりあえず使ってるDBMSの種類とエラーメッセージぐらい書け
特定のRDBMSの機能に依存するのではなく 標準SQLで出来る範囲でやりたいのですが
無理
ユーザ毎に各商品を何点購入、合計何点購入したかを集計するSQLがうまく書けず悩んでおります。 下記のようなテーブルを想定しております。 Shohinテーブル 商品id, 商品名 sid, sname 1, "商品A" 2, "商品B" 3, "商品C" 4, "商品D" Userテーブル ユーザid, ユーザ名 uid, uname 1, "ユーザA" 2, "ユーザB" 3, "ユーザC" Rirekiテーブル(購入履歴) rid,uid, sid, kazu 1, 2, 3, 2 2, 1, 1, 1 3, 3, 2, 4 Shohinテーブルの商品,Userテーブルのユーザは追加・削除される可能性があります。 このような場合に下のように集計結果を得るにはどのようなSQLを書けばよいでしょうか。 集計結果 ユーザ名 商品A 商品B 商品 商品D … 合計 ユーザA 1 2 0 2 5 ユーザB 3 1 2 2 8 ユーザC 0 2 0 0 2 … 使用予定のデータベースはMySQL 5.0です。 何卒よろしくお願い致します。
CASE
SELECT
>>724 >>7 ですと列は固定のようですので
>>9 のストアドプロシージャを使うということでしょうか。
ストアドプロシージャについては全く理解していないのでひとまずマニュアルと格闘いたします。
ありがとうございました。
>>445 SHOWはSQL文ではないという回答ですが、手元の本には
SHOW COLUMNS FROM テーブル名
というSQL文が紹介されており、実際に動作しますが、これはSQL文ではありませんか?
COLUMNSの箇所はRDBMSによってはFIELDSになります。
何のDBMS使ってるかしらんが DBMSに対する命令がすべてSQLだというならSQLでいいんじゃね
728 :
NAME IS NULL :2011/08/05(金) 06:50:08.78 ID:cF+/o9e0
http://blogs.yahoo.co.jp/nonpipo/3382183.html ↑のように、設定して
DB側の構造はutf8_general_ciにしてるんですが、
phpファイルで呼んだときに
一部日本語の文字が化けてしまいます。
おおまかな原因がありそうだったら教えてもらえますか?
文字化けも
ほむらちゃ→ほ(読み込めない文字)?らち
みたく、一部が見れるんですよね... こういう文字化けの仕方は経験が
無かったので、質問させていただきました
スレ違い。
730 :
NAME IS NULL :2011/08/06(土) 22:28:09.78 ID:+lOHSLVg
MySQLで、以下のような2つのテーブルがあり、parent_idはparentの外部キーとなってます。 parent id p_value 1 AAA 2 BBB children parent_id c_value 1 aaa 1 bbb 1 ccc 2 ddd 2 eee これを parent_id p_value c_value 1 AAA (aaa, bbb, ccc) 2 BBB (ddd, eee) のような形で取り出すことはできますか? GROUP BYでparent_idでまとめることはできたのですが、c_valueをまとめて取り出す方法がわかりません。
ぼくもわかりません。
みんなストアド使ってないの?
使ってるよ。頭の体操代わりにこのスレを見てる。
じゃぁここで質問する人は使ってないってことか
ダメ?ねぇ
テーブルのカラム名のことを「フィールド」と書いてある本があるんですが、 これって正しくは、カラム?フィールド?
どっちでもいいよ。
どっちでもいいなんてこと、あるもんか
レコードならフィールド ロウならカラム
どっちでもいいよ。
いままでそれで困った人は居ないからどっちでもいいよ
強いていうと カラムの方が正統っぽい。フィールドは俗が正系を奪った感じが残る。
下のサイトに従ってMADE2000Aをインストールしたのですが、
データーベースに接続しても初期にインストールされているmasterなどのテーブルを見ることができません。
サーバー自体は正常に動作しているようなのですが、
VSで見てもコマンドプロントでSQL文を打ってもログインは出来るのですがテーブルが存在しない状況です。
環境はVS6.0、VS2003、VS2010とインストールしただけなのですが何が問題なのでしょうか?
ConfigSamples.exeも実行したのですがPUBSなどのDBが登録されません、どなたかご協力お願いします。
http://www.atmarkit.co.jp/fdotnet/basics/adonet_index/index.html
スレ違い。
746 :
744 :2011/08/13(土) 15:01:59.27 ID:???
どこのスレッドに書き込めばいいでしょうか?
>>744 >下のサイトに従ってMADE2000Aをインストールしたのですが、
8年も前のサイトを参考にするのはやめたほうがいいんじゃないかと。
ハゲだなんて、いくら何でも侮辱しすぎではないでしょうか。
剛毛なんだからハゲが羨ましいんだよ 察してやれ
なるほど、褒め言葉だったのですね。 世の中のハゲの人達、良かったですね。
752 :
744 :2011/08/13(土) 16:00:46.30 ID:???
ありがとうございました。
何がありがとうだよ ハゲか?ハゲだからか?
以下のようなテーブルがあるとします。 [テーブル名:ユーザー] ユーザーID , NAME -------- 1 , hoge 2 , fuga 3 , piyo [テーブル名:所持品] ユーザーID , 備品ID -------- 1 , 1 2 , 1 3 , 2 2 , 2 3 , 3 1 , 2 [テーブル名:備品] 備品ID , NAME -------- 1 , PC 2 , 電話 3 , プリンタ ここから指定した備品、例えばPCと電話を両方持っているユーザーを 取得したいです。 DBはmysqlです。よろしくお願いします。
全部結合して、備品.Name = PC or 備品.Name = 電話で抽出。 その結果をユーザーでGroup By して Having Count(*) = 2 でいいんじゃね? ひとりのユーザーが二台PC持ってたりするときは、Distinctすればいいし。
757 :
754 :2011/08/14(日) 22:04:51.75 ID:???
759 :
NAME IS NULL :2011/08/15(月) 14:04:30.55 ID:QHhEfPp7
mysqlで SELECT * FROM table ORDER BY RAND() LIMIT 10;でランダムに抽出できることは分かりました。 今度は 値によってランダムの表示割合を変えたいんですがいい方法は無いでしょうか 例えば PC 値段 \90000 TV 値段 \60000 プリンタ 値段 \20000 のうち、ランダムで2つ表示させるとき 値段の高いものを比較的多めに乗せたいです。この場合だと、PCとTVを優先的に2つに表示させることになります。
多めに拾ってその中から上位を選ぶとかは?
761 :
NAME IS NULL :2011/08/15(月) 14:33:22.51 ID:QHhEfPp7
言い忘れました。 プリンタ 値段\20000 掃除機 値段 \20000 のように同じ値段のものもあります。 この場合は完全にランダムで表示されることになります
値段とランダムを乗算すれば
763 :
NAME IS NULL :2011/08/15(月) 15:26:01.68 ID:QHhEfPp7
SQL 確率 乗算でぐぐってみましたが 有益な情報が出てきません。 よければ具体的なやり方を教えてもらえますか?
乱数に値段をかければ値段が高いやつの数字が大きくなることが 多くなるけど、値段の小さいものも乱数によっては大きくなるだろう
765 :
NAME IS NULL :2011/08/15(月) 16:14:35.14 ID:QHhEfPp7
なるほど 仕組みは分かりました。 最初に乗算してそこで変わった値順番にソートするということですね どういう風にしたらいいでしょうか。そこで得た値を比較するいいやり方は無いでしょうか
766 :
NAME IS NULL :2011/08/15(月) 16:34:32.14 ID:QHhEfPp7
サブクエリを使えばいいんですね しかし全体に乱数を掛けるにはどうやったらスマートにいきますかねー
mysql って order by 句に式書けないのか?
768 :
NAME IS NULL :2011/08/15(月) 17:30:22.20 ID:OwWCx7SR
isnumericについて教えてください ある項目(文字列型)の値が 数値のものだけ抽出したいと考えています isnumericで行おうとしているのですが、 Access上のリンクテーブルに対してクエリを実行するとOKなのですが SQLServer上でクエリを実行すと全角スペースのものも数値として抽出してしまいます ■環境 SQLServer2008 R2 ■テーブル W_チェックテーブル ■データ No Aコード 1 100 2 200 3 ABC 4 (全角スペース) 5 500 ■ほしい結果 1 100 2 200 5 500 ■SQL SELECT No,Aコード FROM W_チェックテーブル WHERE isnumeric(Aコード) <> 0 ORDER BY No 上のSQLを実行すると 1 100 2 200 4 (全角スペース) 5 500 となり全角スペースのレコードが出力されてしまいます 全角スペースのレコードを除外するにはどうすればよいでしょうか??
>>768 ずばり全角スペースのレコードを除外すれば?
770 :
NAME IS NULL :2011/08/16(火) 01:33:09.75 ID:EoZbQvG1
>>767 乗算できるみたいですが、 乱数をそれぞれに乗算して
そこからソートするとなると
どういった記述がベターだと思いますか?
771 :
NAME IS NULL :2011/08/17(水) 03:06:56.13 ID:x37vbGC2
若干すれ違いかもしれませんがご容赦下さい。 現在,SQLに接続し,特定行を更新するシェルスクリプトを書いている所です。 まずシェルスクリプトがSQL文を発行し,それをmysqlにバッチとして渡しています。 処理概要: シェルスクリプトの第一パラメータをmd5sumに渡しハッシュを得る。 コマンド出力を整形しハッシュ値のみを抽出。 その値を使ってヒアドキュメントでSQL.sqlを生成。 SQL.sqlをmysqlに手渡す。 Idカラムがmd5ハッシュと合致の場合,Rateカラムを5に設定。 切断。 #rate5.sh #!/bin/sh md5=`md5sum $1 | cut -f1 -d' ' | sed 's,\(.*\)\n,\1,'` cat > SQL.sql << /*END*/ USE てーぶる; UPDATE File SET Rate = 5 WHERE Id = '$md5'; quit; /*END*/ mysql -h ほすと -u ゆーざ --password='ぱすわど' -e SQL.sql rm SQL.sql echo "$1 was rated 5." #EOF しかし出力されたファイルをバッチで渡すと必ずsyntax errorが返ります。 出力ファイルを手入力した場合,正常に処理が行われます。 なにか渡し方に問題があるのでしょうか?
>>771 SQL.sql にpathが通ってないからmysqlから見つからないんじゃないの?
pathに追加するかフルパスで指定してみそ
若干ではなくて、完全にスレ違い。
Oracle10gです。 ひとつのテーブルに一括で複数行のレコードを挿入したいです。 INSERT ALLを使った場合の一意制約違反を回避する方法はありますか? もしくはMERGE文で一括挿入は可能でしょうか? 他にやり方があればアドバイスお願いします。
スレ違い
>>774 ことごとく意味不明だな。
INSERT ALLは複数のテーブルに挿入できるというだけで複数行かどうかとは
関係ないし、一意制約を回避したいなら制約に違反しないデータのみを挿入
すればいいだけ。
INSERT INTO 〜 SELECT 〜 WHERE 〜 使えばいいかと
778 :
771 :2011/08/19(金) 03:30:51.74 ID:???
>>772 パスは通っています。
単にシンタックスエラーが返ります。
スレ違い失礼しました。
シェルスクリプトスレで聞いてみます。
779 :
NAME IS NULL :2011/08/20(土) 20:33:30.23 ID:dBNWBTY0
オラクルで質問お願いします あるテーブル FOO のカラム0がIDだとして、これをユニークにしたい場合にSEQUENCEを使うとしますよね。 でもFOOから項目をガッツリ削除したあとで追加すると、シーケンスは0からカウントしてくれないじゃないですか? そうするといずれ上限に達しちゃいますよね? シーケンスって定期的にドロップして作り直して、カウンタを巻き戻す物なんですか? それとも普通はもっと別の仕組みでユニークなIDを作るんですか?
スレ違い。
>>779 >そうするといずれ上限に達しちゃいますよね?
どんだけハイエンドなマシン持ってるんだよ。
Oracle のシーケンスの最大値は 10^28 だから、
毎秒一京回更新して、30年以上かかるんだが…
782 :
781 :2011/08/20(土) 22:47:54.17 ID:???
30年じゃないや、3万年だった。
>>781 ありがとうございます!
ぜんぜん上限気にしないでOKなんですね。
とおもったけど、受け取る変数の方でintの上限とかに引っかかりそう。 でも実際にはドロップして作り直したりしないんですよね?
> intの上限 number 型使え。 て言うか、少しはググルなりヘルプ見るなりしろ。
はーい
いーえ
788 :
NAME IS NULL :2011/08/21(日) 12:43:27.06 ID:U2ywkqE1
prd1テーブル p_id 商品ID p_name 商品名前 ---- prd2テーブル p_id 商品ID p_date 製造年 ----- prd3テーブル p_id p_date p_frame 種類1 ---- prd4テーブル p_frame p_pattern 種類2(0又は1が入る) ---- prd1の商品IDとprd2の商品IDは1対1の関係です。 prd1の全商品に対して p_id p_date SUM(p_pattern_0) SUM(p_pattern_1) というテーブルを抽出したいです。 1 2001-01-01 5 2 1 2001-01-02 3 NULL 2 2001-01-01 NULL NULL といった感じです。prd1とprd2を結合したモノに、 prd3とprd4を結合したいのです。
>>788 確認だけど、prd3テーブルにp_dateがあるけれど、
これは本来はなくてもよいものと考えていいかな?
3と4を結合して、CASEでパターン0、1の数をSUM(Count?)すればいい。
791 :
NAME IS NULL :2011/08/21(日) 13:24:36.72 ID:U2ywkqE1
>>789 説明が足りなくてごめんなさい。
prd1に対するprd2を抽出(inner join でも where でも)した以下のテーブル
p_id p_date
1 2001-01-01
1 2001-01-02
2 2001-01-01
2 2001-01-02
2 2001-01-03
に対して、prd3とprd4によって抽出したテーブルを結合するときに
商品IDと製造年をキーに結合したいと思っています。
prd3はちなみに
p_id p_date p_frame
1 2001-01-01 1
1 2001-01-02 2
1 2001-01-03 3
1 2001-01-04 4
3 2001-01-01 5
prd4は、
p_frame p_pattern
1 0
2 1
3 0
4 1
5 1
6 1
といった感じです。
prd1とprd2は1:1じゃねーんじゃん
>>792 あ、そうですね・・・ごめんなさい。1対Nの間違いです。
prd1にあるp_id は必ず prd2にあります。
prd1
1 Aメーカー型番A
2 Aメーカー型番B
prd2
1 2001-01-01製造
1 2001-01-02製造
2 2001-01-01製造
2 ・・・
といった感じです。
だとしたら、prd1とprd2は普通にjoinで、prd3とprd4はouter joinでよい。 caseが使えればgroup by p_id, p_dateで、caseで0と1に振り分けたp_patternの SUM()をとる。 caseが使えなけりゃgroup by p_id, p_date, p_patternとでもしておいて、0と1を 横に並べたければアプリ側でどうにかする。
>>791 prd3は、(p_id,p_date)に対してp_frameは1件なのかN件なのか?
N件だとして、集計は (p_id,p_date)で集計するのか?それとも(p_id,p_date,p_frame)で集計するのか?
>>795 別にcase使わんでも、アプリでやらんでも0と1固定ならどうとでもできる
集約関数でcaseとか使うと遅いイメージあるんだが、実際はどうなんだろうな
case使わん実例
(p_id,p_date,p_frame)で集計
select prd1.p_id,prd2.p_date,prd3.p_frame,
(select COUNT(*) from prd4 where prd4.p_frame=prd3.p_frame and prd4.p_pattern=0) as count_0,
(select COUNT(*) from prd4 where prd4.p_frame=prd3.p_frame and prd4.p_pattern=1) as count_1
from
prd1 join prd2 on prd2.p_id=prd1.p_id
left join prd3 on prd3.p_id=prd1.p_id and prd3.p_date=prd2.p_date
(p_id,p_date)で集計
select prd1.p_id,prd2.p_date,
(select COUNT(*) from prd4 where prd4.p_frame in
(select p_frame from prd3 where p_id=prd1.p_id and p_date=prd2.p_date) and prd4.p_pattern=0) as count_0,
(select COUNT(*) from prd4 where prd4.p_frame in
(select p_frame from prd3 where p_id=prd1.p_id and p_date=prd2.p_date) and prd4.p_pattern=1) as count_1
from
prd1 join prd2 on prd2.p_id=prd1.p_id
まじめに検証してないから間違ってたら許せ
797 :
NAME IS NULL :2011/08/22(月) 02:37:37.65 ID:sxibq+zT
簡単な質問になってしまいますが、 phpで用意した配列 ID(12,45,771,32) をselect文に掛けたいのですが、どういうやり方がスマートでしょうか? ひとつずつ検索していくのではパフォーマンスが悪いですよね?
799 :
788 :2011/08/22(月) 14:28:52.77 ID:???
>>797 select * from table where ID in (12, 45, 771, 32);
802 :
NAME IS NULL :2011/08/22(月) 23:48:11.34 ID:r/msq70K
3entity-sets and 1relationship-set. Customers(cid,cname,city) E Products(pid,pname,city,quantity) E Agents(aid,aname,city) E Orders(cid,pid,aid,price) R Q.Get cid(and pid) of customers, who orders the same product through all agents. たぶんすべてのエージェントを通じて同じ製品をオーダーした消費者を 求めろってことだと思うんですけど。 どんなSQL文を書けば求められるんでしょうか。
>>802 英語はよくわからんが、
全てのエージェントに同じ製品をオーダーしている顧客とその製品ってことか?
select distinct C.cid,O.pid from Customers C join Orders O on C.cid=O.cid
where not exists (
select *
from Customers
cross join Products
cross join Agents
left join Orders on Orders.cid=Customers.cid and Orders.pid=Products.pid and Orders.aid=Agents.aid
where
Customers.cid=O.cid and
Products.pid=O.pid and
Orders.aid is NULL)
で行ける気がするけどもっとスマートな方法があるような気がするなぁ
以下のようなテーブルTABがあります。 A B C 1 40 35 2 80 50 3 10 5 4 20 15 5 70 60 列Aで昇順にソートして一番小さい値を持つ行を基準に、 以下の計算式で列Dを求めたいです。 D(n+1)= C(n)× D(n)÷ B(n+1) nは列Aの順位で求めたい結果は、 A B C D 1 40 35 1 2 80 50 0.4375 3 10 5 2.1875 4 20 15 0.546875 5 70 60 0.1171875 みたいな感じになります。 これってSQLで可能でしょうか? DBMSはOracle11gR2です。
Aの連続(常に+1の差)が保障されてれば可能
AがPKなら連続してなくてもできそうな気はするが ORACLEの11gってCTE使えたっけ? ストアドでカーソル回すのが効率的な気はするな
807 :
804 :2011/08/24(水) 23:37:30.24 ID:???
>805 Aの連続は保障されていないです。 >806 AはPKです。 CTEというのはわからないですが、再帰SQLは使えます。 1SQLでできると嬉しかったのですが、やはり無理そうですね。 お二方、ありがとうございました。
808 :
806 :2011/08/25(木) 02:40:18.17 ID:???
>>807 できる気がすると書いたからやってみた
ただしOracle11gは手元にないのでSQLServerで
with T as (
select Tb.A as A,Tb.B as B,Tb.C as C,Tn.A as nA,Tn.B as nB,Tn.C as nC
from TAB Tn
join TAB Tb on Tn.A=(select MIN(A) from TAB where A>Tb.A)
),
Tx as (
select A,B,C,cast(1.0 as FLOAT) as D, nA,nB,nC from T where A=(select MIN(A) from TAB)
union all
select T.nA,T.nB,T.nC,cast((Tx.C * Tx.D / T.nB) as FLOAT) as D, T.nA,T.nB,T.nC
from T
join Tx on T.A=Tx.A
)
select A,B,C,D from Tx;
少なくともSQLServerなら多分行けてると思う
castのとこはORACLE用に修正しないとダメだが、ORACLEで動くかどうかは知らん
内容はもう俺にも何をやってるのか解らんw
これ保守するぐらいなら素直にストアドかホストアプリでやるべきだな
SQLとは関係ないかもですが、単発のSQL文を流すときに ConnectionからBeginTransactionでトランザクション処理するのと トランザクション無しで実行するのはどちらが良いのでしょうか? また、これらはDBMSによって変わってくるのでしょうか?
トランザクションが必要ならすればよし トランザクションが不要ならしなければよし
単発のSQL、良い悪い(パフォーマンスの事?)、とか関係なく 更新系は全部トランザクション張ってるなぁ
812 :
799 :2011/08/25(木) 11:15:57.23 ID:???
通常はトランザクションが必要な処理(複数のSQL文を使う場合) はトランザクションを張るんですが、単発の場合ってどうするのかなぁっと・・・ 周りも半々でトランザクション張る人もいれば、張らない人もいるし、 でも明確な理由があるわけでもないので・・・ トランザクションの有無がパフォーマンスやその他の事象に影響がある って分かれば使い分けも出来るのですが、そういう記事が見当たらないので どうしていいやら・・・とorz そういった情報があればうれしいのですが><
799じゃなかった809でしたm(_ _)m
単発は1行内でかかってるからいらん
環境によるが、トランザクションを明示しないSQLは 暗黙的にトランザクション内にあるとみなされる このトランザクションは1文で閉じる物もあるし 複数回のSQL発行が同一トランザクションになるものもある まず単発のSQL発行したときにその環境でどう扱われるか確認しろ その環境で暗黙的トランザクションがSQL発行ごとに閉じられるなら 俺が明示的にトランザクション発行するかどうかは、 自分でロールバックをコントロールしたいかどうかで決める
質問です。 DB_AのデータからB項目が空白とNullのデータを取ってこうようと思いSQLを作りました。 条件に Select A項目、C項目 from DB_A Where LEFT(DB_A.S項目,1) <> '0' AND DB_A.B項目 Is Null or DB_A.B項目 = '' と書いたのですが、意図した件数が出てきません。 空白とNULLを分けると意図した件数が出てくるのですが、orで条件付けると件数が数倍に跳ね上がります・・・ 何が原因なのでしょうか・・・
AND (DB_A.B項目 Is Null or DB_A.B項目 = '' ) で試せ
>>817 感謝です。
簡単なことではまっていたのが恥ずかしいです。
本当にありがとうございました。
819 :
804 :2011/08/25(木) 22:52:08.76 ID:???
>806 わざわざありがとうございます。 今環境がないので明日にでも試してみます。
SELECT文で A B C というフィールドを持つテーブルを出力しているのですが、 CはAの値+Bの値となります。 Cを求めるSQL文は Aを抽出するSQL + Bを抽出するSQL といった感じで記述するしかないでしょうか。 A、Bを抽出するのにそれぞれけっこう長文なSQL(各50行ぐらい)を記述しているので 簡単な方法があればと思っています。 SQLServer2008です。
Cはなぜ必要なの?
つかビューつくっとけば良いだけじゃないのか
質問の意味がよく分からんけど
CがA+Bというのは質問の本質じゃなくて
>>7 みたいなことがやりたいんじゃないの?
824 :
820 :2011/08/26(金) 21:51:00.58 ID:???
>>821-823 レスありがとうございます。
僕だけで作ってるわけではないのでCは必要なのです。
ビューがてっとりばやい感じがしますね。
ちなみに僕は
>>788 です。
>>7 とはちょっと違います。
select
( select 長文〜 ) AS A,
( select 長文〜 ) AS B,
from
・・・
という感じで作っていましてA、Bに関してはできていたのですが、
Cのフィールドが後から必要となりまして・・って感じです。
>>824 A+B AS C
じゃできないの?SQLServerよく知らんけど
select A, B, A+B as C from (select ( select 長文〜 ) AS A, ( select 長文〜 ) AS B, from ・・・ ) でいいじゃん
それをビューにしておけば毎回長文〜を書かなくて良いわけだが・・・ もしかして長文〜が条件によって異なるものが多数存在するとか?
828 :
820 :2011/08/27(土) 13:31:16.81 ID:???
>>825 それでいけたら楽なのですがエラーがでます。
>>826 なるほど!それでいけそうですね。
>>827 このSQLは1度しか読み込まれないものですのでビューを作っても作らなくてもよいです。
ビューにした場合は、
>>824 からCを除いたものをビューにしてSQLでCを含んだテーブルを
再構成する感じでいけそうですね。
とりあえず
>>826 さんの方法で試してみます。
830 :
820 :2011/08/28(日) 01:09:17.85 ID:???
>>829 えっと、例えば以下の様な問題の場合、
>>826 さんの方法が一番スマートだと思うのですがどうでしょうか。
テーブル名 tbl1 フィールド名 fld1, fld2
fld1 fld2
1 4
2 5
3 6
上記テーブルが存在した時、以下A,B,Cフィールドを出力するSQLを求めなさい。
Aフィールド・・・fld1+1
Bフィールド・・・fld2+1
Cフィールド・・・A+B
(ただし、C= fld1 + 1 + fld2 + 1 という求め方をしない)※なぜなら実際は長文SQLなので。
ちなみにアタマはだいじょーぶではありません。
832 :
820 :2011/08/28(日) 02:22:56.35 ID:???
>>831 さんは
>>829 さんでしょうか?
いちおう
>>826 さんの方法では以下になると思います。
実行してないので分かりませんがたぶんあってるかと。
SELECT tbl2.A, tbl2.B, tbl2.A + tbl2.B AS C
FROM (
SELECT fld1 + 1 AS A, fld2 + 1 AS B
FROM tbl1
) AS tbl2
;
下記の2つのテーブルから情報を抽出したいのですが、どのようにすればよいでしょうか? ・抽出対象テーブル1構成 カラム1個目: カラム1A(PK) CHAR型 カラム2個目: カラム1B CHAR型 カラム3個目: カラム1C CHAR型 ・抽出対象テーブル2構成 カラム1個目:カラム2A(PK) CHAR型 カラム2個目:カラム2D(PK) CHAR型 ※テーブルの説明 ・抽出対象テーブル1「カラム1A」と、抽出対象テーブル2「カラム2A」同一の値が設定される ・"カラム2D"には"01","02","03"・・・"10"の値が設定される ・抽出したい情報 1個目:カラム1A 2個目:カラム1B 3個目:カラム1C 4個目:カラム2Dの値が"01"のレコードが存在するかのフラグ 5個目:カラム2Dの値が"02"のレコードが存在するかのフラグ 6個目:カラム2Dの値が"03"のレコードが存在するかのフラグ ・・・ 13個目:カラム2Dの値が"10"のレコードが存在するかのフラグ
834 :
833 :2011/08/28(日) 10:31:31.65 ID:???
例えば、以下のように抽出したいのです ・抽出対象テーブル1 1個目 | 2| 3 --------+--+----- 1111111 | a| 1 2222222 | b| 2 3333333 | c| 3 4444444 | d| 4 5555555 | e| 5 ・抽出対象テーブル2 1個目 | 2 --------+----- 1111111 | 01 1111111 | 02 1111111 | 03 1111111 | 10 2222222 | 01 3333333 | 02 3333333 | 05 4444444 | 03 ・抽出したい情報 1個目 | 2| 3 | 4| 5| 6| 7| 8| 9|10|11|12|13| --------+--+---+--+--+--+--+--+--+--+--+--+--+-- 1111111 | a| 1| 1| 1| 1| 0| 0| 0| 0| 0| 0| 1| 2222222 | b| 2| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 3333333 | c| 3| 0| 1| 0| 1| 0| 0| 0| 0| 0| 0| 4444444 | d| 4| 0| 0| 1| 0| 0| 0| 0| 0| 0| 0| 5555555 | e| 5| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| ※4〜13番目のフラグは、"1"が設定あり、"0"が設定なしを示す 分かり難い文章で申し訳ございませんが、よろしくお願い致します。
>>833 select
カラム1A as 1個目,
カラム1B as 2個目,
カラム1C as 3個目,
(select count(*) from テーブル2 where カラム2A=t.カラム1A and カラム2D='01') as 4個目,
(select count(*) from テーブル2 where カラム2A=t.カラム1A and カラム2D='02') as 5個目,
(select count(*) from テーブル2 where カラム2A=t.カラム1A and カラム2D='03') as 6個目,
...
(select count(*) from テーブル2 where カラム2A=t.カラム1A and カラム2D='10') as 13個目
from テーブル1 t
とかで行けるんじゃないかと思うが
カラム名とか、ちょっとセンスの無さを感じるなぁ
837 :
833 :2011/08/28(日) 11:24:24.99 ID:???
>>835-836 早速の回答どうもありがとうございます。
2Dの値が01〜10で固定なので
>>7 の方法でもいけそうですが、
>>836 にて具体的なSQLを記載してくれたため、
そちらのSQLで確認したところ、取得した情報を取得することができました。
本当にありがとうございました。
SQL初心者なので、これから精進していきたいと思います。
また、またお世話になるかと思いますが、よろしくお願い致します。
いや、もう来なくて結構
839 :
NAME IS NULL :2011/08/30(火) 15:21:31.44 ID:b+zHUGzz
MySQLです。 テーブルから最初コラムAで並びかえて、その中の上位30個を コラムBで並び替えた結果がほしい時はどう書けばいいのでしょうか SELECT * FROMT T ORDER BY A,B だと、Aの中の同じ値の物しかBでソートされないみたいです。
SELECT * FROM ( SELECT * FROM T ORDER BY A LIMIT 30 ) ORDER BY B
841 :
NAME IS NULL :2011/08/30(火) 16:24:12.12 ID:b+zHUGzz
>>840 できました。ありがとう
最初Every derived table must have its own aliasみたいのが出たけど
)の後ろにas xとかつけたら治りました。
842 :
NAME IS NULL :2011/08/31(水) 02:49:05.04 ID:NnuVVuWW
サブクエリの条件で、 where hoge=(select max(fuga) from t2 where t1.piyo=t2.piyo) みたいのがあります 2つ以上max(fuga)に適合した場合合致したpiyoからt2.foo(int)が最小のもの1つだけを表示したくて where hoge=(select max(fuga) from t2 where t1.piyo=t2.piyo order by foo limit 1) とかしてみたのですがうまくいかなかったので where hoge=(select max(fuga) from t2 where t1.piyo=t2.piyo) group by id のようにしたらうまくはいったのですが ほしいpiyoでありませんでした(t2.fooが最小ではない) おそらくhavingでどうにかすると思うのですがどうしたらよいでしょうか?
さぁ。
説明がよくわからん いくつ合致してようがfooが最少って条件もandでつなげば良いだけじゃないのか?
サッパリわからんけどまずT1とT2のカラムくらいかけよ T1はPIYO T2はPIYO、FUGA、FOOがあるのか? そしてT2において、FUGAが最大且つ2個以上ある行を取り出して それらのなかからFOOが最小の物を選びたいわけ?
あるカラムの重複のみを外したものをSELECTするにはどうとればいいですか? kadenテーブル id item price 1 パソコン 100000 2 パソコン 80000 3 デジカメ 50000 4 プリンター 20000 5 デンワ 6000 結果 1 パソコン 100000 3 デジカメ 50000 4 プリンター 20000 5 デンワ 6000 パソコンを区別するのはidとpriceがありますがidが若い方でお願いします
select * from (select * from test order by id desc) group by item order by id とか?たぶん遅いけど他に思いつかない 変態さんがきっとすごいコード出してくれる
>>846 select id,item,(select price from kaden where id=t.id) from
(select min(id) as id,item from kaden group by item) t
とかで行けるんじゃないかと
>>847 早いとか遅いとかじゃなくて、それちゃんと通るのか?
group by 書いて列リストに*なんて指定できるか?
それに、サブクエリのorder byなんて意味ないぞ
topやlimitの類を使うなら例外だが
カラムcがプライマリインデクスの場合、 1. INで500個指定したSQLを一回実行するのと、 SELECT * FROM t WHERE c IN('a','b','c'.....); 2. 一つ指定したSQLを500回発行するのとどっちが早いですか? SELECT * FROM t WHERE c = a; SELECT * FROM t WHERE c = b; SELECT * FROM t WHERE c = c; : 1のが早いかと思ったんだけどEXPLAINで調べると1はusing indexにならないんだよね。 using indexになる2.の方が早いのかな?
IN使う方が SELECT * FROM t WHERE c IN('a','b','c'.....); なのに、なんで SELECT * FROM t WHERE c = a; が SELECT * FROM t WHERE c = 'a'; じゃないの?
851 :
849 :2011/08/31(水) 17:57:34.51 ID:???
すみません単なる書き間違いです。両方共''でくくります。
1は結果セットは一つだが、2は結果セットは500個できるわけで そんなものを比べることに意味があると思えん 検索対象の件数や500件の条件のヒット率も解らんのに インデックス使うのが早いとか遅いとかも判断できん
>>851 自分でテストしたほうが早いんじゃない?
くだらない質問かもしれませんが質問させてください。 AとBというデータベースにて、 トランザクション処理で、AとBに同じ処理をしようとして A→OK! B→OK! となった場合、両方にコミットすると思いますが たとえば、Aがコミット成功してBがコミット失敗した場合 そのあと、どういう処理になりますでしょうか? Aは確定させてしまっているのでロールバック(アボート)は使えないと思うのですが
2相コミットとかじゃなくて?
>>855 レスありがとうございます
2層コミットにおいても結局のところすべてのノードがOKとなった状態を待って
全部がOKならコミット命令を出すと思うのですが、
そのコミット命令自体に何らかの通信障害が発生した場合どうなるかということです
>>856 その場合だと Bはトランザクションが commit せず rollback もせずの
中途半端な状態になるはず。後で B に残されたトランザクションを
commit してやらないといけない。
データベースがその未解決の分散トランザクションを自動で解決するか
アプリケーション側からやらないといけなくなるかはデータベースや状況に
よるんでないかと
>>857 レスありがとうございます
やはり何らかの仕組みが必要ということですね
スレ違い。
09/01 りんご 09/02 りんご 09/02 みかん 09/03 りんご 09/03 みかん 09/03 バナナ ・・・ このようなテーブルからりんごとみかんとバナナの3つ 全てがある日付を取り出す構文はどうすれば出来ますか?
>>862 お前がテンプレを読まずに質問しただけで
>>861 はお前に何もしていない。
お礼を言うのではなく、テンプレすら読まずに質問したことを謝れ。
スレ違いかもしれませんが質問をさせて下さい. ・DBMS SQL Server 2005 管理番号 サブ番号 種別コード 0001 01 101 0001 02 102 0002 01 101 上のテーブルに対してインデックスを種別コードに対して作成したのですが, select * from テーブル名 where 種別コード = 101 としてもIndex Scanとなり Index Seek になりません. なにか,間違っていそうなポイントがあれば意見下さい.
3件レコードしかないからじゃね?
まさか・・・件数は省略して3件書いただけだろ。
そのとおりです。実際には4件くらいはあります。
5件にしてやってみ
870 :
865 :2011/09/06(火) 16:18:22.57 ID:???
実際にはレコードが1万3千件程度存在します.
>>870 そのテーブル構造で1万3千件だとインデックスを
使う方が遅いだろうな。
>>871 では何万件ならインデックスを使うほうが早くなりますか.
想像ではなく根拠を示して教えてください.
>>865 ・種別コードのバリエーションが少ない
・カラム数が少ない
ので、そうなるんだと思うよ。
index scanになっていることがボトルネックになっていることを疑っているのなら、
(SQLサーバで出来るのかわからないけど、)index scanを禁止して比較してみたら?
まさか実測して遅いというわけじゃなくて、単にexplainしただけとか?
インデックス使われないことに不満を持つ時期を経験するのは悪くない
インデックス使わることに満足する時期を経験するのが最も良い
そして自分はオプティマイザの足元にも及ばないことに気づく
878 :
865 :2011/09/06(火) 20:06:54.82 ID:???
みなさんご意見有り難うございます.
>>874 >>871 実測では遅くありません. インデックスについて調べていて,実際の環境でやるとどうも想定通りIndex Seekにならず
疑問に思いました.SQL Serverのオプティマイザの機能で今のテーブル状態でこの検索条件だったらIndex Seekより Index Scanの方が速いから,Index Scanに
しておくね.って感じなのでしょうか?
>>873 なるほど.
だんだん試行錯誤していて気づいて来たのですが,
indexを作成したカラムの条件でかなりレコードを絞り込めるようなら@Index Seekを使い.そうでないなら
またカラム数,レコード数またはデータのパターンによってはAIndex Scanになるということでしょうか?
@[Index Seek]
select *
from テーブル名
where 種別コード = 102
A[Index Scan]
select *
from テーブル名
where 種別コード <> 102
となると,Aのような'<>'(以外)を使った検索の場合はIndex Seekになりにくいという認識であっていますか?
長々と質問してしまい申し訳ありません.
>>878 概ねその通り
カーディナリティについて調べてみるといいよ
カーディ・・・何?
ヒント付けて実行計画とって比べてみればいい つかどう考えてもスレ違いなんだが、この手の話に適切なスレって案外ないなぁ
SQL Serverスレは何のためにあるんだ
>>878 > SQL Serverのオプティマイザの機能で今のテーブル状態…
大抵そうなんだけど、実測してみないとわからない。
実測して、遅いプランを選択していることが明白になれば、ヒントを使って手法を強制する
でも、それは今後のデータがどうなるかについて、高精度で予測できる場合に限るよ
初心者質問ですみませんが、よろしくお願いします。 ・Oracle11g 【テーブルデータ】 ID | DATA --+------ 1 | aaa 1 | bbb 1 | ccc 2 | bbb ID2に同一データが存在しないID1のデータだけ抽出したいのです。 上記例の場合、「aaa」「ccc」を結果としてほしい。 よろしくお願いします。
ID2という項目が無いようだが? select DATA from テーブルデータ group by DATA having count(ID)=1 とかでいけんじゃね
886 :
884 :2011/09/10(土) 22:26:30.89 ID:???
>>885 すみません。説明不足でした。
項目「ID」の値が表のように1と2があるとして、
値「2」に存在しない値「1」のDATA項目を抽出したいのです。
つnot exists
888 :
884 :2011/09/10(土) 23:02:21.60 ID:???
>> 887 調べてなんとかできました。 SELECT * FROM テーブルデータ TA WHERE ID = '1' AND NOT EXISTS (SELECT * FROM テーブルデータ TB WHERE ID = '2' AND TA.DATA = TB.DATA) ありがとうございました。
お安い御用です。
890 :
NAME IS NULL :2011/09/14(水) 10:44:38.46 ID:Qm15bR6q
初心者ですが失礼いたします。 ID | DATA | TIME --+------ 1 | aaa | 01:02 2 | bbb | 03:42 1 | ccc | 02:11 3 | bbb | 01:32 というデータがあるとしまして タイムが早い順に並べ替えて重複するIDを除外(この場合は1) するにはどのようなクエリを書けばよいのでしょうか? select * from table ORDER BY `time` DESC でタイム順には並べることができていますが重複するID(人物) を除外したいのです。
お安い御用です。
>>890 >というデータがあるとしまして
仮定の質問にはお答えできません。
893 :
NAME IS NULL :2011/09/14(水) 11:06:06.65 ID:Qm15bR6q
すみません 仮定はaaaというDATAの中身だけで構造は仮定ではありません。
>>890 重複IDを除外ってことは、ID:2, 3 だけを取得するの?
896 :
NAME IS NULL :2011/09/14(水) 11:18:32.24 ID:Qm15bR6q
>>894 試したのですが除外だけされてデータが取れませんでした。
>>895 説明が悪くすみません。
1、2、3を最速タイム順に並べて表示したいのです。
今回で言うと「1 | ccc | 02:11 」を除外して
残りのデータを最速順に表示したいということです。
898 :
NAME IS NULL :2011/09/14(水) 11:46:50.71 ID:Qm15bR6q
書いた後で見ました。 AやBやJOIN等使わずもっと単純なものだと思うのですが……
899 :
NAME IS NULL :2011/09/14(水) 12:02:06.42 ID:Qm15bR6q
select * from table GROUP BY id ORDER BY time DESC でほぼ99%近いデータがでたのですが一つのIDだけtimeがそのIDのMAXではありませんでした。 どこかにMAX()を使うのでしょうか?
900 :
NAME IS NULL :2011/09/14(水) 12:22:50.87 ID:Qm15bR6q
idとtimeだけでよければ
select id,max(time) from table group by id;
dataも必要ならば
>>6
最速タイムならmaxじゃなさそうだな
>>898 ということは
>>6 の要件よりも単純な要件ってことだよね。
それならそれを明記。
そうでないなら、なぜ
>>6 がテンプレになっているかを分かるまで考える
>>898 自分ではSQL書けないくせに、なぜもっと単純だとか言えるんだ
最新か最速か(MAXかMINか)の違いしかない、どうみても
>>6 と同じ要件だろ
特定のDBMSの話ならちゃんとなに使ってるか書け
特に
>select * from table GROUP BY id ORDER BY time DESC
なんつう嘘SQLを堂々と通すDBMS使ってるんだし、そのDBMS特有の動作や命令で
もうちょい単純に書ける可能性はあるが
>>6 とは違うよ、idと日付の組み合わせは食い違いが出ないんだから
MIN()だけでいける、JOINいらない
>>905 食い違いが出ないってどういう意味かわからん
簡単に書けるってならお前がSQL書いてやれよ
JOIN使わん方法なら相関サブクエリ書けばできるだろうが
それがテンプレより単純かといえば微妙
使ってるDBMSを書けよ。話はそれからだ
てか多分理解できないだろうからおとなしくストアドつかえば?
カブトムシがタマゴうんで死んだようですが、 タマゴはどう管理すればいいんでしょうか? マットは結構乾燥してるのですが、 タマゴなんて水分のかたまりみたいなもんだし、 乾燥しないよう水をたっぷりやったほうがいいのでしょうか?
あ、うん・・・ スレまちがえた
もうカブトムシが逝ってしまう季節か・・・
カブトムシはカネモチだ
かーねもち かーねもち いーただきもち
914 :
NAME IS NULL :2011/09/16(金) 01:17:00.86 ID:rKifDnII
>>890 Oracleですんまそ
●非相関サブクエリでやる
SELECT * FROM TBL1 as A
WHERE (A.id,A.time) in(
SELECT B.id,min(B.time) FROM TBL1 as B GROUP BY B.id)
●インラインビューでやる
SELECT A.* FROM TBL1 as A
(SELECT B.id,min(B.time)
FROM TBL1 as B
GROUP BY B.id) as iv
WHERE A.id = iv.id
AND A.time = iv.time
それか
SELECT A.* FROM TBL1 as A
JOIN
(SELECT B.id,min(B.time)
FROM TBL1 as B
GROUP BY B.id) as iv
ON A.id = iv.id
AND A.time = iv.time
915 :
NAME IS NULL :2011/09/16(金) 01:19:51.42 ID:rKifDnII
あ、↑インラインビューのほうFROM句にカンマいれわすれました( ̄ω ̄)
神託ならもっとシンプルになる
てめえで考えろボケ。
何故かワロタ
>>920 質疑応答スレの存在意義を否定しないで答えて下さい。
質問が外部結合したテーブルに内部結合ってできます? A 契約テーブル B 顧客テーブル C コードテーブル select A.key B.bangou C,code from
すいません。途中でカキコしてしました。 外部結合したテーブルに内部結合ってできます? 例 A 契約テーブル B 顧客テーブル C コードテーブル パターン1 select A.key B.bangou C.code from A.key = B.key(+) B.code_key = C.code_key Bが存在しない場合 B.bangou、C.codeはNULLでとれてほしい 無理でしょうか?
>>925 ありがとう
こうすればいいのですね
select
A.key
B.bangou
C.code
from
A.key = B.key(+)
B.code_key = C.code_key(+)
927 :
NAME IS NULL :2011/09/17(土) 14:03:30.95 ID:22KyrEEb
(+) って書き方はOracle?
BとCを内部結合してからAを外部結合すれば良いんじゃ?
929 | /l、 ??? | (゚_ 。 7 ツンツン し⊂、 ~ヽ しf_, )ノシ
AとCを外部結合してからBを内部結合すれば良いんじゃ?
AとCを結合するキー項目が無いんじゃない?
じゃあきらめればいいんじゃ…?
お安い御用です。
解決
MYSQLの5を使用しています 最後にupdateを使用し、データを編集した時の日時って得られますか? 最終更新日時という欄を使ってソートをかけようと思っています 新たなテーブルを作成してdatetime作らないとダメですか?
???
テーブルに最終更新日時の列を追加しといて トリガーで更新するとかしとかないと無理
えっと・・・ id score1 score2 score3 -------------------------- 1 10 10 10 2 20 10 10 3 30 10 10 このデータを id3の人が2011-0906にWEB上で編集して id2の人も2011-0905にWEB上で編集した。 id1の人がまったく更新していないとして・・・ id score1 score2 score3 -------------------------- 3 30 10 10 2 20 10 10 1 10 10 10 こういう順番で出すようにしたいんですが 可能ですか?
>>938 作らないとだめですか・・・わかりました。
ありがとうございます
941 :
NAME IS NULL :2011/09/18(日) 23:24:36.64 ID:Zw+0oaRW
DBMS : Mysql 説明 データは10万件あると想定します。 挿入する際に一つのワードを二つのカラムに大して重複チェックを行いたいです。 どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しいです。 select count(*) from table where colA = 'ワード' OR colB = 'ワード' これだと現在2秒程度かかるので高速化したいです。 よろしくお願いします。
Union
>>942 同じテーブル内にAとBがあります。
それでもUnionの使い方によっては早くなりますか?
それはやってみて試すしかない。
頻繁にinsertするならチェック用に別テーブル作るのが一番よさげだけど
>>944 concatならまだわかりますけどUnionならどう使えばいいのでしょうか?
ちなみにconcatではあまり速度は変わりませんでした。
>>945 チェック用の別テーブルとはどのように構築すれば良いのでしょうか?
現在挿入されているものは全てユニークなものになっているので行数は減らないです。
COLA と COLB のデータ両方がひとつのカラムに入ったテーブル。 OR を使わなくていいんで速い。
select cola from table union select colb from table が10万件より劇的に減るなら効果ありそうだけど、難しそうだな
>>947 あー、なるほど。
件数的には19万程度になると思うので微妙だと思います。
ただ、ちょっと追加情報になってしまうのですが、AかBのどちらかがNULLになってることが多いです。
この場合何かいい方法ってありますか?
ならやっぱり、cola、colbにそれぞれインデックスはってunionなのかな
まず言われたことやれよハゲ
952 :
NAME IS NULL :2011/09/19(月) 00:35:14.92 ID:4PlpFPwP
よろしくお願いします MySQLでint型でstartとendというフィールドがあります。start < endとなっています。 n以上m以下の範囲が、テーブルのstart以上end以下の範囲と被ってるレコードを取り出す場合、 SELECT文の条件はどうなるのでしょうか?
>>950 一応報告まで。
Deleteを使用しているためIndexの再生成に時間がかかりすぎてしまうようです。
もうSQLどうこうの前に構造レベルでの変更が必要のようです。
ただ、貴重な意見がいただけました。
変更した際はUnionを使う方法でやりたいと思います。
ありがとうございました。
>>953 被ってるってどういうこと?
n以上m以下とstart以上end以下の範囲がちょっとでも重なってればいいのか
n以上m以下がstart以上end以下にすっぽり収まるのかその逆なのか
>>955 ありがとうございます
ちょっとでも重なるほうでおねがいしたいです
>>956 where (n > start and n < end) or (m > start and m < end)
でいけるんじゃね
>>941 ちょっと確認するけど、
「どちらか片方にそのワードが含まれていたらcountで0を返す結果が欲しいです。」
これは間違いだよね?
959 :
958 :2011/09/19(月) 04:07:39.31 ID:???
>>953 start < m and end > n
>>957 それだとstart-endがすっぽりn-mに収まる時にひっかからない
>>953 SELECT * FROM TBL
WHERE
n<m AND
(n BETWEEN start AND end
OR
m BETWEEN start AND end)
964 :
NAME IS NULL :2011/09/19(月) 15:26:57.92 ID:eM/xKYwS
>>941 >>961 一般的にSQLの速度はEXISTS>IN=OR=UNION ALLなので
索引はEXISTSを検証してから考えてください
●oracleですまそ
SELECT 1 FROM DUAL
WHERE
EXISTS(
SELECT 1 FROM TBL AS A
WHERE カラムA=ワード)
AND
EXISTS(
SELECT 1 FROM TBL AS B
WHERE カラムB=ワード)
両方のEXISTSがTRUEならSELECT結果は1、それ以外ならスペース表示
MYSQLにDUAL表(1×1マスのDUMMY列を持つ表)なんてある?なかったらすまそ
965 :
NAME IS NULL :2011/09/19(月) 15:30:06.35 ID:eM/xKYwS
↑ORやINからのEXISTS化はバグになりやすいから間違ってる結果を返すかもなので実験してください( ̄ω ̄)
なんか違うだろ。
967 :
NAME IS NULL :2011/09/19(月) 15:41:59.11 ID:eM/xKYwS
違った?重複チェックできると思うけど
968 :
NAME IS NULL :2011/09/19(月) 15:48:10.64 ID:BzSFxFF/
テーブル A: フィールド t, r テーブル B: フィールド p, t テーブル B から p の値を指定して t の値を読み込みたいです。 これだけなら select t from B where p = hoge で済むと思います。 さらに条件を追加して、テーブルAにおいて t の値がそれに等しいようなレコードの数が最小なものを選ぶにはどのようにすればよいでしょうか? 例えば テーブルAが (0, 1), (0, 2), (0, 3), (1, 1), (1, 2) テーブルBが (0, 0), (0, 1), (1, 0), (1, 1), ... となっていたら (0), (1) ではなく (1) だけを得たいです。
969 :
968 :2011/09/19(月) 15:50:16.34 ID:BzSFxFF/
なお、上記条件に合致する値はただ1つになるような実装となる予定です。これを用いることでコードが簡単になったり動作が速くなったりするならばそうしていただけるとありがたいです。
970 :
NAME IS NULL :2011/09/19(月) 15:57:57.06 ID:eM/xKYwS
「ような」ってなんだよw 意味がよくわからんけど、たぶん、テンプレのどれかでできる。
>>968 ごく一般的に書くとこうなる
select T3.t
from (select t, count(*) as cnt from A group by t) as T1
inner join
(select min(cnt) as min_cnt from (select t, count(*) as cnt from A group by t)) as T2
on T1.cnt = T2.min_cnt
inner join
B as T3
on T1.t = T3.t
where T3.p = hoge
;
limitとかrank()とか使えればもっと簡単になるけど
DBMS名を書いてもらわないと何とも
それより誰か次スレ頼む
974 :
NAME IS NULL :2011/09/19(月) 16:29:32.40 ID:eM/xKYwS
>>941 >>961 こんな感じ?
●oracleですまそ
SELECT 0 FROM DUAL
WHERE
EXISTS(
SELECT 1 FROM TBL AS A
WHERE カラムA=ワード
AND カラムB<>ワード
)
OR
EXISTS(
SELECT 1 FROM TBL AS B
WHERE カラムA<>ワード
AND カラムB=ワード)
片方のカラムに存在すればゼロを返却
オラクルでは<>つかうと索引使われなくなるどす
976 :
968 :2011/09/19(月) 17:29:04.72 ID:BzSFxFF/
>>972 ありがとうございます。
質問の文章が曖昧だったためで申し訳ないのですが、私の意図した質問と異なるものに答えられたように思います。
p が与えられたときに、
テーブルBに (p, t) というレコードが存在するような t の中で
テーブルAに存在する (t, r) というレコードの数が最小であるもの
を意図していました。
>>972 のコードは
p が与えられたときに、
テーブルBに (p, t) というレコードが存在するような t であって、
すべての t' に対して、
テーブルAに存在する (t, r) というレコードの数は テーブルAに存在する (t', r) というレコードの数 以下であるもの
を選択しているように思いますが、私の読み違いでしょうか?
DBMS というのが何を指すのかわからないのですが、MySQL の 4.1 以降の何か、でよいですか?
お安い御用です。
978 :
972 :2011/09/19(月) 18:57:56.20 ID:???
ごめん間違えた 一般解はこんな感じかな? select T3.t from (select T1.t, T1.cnt as cnt from (select t, count(*) as cnt from A group by t) as T1 inner join B as T2 on T1.t = T2.t where T2.p = hoge ) as T3 inner join (select min(T4.cnt) as min_cnt from (select t, count(*) as cnt from A group by t) as T4 inner join B as T5 on T4.t = T5.t where T5.p = hoge ) as T6 on T3.cnt = T6.min_cnt ; MySQL限定なら select T1.t from (select t, count(*) as cnt from A group by t) as T1 inner join B as T2 on T1.t = T2.t where T2.p = hoge order by T1.cnt limit 1 ;
979 :
968 :2011/09/19(月) 19:10:19.28 ID:BzSFxFF/
MySQL限定ってだけでそんな違うんですね! 昇順ソートして1つだけ取ればよいということでしょうか。とてもわかりやすくなりました。ありがとうございました。
980 :
NAME IS NULL :2011/09/19(月) 19:50:45.46 ID:Hy6kQx4A
H2データベースを、MySQLに読み込んで、 MySQLから参照できるようにしたいのですが、 インポートはどのようにすればよいのでしょうか・・・ よろしくお願いします
スレ違い。
982 :
980 :2011/09/19(月) 19:58:06.94 ID:???
>>981 すみません〜
誘導お願いできないでしょうか?
MySQLスレで質問させてもらったらいいでしょうか・・?
>>982 MySQLの方でもどうかと思うがな〜
そのH2DBではテキスト(*.txt *.csv)で出力することは出来んの?
>>953 おまえ、SQL以外でも人生でわからないことが多くて困ってるタイプだろ。
985 :
980 :2011/09/19(月) 20:41:07.14 ID:???
>>983 あぁ・・すみません
csvなどのテキスト出力方法がわからず困ってたのですが出力できました
このテキストをMySQLで読み込めばいいのですね。
ありがとうございました、助かりました
お安い御用です。