>>698 サブクエリ必要か?
SELECT bk.* FROM books bk
LEFT OUTER JOIN reserves res ON (
bk.book_cd = res.book_cd
AND res.user_cd <> '19'
);
これで取れそうな気がするが
701 :
700:2013/03/21(木) 13:08:21.34 ID:???
すまん、最初のbk.*は*の間違いだ
テーブルの定義にもよるけどユーザIDに関連するフィルタ近辺で意味が変わる可能性があるよ。
一番外のサブクエリははずせると思うけども
お前らかっこいい
禿がいいのか。
SQL SERVER 2010ですが
TOP 2を求めて残りをその他として合計表示したいです。
よろしくお願いします。
元のデータ
列1
A
A
A
B
B
C
D
求めたい結果
A 3
B 2
その他 2
>705
SELECT NAME, SUM(CNT1) CNT FROM(
SELECT NAME=CASE ID
WHEN 1 THEN NAME
WHEN 2 THEN NAME
ELSE 'OTHER'
END,
CNT1 FROM (
SELECT ROW_NUMBER() OVER(ORDER BY COUNT(*) DESC) ID,NAME,COUNT(*) CNT1
FROM TBL1
GROUP BY NAME
) A
) B
GROUP BY NAME
710 :
NAME IS NULL:2013/03/24(日) 14:16:59.11 ID:LtAoLu+W
mysqlを使用しています
descを使うとカラムの名前などがわかるのですが
sql分の結果でカラムの名前だけを知りたい場合はどのようにすればいいか教えて頂けないでしょうか?
カラム名を知らないDBにアクセスする状況がまったく思い当たらないんだが
show columns from TBL;
とか
select column_name from information_schema.columns where table_schema="SCHEMA" and table_name='TBL';
でどうだろうか
712 :
NAME IS NULL:2013/03/24(日) 15:09:57.15 ID:LtAoLu+W
ありがとうございます
zaikoというテーブルがあって
desc zaikoを実行すると
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| B508 | varchar(50) | YES | |NULL | |
| C895 | varchar(50) | YES | |NULL | |
| d786 | varchar(50) | YES | |NULL | |
と出てくるのですが
Fieldの部分だけを表示したいと思っております
Type | Null | Key | Default | Extra |の項目は非表示にしたい
ADOで
For i = 1 To wkRs.Fields.Count
Write #num, wkRs.Fields(i - 1).Name
Next
とやって列名取出してんのはやってるけど、Fieldの部分だけ出すのってSQLだけで出来るの?
まだよくわからん
Fieldの部分だけを見たいのはプログラム?人間?
どっちにしても
>>711の後者のSQLで表示はできるが
>>713 ほとんどのDBMSでシステムが持ってるカタログを参照することで可能
いちおうinformation_schemaってのが標準SQLで決められてたはずだが
実装されてるかどうかはそのDBMS次第
確実な方法は各DBMSのスレで聞いてください
ということで
>>712はmysqlのスレへ行ってください
テーブルを5つJOINしてselectで、グループ名、ホスト名、データ名、データ取得時刻、データ値を表示しようとしています。
しかし、データ型が整数の場合と、浮動小数の場合で、データ取得時刻とデータ値が格納されているテーブル(trendsとtrends_uint)が異なっている。
つまり二つのテーブル(trendsとtrends_uint)から片方で検索してNULLならもう片方のデータ値、時刻を取得したいのですが、どうしたらよいでしょうか。
現在、下のようなSQLだと全てのデータ値、時刻がNULLになってしまいます。
SET NAMES UTF8;
SELECT groups.name,hosts.host,items.name,from_unixtime(trends.clock|trends_uint.
clock),(trends.value_min|trends_uint.value_min)\
FROM hosts \
RIGHT JOIN items ON items.hostid = hosts.hostid \
LEFT JOIN trends ON items.itemid = trends.itemid \
LEFT JOIN trends_uint ON items.itemid = trends_uint.itemid \
RIGHT JOIN hosts_groups ON hosts_groups.hostid = hosts.hostid \
RIGHT JOIN groups ON hosts_groups.groupid = groups.groupid \
WHERE hosts_groups.groupid = 14 \
;
COALESCE 使う
>>717 簡潔にして素早いレスありがと。これでいけたっぽい。
SET NAMES UTF8;
SELECT groups.name,hosts.host,items.name,from_unixtime(COALESCE(trends.clock,trends_uint.clock)),COALESCE(trends.value_min,trends_uint.value_min)\
FROM hosts \
RIGHT JOIN items ON items.hostid = hosts.hostid \
LEFT JOIN trends ON items.itemid = trends.itemid \
LEFT JOIN trends_uint ON items.itemid = trends_uint.itemid \
RIGHT JOIN hosts_groups ON hosts_groups.hostid = hosts.hostid \
RIGHT JOIN groups ON hosts_groups.groupid = groups.groupid \
WHERE hosts_groups.groupid = 14 \
読み方はコウアレス
しかし、コアレスセと心の中で発音しながらタイプする
やっぱりみんな、読み方と綴りに苦労してるんだなw
コアリーズだとばかり思ってたw
コアレス
シングルコア→マルチコア→メニーコア→ついにコアレスへ
725 :
NAME IS NULL:2013/03/28(木) 19:15:34.91 ID:qyRM7UsI
アクセントはレにあるのか
やべー今まで間違えてたぜ
日本人相手ならカタカナ棒読みで大丈夫だ。
mysql 5.5.9
master
code
last_tradingdate
data_tbl
code
data1
tradingdate
で、data_tblにはcode毎に取引日が入っています
それでmasterのlast_tradingdateにcode毎の入力最新日をセット
したいのですが、どう書けばいいんでしょうか。
730 :
NAME IS NULL:2013/03/30(土) 10:44:46.72 ID:aVENNsvE
お知らせ
市原警察署の生活安全課の帰化人創価警官の指導の元、
入学式から2週間ほど、在日の創価学会員を主体とした自称防犯パトロールが、
2週間ほど行われることになりました
生活安全課の指導であることと、パトロールであることは、
絶対に公言してはいけないとの指導も、帰化人創価警官より出ています
期間中は2人組の在日の創価学会員が、頻繁に創価批判者の自宅周辺を、
うろつき回ると思われます
日本人の方は、充分に注意してください
coalesce 使うと遅くなる?
>>729 UPDATEはDBMSで結構差があるからなぁ
mysqlよく知らないが
update master set last_tradingdate =
(select max(tradingdate) from data_tbl where code=master.code)
とかで出来ないか?
masterに別名付けないとダメかもしれんが
>>732 729です。感謝です!セット出来ましたm(__)m
735 :
NAME IS NULL:2013/04/07(日) 13:20:22.35 ID:XikuI4eK
日記のテーブル(tD)
id,title,main_text
日記の写真のテーブル(tF)
id,diaryId,file_path,is_deleted,is_finished
以上のようなテーブルがあり、tD.id = tD.diaryIdの関係です
この状況で、日記のタイトル・文章とその日記に属する写真情報のセットを取得したいとき
left joinで on tD.id = tD.diaryId としてクエリしたら良いと思いますが
以下の条件がついた時にどうしたら良いかわかりません
条件1:tFのデータは、一つの日記に対して複数のデータを持ち、そのうちis_finishedが1かつis_deletedが0のモノだけを取得
条件2:条件1を満たせる写真情報がなければ、写真情報は必要ない。日記のテキスト情報だけを取得する。
条件3:写真情報をもたないテキスト情報も存在する。
条件1はwhereに tF.is_finished = 1 AND tF.is_deleted =0 として書けば満たせますが、
こう書いてしまうと条件2と3を満たせなくなります(写真情報のない日記を抜き出せなくなる)
どうしたら良いんでしょうか、すみませんがよろしくお願いします
736 :
735:2013/04/07(日) 13:33:53.21 ID:???
すみません、解決しました
joinの条件としてonで指定できるんですね
お邪魔しました
onの条件じゃなくて、inner join かouter joinかって話だと思うが
left joinとか何も分からず使ってるのか
>>736 亀だけど、
select * from tD left join tF on (tD.id = tF.diaryId)
where
tF.id is null -- tFと結合できなかったもの
or
is_finished = 1 and is_deleted = 0 -- tFと結合できた場合の条件
>>738 それだとis_finished=0の写真しかもたない日記が選択されないぞ
条件2の日記のテキスト情報だけを取得する、に反してる
あと俺なら結合できた場合の条件の方は括弧で囲んどく
andとorの優先順位に絶対の自信があるなら無くても良いのかもしれんが
おおほんとだ。ありがとう。
tFを事前にフィルタしてそれと結合がいっか。
select * from tD
left join (select * from tF where is_finished = 1 and is_deleted = 0) tF_filtered
on (tD.id = tF_filtered.diaryId)
>>736のonでやるってのはどうにも解決に結びつかないと思いつつ
と、作ったものの、select句に入れるのとどっちがいいんだろね。
select *
, (select file_path from tF where tD.id = diaryId and is_finished = 1 and is_deleted = 0) as file_path
from tD
以前セレクト句でサブクエリ使うのはワカッテナイ人だみたいな事言われてちょっと悩んでる。
ほしい列がひとつであることとか、抽出されるのが高々1件である前提はつくんだけど、
existsとかが許されて、こっちは許されないってのは納得いかないようにも。
>>741 たぶん、ワカッテナイ人が無暗に使うからでしょ。
結局は、それも一つの道具じゃんね。
>>742 System R 時代からの基本中の基本じゃない。
>>741 それは条件1:一つの日記に対して複数のデータを持ち
に反する
>セレクト句でサブクエリ使うのはワカッテナイ人だみたいな
お前がわかってないだけで、ちゃんと使ってる人はわかってる
そんじゃ
>>740でいいのか
って書いたらその書き方じゃだめだっていわれるのかなぁ…
onの条件で解決したって書いてんだから
select * from tD left join tF on tD.id = tF.diaryId and is_finished = 1 and is_deleted = 0
だろうがJK
747 :
NAME IS NULL:2013/04/11(木) 18:26:57.82 ID:5zVK9FJ/
MySQL 5.5.29
┏━┳━━┳━━┓
┃no┃.date┃名前┃
┣━╋━━╋━━┫
┃.1 ┃12-3┃榊 ┃
┣━╋━━╋━━┫
┃.2 ┃12-3┃山下┃
┣━╋━━╋━━┫
┃.3 ┃12-3┃斎藤┃
┣━╋━━╋━━┫
┃.4 ┃12-4┃山下┃
┣━╋━━╋━━┫
┃.5 ┃12-4┃斎藤┃
┗━┻━━┻━━┛
result:
no:1
名前:榊
このようなテーブルデータから、12-4に対して絞込みを行った際、前日に名前があり、当日に名前の消えているデータを抽出したいと思っています。
当初は2回SQLを実行しPHPで配列に流しこみそこで比較していたのですが処理の遅さが気になり、どうにかデータベース内で完結出来ないかと思い質問に来ました。
宜しくお願いします。
やりたいことがよくわかんないけど
実際に削除せずに削除フラグ(削除日)の列を追加すればいいんじゃないの?
749 :
NAME IS NULL:2013/04/11(木) 19:04:40.74 ID:5zVK9FJ/
>>748 毎日別の場所から全データデータをinsertしており、削除しているわけではありません。
前日で絞り込んだものと当日で絞り込んだものを外部結合して、当日のレコードがないものがそれだとおもうよ
にしても処理の遅さってのが気になるなぁ。
PHPのコードが下手なんじゃないだろうか。もしくはレコードが10万件ぐらいあるか
751 :
NAME IS NULL:2013/04/11(木) 22:01:35.96 ID:Rj/wVQTL
遅くなりました。
PHPのコードが非効率的なのもあると思います。ただ、レコード数が2万件/day近くあり、出来ればデータベース内で処理したいなと思ったのです。
SELECT t1.no,t1.name FROM test as t1 LEFT OUTER JOIN test AS t2 on t2.date='2012-12-03'
WHERE NOT EXISTS(SELECT * FROM test WHERE name = t2.name AND date='2012-12-04') AND t1.no=t2.no
これでなんとか取得出来ました。ありがとうございます。
2万行でこのSQL走らせるとか…何もわかってねーな。
なんだろうこのクエリ
とても読みにくい
>>750の説明の通りに書いたつもりの結果なのかな
2万件/dayが二つあって、PHPで4億回ループするコード書いてそうな気がする
754 :
NAME IS NULL:2013/04/12(金) 05:59:19.07 ID:1iWE1m3w
会議室予約のようなシステムを作っています。
前提として、
Username,Email,Passwordなどのカラムを持つUserテーブルがあり、
さらに、それぞれのユーザーが
Aさん
10日月曜日 13:00-14:00
13日木曜日 15:00-16:00
14日金曜日 20:00-21:00
。
。
などのように時間の枠をいくつか指定して予約できるようにしたいです。
この場合、こうやった時間のデータをどのように保持するのが理想でしょうか
使用しているデータベースはmysqlです。
>>754 最低でも
>>1は読んでね。
情報がないので
表示する際にまとめて呼び出すべき内容だとか
仕様上の制限だとか色々なものとっぱらって中身だけとなるけど
Usernameがprimary keyだと仮定した場合
予約テーブル
Username
予約開始時刻 datetime
予約終了時刻 datetime
で、とりあえずでけるでそ。
曜日は、ホスト言語側で計算させるほうが大概はいい気がする。
756 :
NAME IS NULL:2013/04/12(金) 16:00:24.21 ID:1iWE1m3w
>>755さん
失礼いたしました。
データをテンプレにそって書き直しました。
・DBMS名とバージョン
Mysql 5.5.27
・テーブルデータ
ユーザーテーブル
ID | Username| email
--+----------+-----
1 | taro |
[email protected] 2 | jiro |
[email protected] 3 | saburo |
[email protected] 4 | shiro |
[email protected] ・欲しい結果、説明
以上のようなテーブルの各ユーザーに
10日月曜日 13:00-14:00
13日木曜日 15:00-16:00
14日金曜日 20:00-21:00
と行ったような複数の予約データを
持たせたい(会議室予約のようなイメージです。)
--------------------
755さんの示していただいた解決策は、
予約テーブルを新たに作り(primaly keyはIDでした)
予約テーブル
ID |StartDatetime |EndDatetime
--+---------------------+-------------------
1 | 2013/10/03 13:00:00 |2013/10/03 14:00:00
1 | 2013/10/03 15:00:00 |2013/10/03 16:00:00
1 | 2013/10/03 20:00:00 |2013/10/03 21:00:00
2 | 2013/10/05 11:00:00 |2013/10/05 15:00:00
3 | 2013/10/06 13:00:00 |2013/10/06 14:00:00
3 | 2013/10/07 13:00:00 |2013/10/07 14:00:00
2 | 2013/10/08 13:00:00 |2013/10/08 14:00:00
このような意味合いになるでしょうか。
だとしたらすっきりいたしました。
ありがとうございます。これで実装をしてみます。
>>756 うーむ、それで要件にマッチしてるというならそれでいいけど…。
まず、その予約テーブルのPKはIDじゃないよね?
それと、「会議室予約」をイメージするなら、こんな感じなのを想像するんだけど。
CREATE TABLE users (
user_id text, -- PK
user_name text
);
-- 会議が行われる場所
CREATE TABLE meeting_rooms (
room_id text, -- PK
rroom_name text
);
-- ある会議室で行われる会議
-- 別途、いろいろな制限をデータベースの制約かプログラムで実現する必要がある
CREATE TABLE meetings (
meeting_id text, -- PK
room_id text, -- FK: meeting_rooms.room_id
from_date datetime,
to_date datetime
);
-- 会議に参加する人達
CREATE TABLE participants (
meeting_id text,
user_id text,
);
DB設計のところから話を始めたほうがよくね?
759 :
NAME IS NULL:2013/04/12(金) 20:24:18.00 ID:WP7p6Bmy
>>752 >>753 実際に抜き出すデータは100件そこらなので、PHPの時には
2重foreachで回して、同一データが存在した場合両方を削除して最初からやり直しーといったコードを組んでおりました。
>>750さんの説明通りに書いてみたつもりなのですが、
もっと効率良く抽出出来るSQLがあるのでしたら、是非お教え願えませんでしょうか。
>>759 効率よくという以前に、結合とはどういう処理なのか、考えたほうがよいかと。
761 :
NAME IS NULL:2013/04/12(金) 22:17:06.04 ID:WP7p6Bmy
>>760 はい、実は結合を使ったのは今回が始めてでして・・・学びなおしてきます。
>>761 1. 指定日付の集合 T1 を得る
2. 指定日付の前日の集合 T2 を得る
3. T1 のうち T2 に名前のないレコードを出力する
>>761 まあ手続き型の言語ばっかりやってるとなかなか良いSQLは思い浮かばない
たとえば
>>762を馬鹿正直(日付要件勘違いしてるのは訂正)に書くと
select T1.no,T1.name from
(select * from test where [date]='2012-12-03') T1
where name not in ( select name from
(select * from test where [date]='2012-12-04') T2)
まあ、これではいまいちなんで、これを外部結合でやってもうちょいスマートに
select T1.no,T1.name from
(select * from test where [date]='2012-12-03') T1
left join
(select * from test where [date]='2012-12-04') T2
on T1.name=T2.name
where T2.name is NULL
日付指定が2か所ででてるが、条件が指定日と前日で良いなら
select T1.no,T1.name from
test T1
left join
test T2
on T1.name=T2.name and T2.date=T1.date+1
where T2.name is NULL and T1.date='2012-12-03'
まあ、俺ならこう書く
失礼します。
【質問テンプレ】
・DBMS名とバージョン
SQLiteバージョン3
・テーブルデータ
ドメインID,ドメイン名
------------
1,test1.co.jp
2,test2.co.jp
・欲しい結果
"server1.test1.co.jp"という入力に対し
"test1.co.jp"のドメインIDである1
・説明
自分のサイトへのアクセスを行うドメインを管理しています。
"server1.test1.co.jp"や、"server2.test1.co.jp"等、第4レベルだけが違う同じ業者からのアクセスがあります。
それらを"test1.co.jp"からのアクセスであると判断し、ドメインIDである1を取得したいのです。
以上、宜しくお願いします。
SELECT * FROM テーブル WHERE 'server1.test1.co.jp' like '%'||ドメイン名
で行けるんじゃないかな
ドメインの部分一致であればドットをちゃんと考慮しないとダメだよ。
SELECT * FROM テーブル WHERE '.server1.test1.co.jp' like '%.'||ドメイン名
パーセントの後のドットとserver1の前のドットに要注目。
単に後方一致だとserver1.latest1.co.jpがtest1.co.jpとマッチしてしまう。これは不味い。
なのでまず%の後にドットをつけて'%.test1.co.jp'というパターンを使う。
次にこれだとserver1.test1.co.jpはマッチしてもtest1.co.jpという完全一致文字列がマッチ
しなくなってしまう。なのでトリックとして検索文字列の方にも頭にドットをつける。
え、そんな難しいことは言ってないべ?
test1.co.jp も許可してやれよ。
PostgreSQL なんだから POSIX正規表現 使えよ
>>769 許可してるじゃん。
トリックの解釈が難しいのかな?
>>771 %.test1.co.jpじゃtest1.co.jpは引っ掛からないだろ。
>>772 トリックわかってないんじゃん、、、やっぱり
>>766って難しいこと書いてたのかな。
俺はすぐわかったけどなあ
>>773 おれなら
>>766のSQLはこう書く
SELECT * FROM テーブル WHERE '.'||'server1.test1.co.jp' like '%.'||ドメイン名
まあドメインの検索条件は要件次第だしよそでやってくれ
766と大差無いやん。
この例の場合はあまり関係無いけど、ドメイン名に関してはレコード数が多くなった場合は
test1.co.jpではなくjp.co.test1のようなリバースオーダーで管理した方が扱いやすいことも多い。
>>773 ごめん。
>>766のSQLをさらっとだけ見てたんだよ。
でも766の書き方じゃ変だろ。
'.server1.test1.co.jp' の左端に . があることなんて気が付かん方が多いだろうし、
. を付けるコードが入ってないじゃないか。
. を付けたいんだったら
SELECT * FROM テーブル WHERE '.'||'server1.test1.co.jp' like '%.'||ドメイン名
として検索したいデータである'server1.test1.co.jp'に'.'を付けてやらなきゃだめだろ。
index効かないからドメインの抽出はホスト言語側でやれよ。
index必要なほどたくさんのdomainをホストしているようには思えないな。
>>761 結合が初めてでMySQLならば、まずInnoDBを指定してテーブル組んで
最初に出してたユーザテーブルと
予約ID int unsigned primary key auto_increment,
ユーザID int unsigned,
予約開始時刻 datetime
予約終了時刻 datetime
で組んだうえでこの予約テーブルとユーザテーブルのそれぞれのユーザIDを外部キーで繋いでみそれ。
ああ、ちなみに外部キーかけるときは、予約テーブル.ユーザIDにもINDEXが必要。
あんまり意味がある話じゃないんだけれども、結合を利用した多次元的な組み方をより早く理解できるんじゃないかと。
効率がいいものが欲しい場合、それらを利用してどんな出力を多用するかとかの話がないと無理ポ
>>776 なもんでこれを書いてたんだと思うよ。
> 次にこれだとserver1.test1.co.jpはマッチしてもtest1.co.jpという完全一致文字列がマッチ
> しなくなってしまう。なのでトリックとして検索文字列の方にも頭にドットをつける。
実装時にはSQLでやるかロジックでやるか任せてみたんでないの
質問です。
join は、where や order by より必ず先に実行されるのでしょうか。
たとえば
select *
from employees e
join departments d on e.department_id = d.id
where e.id in (1000, 10001, 10002)
order by e.name
というSQLがあったとして、この場合だと先に where や order by で対象行を
絞りこんでから join を実行したほうが、実行効率がよいと思われます。
しかし join のほうが先に実行されると、すべての行に対して join が実行
されてから、対象行が絞りこまれす。つまり、必要のない行にも join が
実行されてします。これは効率が悪いように思います。
というわけで、SQLのjoinは必要に応じてwhereやorder byよりあとに実行される
ことがありますか。それとも必ず先に実行されますか。
RDBMSごとに違う場合は、RDBMSごとに教えていただけるとさいわいです。
>>781 とりあえず自分の使ってるRDBMSでどういう風に処理されたか確認してごらん。
どういう順番で処理されたかを知る方法はあるから。
FROM句に(SELECT 〜)置いてそれとjoinするとか
>>785 その記事で全てがカバーされてはいないが、
・実行計画とは何か
・実行計画にはどのようなものがあるのか
・実行計画はどのようにして決定されるのか
・自分が使っているRDBMSで実行計画を知るにはどうすれば良いのか
を、自分で調べろっつってんだよ、タコ
あと、コストベースとかルールベースとかがその記事になければ、そこまで調べろアホ
まぁまぁ。上の人が言いたいのは、
>>781 > というわけで、SQLのjoinは必要に応じてwhereやorder byよりあとに実行される
> ことがありますか。それとも必ず先に実行されますか。
> RDBMSごとに違う場合は、RDBMSごとに教えていただけるとさいわいです。
ケースバイケースとしか言えないから、自分で実行計画を読めるだけの知識を蓄えて、
自分で試しましょうってことだと思うよ。
SQL文に ( ) 付ければ、( ) の中から順に処理してくれるよ。
(落とし穴があることは気がつかないだろうけど)。
>>781 多分、君が効率良いだろうと思うこと(あるいはそれ以上)は、大抵のRDBMSはやってくれるよ。
まあ普通はまずemployeeをidでfilteringして、departmentsをhash joinすると思うけど。
ただ、行数とかidの散らばり具合とか(100万行のうち1000,10001,10002が95万行有るとか)によっては
filteringしない場合もあると思う。
>>786 そんなに行数費やしてるのに答えが書いてないということは、知らないってことですね。
「知ってるけど教えてやらない」という態度を取る人は、実は知らないことが
バレてしまうのを恥ずかしがってるだけだからあまり追求してやるなと、
死んだじいちゃんが言ってました。
>>787 コストベースもルールベースも、その記事に書いてますよ。読んでないんですか?
RDBMSごとに違うというよりもスキーマやクエリごとに違うというのが実際だからなぁ。
実行計画見てみなさいとしか答えようがないのでは。
>>791 で、手元にあるRDBMSが出力する実行計画の内容は理解できたの?
>>791 なりすますのは楽しい?
> 先に where や order by で対象行を絞りこんで
元はこのレベルなんだから釣るならもっと上手にお願い
>>781 >join は、where や order by より必ず先に実行されるのでしょうか
答え:いいえ。実際の実行方法はRDBMSが判断して決定します
以上、この話題終了で
春だよな。
おまけに月曜日だよな。
給料もらってSQL書いてるなら、2chで質問せずに自分で調べて考えりゃいいのに。
給料は、2chで回答してもらうため
お勉強熱心なのは良いと思うけど、
それを知ったところで彼にどんなメリットがあるんだろうか。
単純にSELECT文は宣言的であることを理解していないから出てきた質問だと思うよ。
でも組むときは手続き的に考えないとパフォーマンスを考慮できないというSQLの問題
http://mountainbigroad.jp/fc5/mysql_java.html これの最後の[root@linux ~]# java DbTestでうまくいかないのです
[root@localhost /]# java DbTest
java.lang.ClassNotFoundException: org.gjt.mm.mysql.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
〜〜〜
こちらのコマンドでは
[root@localhost /]# java -classpath $CLASSPATH:/usr/share/java/mysql-connector-java-5.1.24-bin.jar DbTest
SQL failed.
java.sql.SQLException: Access denied for user 'centos'@'localhost' (using password: YES)
〜〜〜
という感じです
スレ違いでしたら誘導お願いします
スレチ。一応エスパーしておくとmysqlへのログインの失敗。
user: centos host: localhostというユーザがmysql上に存在するかちゃんと確認。
しかしrootでサンプルをコンパイルして実行したり/usr/shareにJar突っ込んで/etc/profileに
クラスパス追加したりと、色々な意味ですごい解説ページだね。
他のページも見たけど情報古いし(そもそもFC5だし)当時基準で考えても行儀の悪い手順が多い。
他所をあたるのが吉。
>>788 >ケースバイケースとしか言えない
じゃあjoinされる順番は固定ではなく、必要に応じてwhereやorder byよりあとに実行されることがあるというわけですね。
それがわかれば充分です。ありがとうございます。
>>789 > SQL文に ( ) 付ければ、( ) の中から順に処理してくれるよ。
> (落とし穴があることは気がつかないだろうけど)。
こう書くってことでしょうか。
select * from
(select *
from employees
where id in (1000, 1001, 1002)
order by name) as e
join departments d on e.department_id = d.id
たしかにこのほうが、
>>781より1割くらい高速なようです(PostgreSQLの場合)。
つまり、PostgreSQLの場合はjoinのほうを先にやってしまうということなんでしょう。効率悪いなあ。
>>790 > 多分、君が効率良いだろうと思うこと(あるいはそれ以上)は、大抵のRDBMSはやってくれるよ。
そうだといいんですが、上のようにjoinをあとにするよう手作業でSQLを書き換えた方が速い場合もあるので、なんとも。
サブクエリのorder byは(特殊な条件のぞいて)意味が無いんだが
それはともかくとして、ポスグレのオプティマイザそんなに貧弱なのか?
だからさ、まず実行計画の見方を勉強しようよ。
そしてRDBMSによっては、スロークエリーの検出機能があるから、その閾値を100msとかに設定して、
時間がかかるクエリの実行計画を見て、改善点があるかさがすとかしようよ。
807と781は論理的に等価なSELECT文じゃないからね。
781はnameでソートされた結果が保証されるけど807に関してはそうではない。
(仮に807がソートされた結果を返してもそれは「たまたま」)
order by無しで比較するとどうなる?
>>807 > PostgreSQLの場合はjoinのほうを先にやってしまうということなんでしょう
まだ推測ですすめるクセが残ってるね
1割ってのもあいまいな話だし、脱初心者をしたと思っている初心者の状態なのかなぁ
だから落とし穴があると書いといたのに。。。
新人君は駄目だな。
Postgresのドキュメントみるかぎりカッコつけてネストしたクエリもまず一端展開する
みたいだけど。一般論としてはカッコ付けて実行計画を強制出来るかはSQLの仕様上は
無し、実際の動作は実装依存であまり考慮の対象になる方法ではないと思うなぁ。
実行計画の見方がわからなかったので
推測に頼ることにした。
に一票
(分散トランザクションとかリモート問い合わせはスレチ…??)
基本的にSQL関係ないのはスレチ
というか、RDBMSの実装に強く依存するのはそれぞれのスレで聞けよ
日本人の払った貴重な血税から
ゴキブリ在日朝鮮人に生活保護が支払われている
ゴキブリ在日朝鮮人の一家族で年間600万円である
ゴキブリ在日朝鮮人の2人に1人は生活保護だ
これより安い給料で働いている日本人が
少ない給料から支払った税金が
ゴキブリ在日朝鮮人の生活保護になっている
ゴキブリ在日朝鮮人は生活保護をもらって
毎日パチンコをして遊んで暮らしてる
ゴキブリ在日朝鮮人の犯罪者も非常に多い
ヤクザの2人に1人はゴキブリ在日朝鮮人だ
日本社会の寄生虫 ゴキブリ在日朝鮮人
日本から出て行け! ゴキブリ在日朝鮮人
環境:アクセス2007
得点テーブル
日 科目 得点
1/1 英語 80
1/1 国語 50
1/1 数学 90
1/2 英語 70
1/2 国語 70
1/3 国語 60
1/3 数学 80
1/4 英語 60
1/4 国語 60
1/4 数学 60
このようなテーブルから、下記のようにデータを取ってエクセルに張り付けたいのですが
どのようにすればよいでしょうか。
日 英語 国語 数学
1/1 80 50 90
1/2 70 70
1/3 60 80
1/4 60 60 60
↑欲しい結果の表示がおかしいですが
こんな結果が欲しいです
日 英語 国語 数学
1/1 80 50 90
1/2 70 70 ""
1/3 "" 60 80
1/4 60 60 60
>>821 素早い回答ありがとうございます。
環境が会社にしかないので明日試してみます。
だめそうなら別の手を考えてみます。
たとえば
1/3 "" "" ""
のような結果はそのままじゃ作れないよ、と。
こういう結果もほしい場合は
>>8 も組み合わせてね
標準SQLにはないけどアクセスにはクロス集計クエリーていう技があるから
それ使えばいいだけじゃ
最終的にエクセルで処理するんならエクセル側でピボットテーブル使うという手もある
826 :
NAME IS NULL:2013/05/09(木) 18:22:40.24 ID:3HjWO8Ji
助けてください><
新人から以下のような質問きたけど理由がわかりません。。。
「先生。SQLのavg関数はなぜwhere句で使用することができないのですか?」
827 :
826:2013/05/09(木) 18:25:16.79 ID:3HjWO8Ji
質問者です。
あれ?理由って以下でおk?
WHERE句の条件は同一行に対して適用されるからです。
正しい理由としては「SQLの文法がそう決めているから」。
厳密には入れ子クエリーの中のWHERE句では使える場合もあったりと、WHERE句の
中での集約関数の扱いの文法ルールは結構複雑。
informalな理解としては、集約関数はグループテーブル(grouped table)の中の
行グループに適用されるから、という説明が出来ると思う。
グループテーブルというのは元のテーブルを複数の行グループに分割したもので
GROUP BY句を評価した結果として得られる(GROUP BY句がない場合は全ての行を
含むただ一つの行グループからなる暗黙のグループテーブルとして扱う)。
で、SELECT文の評価順序はFROM -> WHERE -> GROUP BY -> HAVING -> SELECT
なので、グループ化される前のWHERE句では集約関数は使えないけれども
グループ化後のHAVINGやSELECTでは使えるという理屈です。
829 :
826:2013/05/09(木) 20:44:45.42 ID:???
>>828 ふむ。。。
他の子はプログラムのメソッド理解してるけどその子はって何?ってレベルの子なので
教えてくれた内容を理解するのは難しいかも(´・ω・`)
教えてくれてありがとうございました
ふむ。
ではエッセンスとしてSELECT文はFROM -> WHERE -> GROUP BY -> HAVING -> SELECT
の順番で評価する、ということだけ教えてはどうでしょうか。
SELECT文が返す結果がどう作られるのか理解するためにも大事な点なので。
そして集約関数はグループを作った後で使えるのでHAVINGとSELECTだけだと。
(厳密にはこの順番で評価した結果と「等価な結果」を返すとか暗黙のグループ
とか色々ツッコミどころはありますがその辺はとりあえず無視で)
831 :
NAME IS NULL:2013/05/09(木) 23:25:42.14 ID:iWf63QvN
mysql5.5使用しております
テーブル結合をした後に最小値を求める勉強しています
テーブルA
uuid,name
1,"田中"
2,"鈴木"
テーブルB
uuid,date
1,"2013-04-04"
2,"2012-03-03"
があるとして
SELECT a.uuid,a.name,MIN( b.date ) FROM a, b WHERE a.uuid = b.uuid
を実行してみると
1,"田中","2012-03-03"というものがかえってきてきてしまいます
832 :
NAME IS NULL:2013/05/09(木) 23:26:32.98 ID:iWf63QvN
申し訳ありません途中で送信してしまいました
1,"田中","2013-04-01"を返してもらう為のsql文を教えて頂けないでしょうか
よろしくお願い致します
04/04 からどうやって 04/01 を導くんだよ? 月初、でいいんか?
834 :
NAME IS NULL:2013/05/09(木) 23:46:43.73 ID:hRjieOLa
MIN( b.date )
これで13年4月を出すのはムリ
835 :
NAME IS NULL:2013/05/09(木) 23:57:17.88 ID:iWf63QvN
申し訳ないです
2、”鈴木”,"2012-03-03" が欲しいと思っています
イメージとして テーブルAとBを結合して
uuid,name,dateになったところで min(date)で一番日付の若い人を見つけようと思っているのですが
うまく行かず
テーブルAの1,"田中"
テーブルBの2,"2012-03-03"
が結果として表示されてしまいます
同じ日付があったら無理だけど、まず、テーブルBから最小の日付をもつレコードのuuidを求めて、
そのuuidでテーブルAと結合。
837 :
NAME IS NULL:2013/05/10(金) 00:57:34.59 ID:H99FPAxg
ありがとうございます
SELECT a.uuid, a.name
FROM a,b
WHERE a.uuid in (select b.uuid,min(b.date) from b)
(select b.uuid,min(b.date) from b) の所をどうすればいいか
テーブルBから最小の日付をもつレコードのuuidを求める方法がわからないのですが
教えて頂けないでしょうか
838 :
NAME IS NULL:2013/05/10(金) 01:08:46.71 ID:6pGPZ1aE
こんな感じでどうでしょうか?
SELECT a.uuid,a.name,b.date
FROM a
INNER JOIN b ON a.uuid=b.uuid
ORDER BY date limit 1
839 :
NAME IS NULL:2013/05/10(金) 01:18:40.11 ID:H99FPAxg
>>838 ありがとうございます
できました!
SELECT a.uuid, a.name, MIN( b.date )
FROM a, b
WHERE a.uuid = ( SELECT b.uuid FROM b ORDER BY date LIMIT 1 )
で同じようなこともできました とても勉強になりました
>>835 >>838で良いと思うが、別方法
>テーブルAとBを結合してuuid,name,dateになったところで min(date)で一番日付の若い人
を素直にSQLで書けば良いだけ
試してないけど
select a.uuid,a.name,b.date from a join b on a.uuid=b.uuid
where b.date=(select min(date) from b)
で行けるはず
mysqlは普通はエラーにならないとダメなSQLが通ったりするからSQLの勉強には向かないと思うぞ
ISO標準に完全に沿って作られてるRDBMSなんてないでしょ
完全にISO標準である必要なんてないけど
どう考えても結果が不定で実行できないSQLをエラーなしで通すのはなぁ
>>839みたいな、とんでもSQLで出来た気になってしまうのは問題だろ
843 :
NAME IS NULL:2013/05/10(金) 01:35:27.33 ID:H99FPAxg
>>840 ありがとうございます
>>840でもで問題なくできました!
>>839 これだめですね
MIN( b.date )がついてたから正しく動いてるように思えただけでした
別にとんでもSQLだとは思わないけど
aテーブルの内容を副問い合わせで表示して
その副問い合わせとは全く無関係なところでb.dateを出しちゃってるから
あんまり良いSQL文だとは言えないかもな
すみません教えてください
【質問テンプレ】
・DB2 9.7
・テーブルデータ
load済。
・欲しい結果
loadしたテーブルを使うサマリ表がエラーとなった場合、
チェックペンディングを解除したい。
・説明
下記の処理を行いました
@テーブルAにデータをロード
Aチェックペンディングになっているのでimmediate checkdをかける
→こっちは成功で、ステータスが「移動なし」に変わる
BテーブルAを使うサマリー表がチェックペンディング状態になる
Cサマリー表にimmediate checkdをかけたら算術オーバーフローで解除できず。
テーブルAのデータを確認したら集計後オーバーフローする値が入っていました
そこで、テーブルAのデータをupdateなどで操作した上で改めて更新したいのですが、
テーブルAの状態を「正常」に戻すにはどうすればよいでしょうか?
サマリー表に対して色々オプションをつけてset integrityしてみましたが、何が何でもリフレッシュしようとしてエラーになります。
イメージとしては、サマリー表をリフレッシュせずにペンディング解除することで、連鎖的にテーブルAも解除されると思っています
テーブルAだけ単独で解除してデータを更新後サマリー表のチェック解除ということもできるのでしょうか?
>>846 ありがとうございます、そちらに書いてみます。
848 :
NAME IS NULL:2013/05/15(水) 20:46:46.85 ID:sLWZCJrM
UNIOの練習をしております
テーブルa
id,price
aaaa,500
テーブルb
id,price
bbbb,600
rrrr,300
テーブルc
id,price
cccc,700
dddd,1000
eeee,900
のデータが入ってるとして
各テーブルを合体させてその後priceの最小値のレコードを表示させたいと思っております
select id,price from a where price = (select max(price) from a)
union select id,price from b where price = (select max(price) from b)
union select id,price from c where price = (select max(price) from c)
だと各テーブルのpriceの最大値が1個ずつ表示され
select id,min(price) from (
select id,price from a
union select id,price from b
union select id,price from c
)
だと#1248 - Every derived table must have its own alias
と表示されてしまいます
合体させてその後priceの最大を持ってくるsql文を教えていただけないでしょうか
よろしくお願いいたします
誤:min(price)
正:max(price)
でした
エラーメッセージの通りだろ。別名使え。
UNION以前に二つ目のクエリはGROUP BY無しでidとmax()がSELECTリストに並んでいる
のでエラーになるね。
SELECTリストからidを外すか、一つ目のクエリと同様に最大値だけ求めてから絞り込みを
する必要がある。
>>850のとおり。
あと、union all の方がいいとおもうよ。
>>851 mysqlだとgroup byなしでできてしまうかもしれない。気持ち悪い。
854 :
845:2013/05/17(金) 09:01:16.91 ID:???
>>845 uncheckedすることで解除できました
算術オーバーフローはロードしたテーブルAのデータを修正してからrefreshをかけることで解決
あと、チェックペンディングになっていたのはサマリー表ではなく間にあるステージング表でした
お騒がせしました
855 :
NAME IS NULL:2013/05/17(金) 19:07:27.79 ID:Fw65R92N
HTAアプリで、JavaScriptを使ってMySQLにアクセスしてみました
JSには当然ですがSQLエスケープ用の関数が用意されていないので、自前でしないといけないですが
単に文字列置換でシングルクオートをエスケープするだけでいいのでしょうか?
856 :
NAME IS NULL:2013/05/17(金) 19:26:56.49 ID:boKr6IGa
htaアプリっていうの知らないんだけどjavascriptでアクセスって時点でセキュリティも何もないんじゃないの?
スレ違い。
自分しか使わないローカルなアプリなので、セキュリティのためというよりは、誤動作防止のためですね
どっちにしろSQLの質問じゃねえ
860 :
NAME IS NULL:2013/05/19(日) 08:59:29.04 ID:zWNrczk3
mysqlです
【authors】
--------------------
id name
--------------------
1 hoge
〜 …
10 fuga
【books】
--------------------------------------
id author_id title
--------------------------------------
1 1 foo
… … …
10000 10 bar
ここからbookを検索したいのですが
select books.* from books join authors on authors.id = author_id where authors.name like '%word%' or books.title like '%word%';
だと重そうなので
select * from books where title like '%word%' or author_id in (select id from authors where name like '%word%');
な感じなのですがこういうときの定番なやり方ありますか?
862 :
NAME IS NULL:2013/05/20(月) 00:23:39.38 ID:QJOCjzcl
ワイルドカードに該当する部分をクエリで参照したい場合、どういう方法がありますか?
update table set col0 = 'ワイルドカード部分' where col1 like '%hoge_hoge%'
のようなことをやりたいのです
ワイルドカードが三箇所になってしまいました
hogeとhogeの間の一文字、ということです
正規表現とかマッチした部分抜き出す機能があるdbmsならできるけど。
じゃなきゃ普通はアプリ側じゃないかな
>>862 update table set col0 = col1 where col1 like 'hoge_hoge';
hogeの部分を空文字列に置換すればいいな。
hoge%と%hogeでANDで検索してsubstringとかでhoge消すのか
>>862 これでどうかな
update table set col0 = replace(col1, 'hoge', '') where col1 like 'hoge_hoge';
真ん中にhogeあったらそれも消えちゃうような
汎用的なのは、SQLだけじゃ無理だろうな。
>>869 _にhogeが入るって事?あったら驚きだね
カラム/テーブルに日本語使っている人いますか?
873 :
NAME IS NULL:2013/05/20(月) 22:30:00.97 ID:3Fvcp97C
使う理由がない
続きの質問が気になってしょうがないけど、それはきっと杞憂で、これが本来の質問なんだろうな。
いるよ。
特定の環境でしか作業しない人なら、
日本語のカラム名、テーブル名使う人いそうな気がする。
876 :
NAME IS NULL:2013/05/20(月) 22:44:45.81 ID:3Fvcp97C
いやいや、SQLの質問スレなんだから「いればその方に聞きたいのですが・・・」と続くはず
>>872が気付くのを待ったほうがいい
無理に英語使うより、税区分とかのほうがわかりやすいというのはある。
878 :
872:2013/05/20(月) 23:32:40.01 ID:???
うちの会社で作っているソフトって、全部カラム・テーブルが日本語なんですね
そして、他の会社も同じく日本語を使っていたわけです。
なので、これは一般的なのかな?と疑問に思って質問しました
在庫管理のシステムなのですが、みなさんは英語でやってますか
うちも在庫管理も含めて色んな業務アプリ作ってるけど、
日本語のテーブル名やカラム名なんてありえないよ。
ローマ字ですら少ない。
基本は英単語や短縮形。
Inventoryとか、Qtyとか、DueDateとか。
人生いろいろ、sqlもいろいろ
どこがSQLの質問なの?
今いる会社はそもそも日本の会社じゃないので当然全部英語だけれども、それ以外にも
専ら規約ベースのORMを使うのでテーブル名やカラム名をアプリのコード内で使われて
いるドメインクラス名やそのプロパティ名と可能な限り一致させているという事情もある。
クラス名やプロパティ名が英語なのでテーブルやカラムの名前も自動的に英語になる。
日本語での開発であっても例えばJavaだとHibernateなどJPA系のORMを使うのであれば
英語のテーブル名カラム名を使った方が断然楽だと思う。
さもなければ名前マッピングを全部書き下すか、開発者にクラス名等々に日本語を使えと
お願いすることになりそう(日本語のクラス名等でORMがきちんと動くかも謎)。
スレ違いネタはいらないから。
つか、専用のスレ立ってるじゃん。
そっち書けばいいじゃん。
じゃんじゃん。
t1
ID KEY HOGE
-----------------------
1 a 5
1 b 7
2 a 5
2 b 8
3 a 4
3 b 4
4 b 9
4 d 2
t2
ID KEY PIYO
-----------------------
1 a 7
1 b 1
1 c 1
1 d 5
2 a 2
2 c 8
3 a 7
4 c 6
t3
ID KEY NYAN
-----------------------
1 d 5
2 a 5
2 d 7
3 b 4
3 c 3
3 d 2
4 d 7
5 b 1
こういう3つのテーブルから
t1で KEY a b を
t2で KEY c を
t3で KEY d且つNYAN 5以上を持っているID1と2のみを取り出したいのですがどうすればいいでしょうか
なんだか崩れてしまいましたすみません
t1
ID KEY HOGE
-----------------------
1 a 5
1 b 7
2 a 5
2 b 8
3 a 4
3 b 4
4 b 9
4 d 2
t2
ID KEY PIYO
-----------------------
1 a 7
1 b 1
1 c 1
1 d 5
2 a 2
2 c 8
3 a 7
4 c 6
t3
ID KEY NYAN
-----------------------
1 d 5
2 a 5
2 d 7
3 b 4
3 c 3
3 d 2
4 d 7
5 b 1
まぁJOINって何? なんだろうけど。
運が良ければ誰かがSQL書いてくれるかもしれないしな。
890 :
NAME IS NULL:2013/05/21(火) 20:27:50.23 ID:4o/NXjFR
SQL書くのは楽なんだけどテスト用のデータベース作るのが面倒くさい
テーブルの結合条件がわからん
最終的に欲しいデータもよくわからん
検索条件っぽいのもわからん
t1で KEY a b を どうなの?
t2で KEY c を どうしたいの?
t3で KEY d且つNYAN 5以上を持っているID1と2のみを取り出したい
select * from t3 where KEY=d and NYAN>5 and ID in (1,2)
892 :
NAME IS NULL:2013/05/21(火) 21:29:34.50 ID:4o/NXjFR
IDがユニークじゃない…
893 :
872:2013/05/22(水) 00:01:12.70 ID:???
英語だとこんな感じになりますか?
商品コード → ProduceCode
納入先住所1/2/3 → CustormZip1/2/3
在庫数(総バラ) → Piece
在庫数(ケース数) →Unit
----------------------------------------------
テーブル名
出庫依頼 → info_order_list
oracle形式で明細テーブルのコード、区分をキーに、
コードマスタの名称を2種類を外部結合で取得したいです。
何か足りないようでエラーになります。宜しくお願いします。
select
親テーブル .親コード
子テーブル.コード
a.名称
b.名称
from
親テーブル
子テーブル
コードマスタ a
コードマスタ b
where 親テーブル.親コード =子テーブル.親コード
and 明細テーブル.コード =a.'ZZ'
and 明細テーブル.コード =a.コード (+)
and 明細テーブル.コード =b.'YY'
and 明細テーブル.コード =b.コード (+)
>>893 あまりにも違いすぎる。わざと間違えてるとしか考えられん。
商品はItem
納入先≠顧客=Customer≠Custorm
住所≠郵便番号=ZipCode
出庫依頼=ShippingOrder
PieceとUnitの使い方も変よ。
で、いつまでスレ違い続けるの?
899 :
NAME IS NULL:2013/05/22(水) 13:29:28.02 ID:SXOouUvj
お前がぶり返さなきゃ終わってたよ
900 :
NAME IS NULL:2013/05/22(水) 18:24:07.93 ID:SXOouUvj
t1:
id data1 data2 data3
11 good bad bad
12 bad good bad
13 good bad good
t2:
data score
good 100
bad 0
2つのテーブルがあり、t1にidに対する各データに対する評価
t2にはその評価に対する点数が入っています。
ここからテーブルを結合し、t1.idに対する、data1,data2,data3の点数を拾いたいと思っています。
その際、この場合は3回結合するしかないのでしょうか?
902 :
NAME IS NULL:2013/05/22(水) 18:34:03.54 ID:SXOouUvj
やっちゃったな・・・ID
基本的にはそうだろうけど、オプティマイザがうまいことやってくれそうな気がするな。
>>6で逆にAもBもCも持っていない、ID:02と03を取り出すにはどうしたらいいんですか?
間違えました
>>6と逆のパターンで
(問)
ID HOGE
01 B
01 E
02 A
02 F
03 C
03 G
04 D
04 F
ここからAもBもCも持っていない、ID:04を取り出すにはどうしたらいいんですか?
Havingで3にならないやつ。
Having 4以上なら当然無し
2ならA,B,Cの中からどれか2つを持っている値
1ならA,B,Cの中からどれか1つを持っている値になりますよね
Hving 0では当然駄目ですが
0でA,B,Cの中からどれか0個を持っている値を得られるならそれを得たいんです
よろしくお願いします
not in でいいだろ。
>>907 A,B,Cのどれかひとつでも持っているIDの一覧を取得し、
その一覧にないIDを選択
NOT INでは無理です
>>909 直接得るの難しいですか
ありがとうございます
>>910 こんな感じじゃないかな
SELECT distinct id
FROM TableName
WHERE id not in
(SELECT id
FROM TableName
WHERE hoge in ('A','B','C'));
SQL Serverでストアド書くときどのように書いてますか?
OracleだとPACKAGEがあるのでVBっぽく書けますが、SQL Serverはちょっとイメージがつかないです。
ゆとりw
春だからな。
馬鹿には無理
馬鹿には無理さんてここにもいたのか
スレ違い。
過疎ってるからなんでしょ。
SQL Serverスレでスルーされてただけだろ
このスレでストアドが対象外だと思うならスルーしとけば
スルーされるだけだから親切心で言ってるんだろ
ストアドは対象外。
925 :
NAME IS NULL:2013/05/27(月) 03:01:24.47 ID:qPx1TzON
MySQLでの並べ替えについてなのですが
score | address
200 おおさか
350 きょうと
180 ひょうご
100 おおさか
150 きょうと
↓↓
score | address
100 おおさか
200 おおさか
150 きょうと
350 きょうと
180 ひょうご
addressの中の最小値でソートして、最小値に続けて同じaddressの値をscore順に並べていくというソートを行いたいのですが、どのようなSQLが書けますか?
926 :
NAME IS NULL:2013/05/27(月) 03:02:21.54 ID:qPx1TzON
> addressの中の最小値
訂正
同じaddressの中のscoreの最小値
group by
こんな感じかな。
SELECT T.score, T.adress
FROM T, (
SELECT MIN(score) as minscore, adress
FROM T
GROUP BY T.address
) S
WHERE T.adress = S.adress
ORDER BY minscore, address, score
ORDER BYにaddressも入っている点がポイント。これが入っていないと
同じ最小値を持つadressが複数ある場合に期待したように動かない。
なんだかクレージーな印象
>>929 「最小値でソートして」という所が問題なんだろ。
order by address desc,score desc
でダメなん?
>>931 180 ひょうご ← 120だったら、きょうとの前にこないといけない
200 おおさか
350 きょうと
120 ひょうご ←並べ替えの評価に使う(2番)
100 おおさか ←並べ替えの評価に使う(1番)
150 きょうと ←並べ替えの評価に使う(3番)
↓
100 おおさか ←並べ替えの評価に使う(1番)
200 おおさか
120 ひょうご ←並べ替えの評価に使う(2番)
150 きょうと ←並べ替えの評価に使う(3番)
350 きょうと
>>935 この程度のことも分からずにプログラマやっていけてる?
体裁は良くないが、聞きたいことと内容は明確だろ。
937 :
NAME IS NULL:2013/05/28(火) 03:30:47.95 ID:pJTxBQZ+
アンカー間違ってるのか読む場所間違ってるのか区別付かんなw
こういうの、ウィンドウ関数できれいに書けたりするのかな?
あれが独自拡張なのか標準SQLにあるものなのかわかんないけど
>>936が安価ミスなのか、安価の先を見誤ったか、はたまた別かわからなくてもやっとする
プログラマならバグ直してください
>>939 窓関数はSQL2003から標準だけれどもどのRDBMSでも実装されているかは微妙。
無難にSQL92の範囲で書くなら
>>928みたいなサブクエリーを使う書き方になる。
でも確かに窓関数使うとスッキリ書ける。
SELECT score, address FROM T
ORDER BY MIN(score) OVER (PARTITION BY address), address, score
>>940 SQL2003からなのね。ありがとです。
すごいすっきりしてるし直感的だ、やっぱ使えるようにしとかないと。重ね重ねどもでした
再帰構造のテーブルをSQLで辿る事は可能でしょうか?
id parent value
1 null aaa
2 1 bbb
3 2 ccc
4 3 ddd
5 2 eee
このようなテーブルで4の親を辿って最初にid in (1,2)を満たすvalue(bbb)を探したいです。
DBはpostgresql9.3betaです。
944 :
NAME IS NULL:2013/05/30(木) 18:21:17.05 ID:zDo8DD4s
DB: oracle10g
テーブルにprimary key 制約(以下pk制約)を作成すると、
pk制約と同じ名前のunique indexが作られます。
このunique indexの名前をpk制約作成時に指定することは出来ますか?
作成後にalter indexで変更できることは確認済みです。
alter table TableA add constraint PK_CONST primary key (...);
select * from user_constraints where table_name = 'TableA';
select * from user_indexes where table_name = 'TableA';
pk制約、indexともに'PK_CONST'の名前になっている。
create table TableA (COLNAME number constraint PK_CONST primary key);
制約名とインデックス名を違う名前にしたいという話なら
unique indexを先に作れば
primary key using index インデックス名
でできるにはできるけど
>>945-947 ありがとうございました。
(1) create table
(2) create unique index
(3) alter table add constraint primary key using index
の順番で意図したことが実現出来ました。
一応、下記の方法でも可能でした。
DDLが分かれている方が都合が良かったので採用してません。
create table aaa (
a int,
constraint pk_const primary key (a)
using index (create unique index index_const on aaa(a))
);
950 :
NAME IS NULL:2013/06/07(金) 17:32:29.57 ID:yGnvQyXR
可能な限り、DB依存になるような構文を書きたくないんだけど
DB依存構文検出チェッカーみたいなのって、世の中にある?
952 :
NAME IS NULL:2013/06/09(日) 13:39:06.60 ID:DY/9Y4Gb
MySQLについての質問です。
highscoreというテーブルに、id, scoreという2つのカラムがあります。
idのインデックスはPRIMARYです。
POSTでidとscoreの値が送られてきたとき、
そのidが既に登録されている場合、送られてきたscoreが登録されているscoreより大きければ、そのidのscoreを更新し、
送られてきたidがまだテーブルに存在しなければ、新規レコードとしてINSERTしたいのですが、
条件分岐の部分でどのようなSQLを書けばよいのか検討がつきません。
何かヒントをいただければ幸いです。よろしくお願いします。
SQLじゃなくてストアドでやる話。
そんなたいそうなもんじゃなかろう。
やり方は色々思いつくけど、SQL文を2つ発行するのが初心者向けかな。
SQL二つ発行するのは、本来なら分離レベルとかロック制御とか考慮しないといかん
最近のDBMSなら1文で出来るやつもあるから、MySQLで使えるかどうか調べてみたら
upsertとか、mergeとか言われてるやつな
>>952 idが 1 で、入れようとしている score が 9999 の場合
INSERT INTO highscore (id, score) VALUES (1,9999)
ON DUPLICATE KEY UPDATE score = IF(score<9999, 9999, score);
でできると思います。
存在しない id ならそのまま INSERT、存在する id ならば IF で
DBの score より大きければその値を、同じか小さければ元の値でUPDATE。
ちょっとスマートじゃないね。
958 :
952:2013/06/09(日) 17:45:07.54 ID:???
御回答いただいた皆様大変ありがとうございました。
>>957さんの方法で実装できました。
scoreが更新されていなくてもUPDATEするのが無駄に思えますが、
とりあえずこれで運用してみます。
ストアドプロシージャについても調べてみます。
ありがとうございました。
959 :
NAME IS NULL:2013/06/13(木) 04:44:36.45 ID:gtAIlzh6
質問させてください
アマゾンとかでよくある商品の評価ポイントを集計するクエリを作りたいです
アマゾンと少し違うのは、商品そのものの評価ポイントではなく、
商品を登録した出品者くくりでの、「その出品者が出品した全ての商品の評価ポイント」の平均値をとることです
まとめると、
・特定の出品者の出品した商品の評価ポイントの平均値をとる
・同時に、レビューの件数をとる
・判明してるキーはt_prof.keyのみです
テーブルは以下の通り。
レビューtable =t_review
===============================
reviewId -- int(11) :プライマリキー、auto_increment
workId -- int(11) :商品のID
userId -- int(11) :出品者のID
point -- tinyInt(1):評価ポイント(1〜5)
出品者プロフィールtable =t_prof
===============================
userId -- int(11) :プライマリキー、auto_increment
namae -- text :出品者の名前
key -- int(3):キー。ユニーク
どんなクエリを書いたらいいんでしょうか
すみません、よろしくお願いします
1回の出品に対する評価は何回?
複数のの出品者が「同じ商品」を複数個出品することがある?
「判明しているキー」に「プライマリーキー」が含まれていないが?
「サンプルデータ」と「欲しい結果」を出してくれ
これだけなら、出品者IDでgroup byしてavgとcountでよくないか?
where userId = (select userId from t_prof where key = 判明しているキー)
select p.namae,avg(r.point),count(r.point) from t_review r,t_prof p where r.userid=p.userid group by r.userid;
こんなんでどお?
動かしてないけど、p.namaeがgroup byにないってエラーがでそう。
mysqlだったらどれかひとつが勝手に選ばれるという話だったかも
>>959 t_prof.keyは何に対してユニークなんだ
評価はNULLはあり得るのかとかその場合は評価件数に加えるのかとか
いろいろ詰まってないところがあるが
select t_prof.userId,count(*),avg(point)
from t_review join t_prof on t_review.userId=t_prof .userId
where t_prof.key=判明してるキー
group by t_prof.userId
とかで良いんじゃね
始めたばかりでググりましたがよくわかりません
結果がなしなのを0で返したいのです
T-sql
select @test=data from db where 除外内容
宣言済のtestに0か数字を入れたいのです
sumなりで返せばいいだろ。
>>966 SQLの話から外れるけど、ホスト言語側で大概、結果のレコード数を返す
関数が用意されているから、それで見るのが比較的常套だと思うけど。
それをサブクエリーにして、レコード数を集めたりしているのであれば
count()を使えばいいんじゃないかね。
>>966 ISNULL関数使え
つか特定DBの話はそこで聞け
>>967 SUMは対象が全てNULLならNULL返す
>>968 あれレコード数見てるんじゃないぞ
970 :
959:2013/06/14(金) 23:24:15.62 ID:???
>>960-965 ありがとうございます
COUNTやAVGの使い方を復讐しつつそれぞれ参考にさせていただきます
復讐は何も生まないよ
Revengeコマンド、作る?
Living Well Is The Best Revenge
974 :
NAME IS NULL:2013/06/15(土) 16:04:10.91 ID:FktO2NAp
どなたかお願いいたします。
私初心者で「ゼロから始めるデータベースSQL」という本で勉強をしています。付属のソフトをインストールしてパスワードを入れて書いてある通りにやってるんですが最初のテーブルを作るところでエラーが出てしまい困ってます。
Create table shohin;
と入れると
";"またはその近辺でエラーと出ます。
これはなぜでしょうか。
よろしくお願いします。
975 :
NAME IS NULL:2013/06/15(土) 16:15:53.30 ID:FktO2NAp
すみません。
中身何も入れてないからか!?と思い、書いてある通りに入れたら、
プライマリキーはテーブル"shohin"に暗黙的なインデックス"shohin_pkey"を作成します
と出たのですが、これはテーブルを作成できたんでしょうか
976 :
NAME IS NULL:2013/06/15(土) 16:19:55.22 ID:FktO2NAp
ごめんなさい。
できてるみたいです
日本語でおKって話ですよね
初心者すぎました
すみません!
書いてる通りにやってないだろ。
初心者に素直さを期待してはいけない
本当の初心者は、めんどくさそうな手順は後からやろうと飛ばすものだ。
問題は飛ばしたことをすっかり忘れることだなw
981 :
NAME IS NULL:2013/06/16(日) 15:21:55.25 ID:uKsaBYgK
中身何も入れてないってどういうこっちゃ?
データベース作ってないのにテーブル作ろうとしたのかこいつ
> Create table shohin;
って書いてるだろうw
>>981 カラム定義
列は後回しにして、とりあえずテーブルを作ってみようって思ったのかも。
斬新な発想だな。
プロには想像もつかない。