【先着1,000名様!】1,000円分をプレゼント!

SQL文のみを用いて値の検索結果を元にまた検索を行い、さらにその結果をもとに検索結果の中身を参照して比較する方法を探しています。

例として、データベース内に図のような4つのテーブルがあるとします。
地域情報Aと都道府県名A、地域情報Bと都道府県名Bはセットと考えます。
地域情報には、地域ごとに対応する番号があり、都道府県名には地域情報の番号と、それに対応した件名が記述してあります。
(例えば、東北は001番で、001番(東北)には青森・岩手が存在する、と読みます)

このようなデータベースがあるとき、入力として「中部」「北陸」があったとします。
すると、1つ目の入力(中部)は地域情報Aからその番号を探し,その番号を元に都道府県名Aから県名を探します。
同様にして、2つ目の入力(北陸)もBのテーブルから値を検索します。
すると、1つ目の入力に対して「愛知・福井」、2つ目の入力に対しては「福井・石川」が出力されます。
最後に、1つ目の出力結果と2つ目の出力結果を比較して、同じ都道府県名が含まれていれば 1 を、含まれていなければ -1 を出力します。
ここではどちらも「福井」が含まれているので、最終的な出力結果は「1」になります。

ということをやりたいと思っています。
現在、C言語で、2つの出力結果(県名)をそれぞれ配列に格納して、2つの配列の中身を比較、for文とstrcmpで配列に一致する県名があるかを確認、ということをしていますが、
入力に応じてSQL問い合わせが4回と配列の中身の一致比較のためにfor文を2重に回しているため、実行速度が遅いのが気になります。

これをC言語を使わず、SQL文のみで完成させるには、どういったSQL文を書けば良いのでしょうか?
また、実際に実行するとして、データ検索にSQL・一致比較にC言語を使う場合、全てSQLのみで実行する場合 ではどちらが処理時間が短くなるのでしょうか?
ただし、実際は地域情報A・Bにはレコードが1000件以上、都道府県名A・Bには各地域ごとにレコードが5件程度あることを想定しています。
今回は例のためこのような書き方になっていますが、実際に扱うデータに文字列はなく、すべて数値データです。

長文になってしまいましたが、対応の仕方を知りたいと思っています。
よろしくお願いします。

「SQLで複数データベースの一致比較する方」の質問画像

このQ&Aに関連する最新のQ&A

A 回答 (1件)

すなおにやればこんな感じでしょうか?



//準備
create table tiikiA(id int,name varchar(30));
create table tiikiB(id int,name varchar(30));
create table kenA(id int,name varchar(30));
create table kenB(id int,name varchar(30));
insert into tiikiA values(1,'東北'),(2,'関東'),(3,'中部'),(4,'九州');
insert into tiikiB values(1,'関西'),(2,'中国'),(3,'四国'),(4,'北陸');
insert into kenA values(1,'青森'),(1,'岩手'),(2,'埼玉'),(2,'千葉'),(3,'愛知'),(3,'福井'),(4,'鹿児島');
insert into kenB values(1,'大阪'),(2,'鳥取'),(3,'徳島'),(4,'福井'),(4,'石川');

//実行
select if(count(*)>0,1,-1) as kekka from
(select kenA.name from kenA
inner join tiikiA on tiikiA.id=kenA.id
and tiikiA.name='中部') as subA
inner join
(select kenB.name from kenB
inner join tiikiB on tiikiB.id=kenB.id
and tiikiB.name='北陸') as subB
on subA.name=subB.name;
    • good
    • 0
この回答へのお礼

ありがとうございます.
SQLでこんな処理も可能だったんですね.
このくらいの処理がさらっと書けることを目指して頑張ります.
処理時間がCと併用するときに比べて約1/10になりました.

お礼日時:2012/01/15 00:36

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSQLで違うテーブルの値を比較して値に差があるレコードを抽出したいので

SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
下に例を作ってみました。(テキストに貼りなおしてもらうと見易くなると思います)
<Aテーブル>
A1A2A3A4A5
------- ------- ------- ------- ----------
XXXXXXX XX1ABC32009/05/08
WWCWWCW WW2CCB12008/03/21
DDDDDDD DD1JPN52007/08/08
GGGGGGG GX9SOX21977/01/04
FFFFFFF USJNPB32001/09/11


<Bテーブル>
B1B2B3B4B5
------- ------- ------- ------- ----------
XXXXXXX XX1ibichaoshimu2002/07/05
XXXXXXX XX1takeshiokada2005/07/15
XXXXXXX XX1kamoshu1857/09/25
WWCWWCW WW2waowao2008/10/22
DDDDDDD DD1uihhh2006/06/30
DDDDDDD DD1jojoj x5xx1999/09/09
DDDDDDD DD1momohara2005/03/07
DDDDDDD DD1itaiu-2003/12/22
DDDDDDD DD1komanogoal2007/04/26
GGGGGGG GX9 damerecord2009/11/14
FFFFFFF USJ ikitai1995/08/15
FFFFFFF USJ sstebuspi2004/01/05
FFFFFFF USJ bbpp2009/08/23

A1とB1は主キー、A2とB2は副キーです。
Aテーブルの「A4」カラムにはBテーブルのレコード数を持っています。(主キー、副キーが同じものの)
しかし、よくよく見るとAテーブルの「GGGGGGG」のA4には「2」のはずなのにBテーブルには実際にレコードは1つしかありません。
こういう状態になってしまっているのを割り出したいのですがどのようにA4とBテーブルで数があってないものを抽出できるでしょうか。
よろしくお願いいたします。

SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。
下に例を作ってみました。(テキストに貼りなおしてもらうと見易くなると思います)
<Aテーブル>
A1A2A3A4A5
------- ------- ------- ------- ----------
XXXXXXX XX1ABC32009/05/08
WWCWWCW WW2CCB12008/03/21
DDDDDDD DD1JPN52007/08/08
GGGGGGG GX9SOX21977/01/04
FFFFFFF USJNPB32001/09/11


<Bテーブル>
B1B2B3B4B5
------- ------- ------- ------- ----------
XXXXXXX XX1ibichaoshimu200...続きを読む

Aベストアンサー

SELECT A.* FROM Aテーブル A
INNER JOIN
TABLE(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2) B
ON A.A1=B.B1 AND A.A2=B.B2
AND A.A4<>B.SU

または

WITH B(B1,B2,SU) AS
(SELECT B1,B2,COUNT(*) SU
FROM Bテーブル GROUP BY B1,B2)
SELECT A.* FROM Aテーブル A
INNER JOIN B ON A.A1=B.B1
AND A.A2=B.B2 AND A.A4<>B.SU

こんなのでどうでしょうか?
後者の方が標準的(他のDBシステムでも
使える可能性が高い)かと思います。

Qテーブルの差分をとる結合

TableAとTableBがあります。構造は同じです。
中身は下記のようだとします。
TableA      TableB
ID VALUE     ID VALUE
1 A       3 C
2 B       4 D
3 C       

差分結合結果を下記のようにとりたいのです。
1 A
2 B
4 D

良い方法をご存じでしたら、ご教授よろしくお願い致します。

Aベストアンサー

SQL Server 2005 以降であれば、EXCEPT が使えるので、TableA - TableB と TableB - TableA の結果を UNION してやれば良いかと。
http://codezine.jp/article/detail/1304?p=2

例) --------------------------------------------------------------
(SELECT * FROM TableA
EXCEPT
SELECT * FROM TableB)
UNION ALL
(SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA);
------------------------------------------------------------------

EXCEPT が使えないバージョンの場合は、 NOT EXISTS を使って差分を抽出してやれば良いでしょう。

例) --------------------------------------------------------------
SELECT * FROM TableA
WHERE NOT EXISTS (
SELECT 'X' FROM TableB
WHERE TableA.ID = TableB.ID AND TableA.VALUE = TableB.VALUE
)
UNION ALL
SELECT * FROM TableB
WHERE NOT EXISTS (
SELECT 'X' FROM TableA
WHERE TableA.ID = TableB.ID AND TableA.VALUE = TableB.VALUE
)
------------------------------------------------------------------

SQL Server 2005 以降であれば、EXCEPT が使えるので、TableA - TableB と TableB - TableA の結果を UNION してやれば良いかと。
http://codezine.jp/article/detail/1304?p=2

例) --------------------------------------------------------------
(SELECT * FROM TableA
EXCEPT
SELECT * FROM TableB)
UNION ALL
(SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA);
------------------------------------------------------------------

EXCEPT が使えないバージョンの場合は、 NOT ...続きを読む

Q異なるDBの値比較方法

まったく同じジョブの内容でスケジューリング方法を変えて実行した時、その前後でDBの内容が同一であるか検証する方法を考えています。

DBはoracle9、テーブル数は約100強、エクスポートすると約500MBです。

検証方法は、処理前に本番データをエクスポートし、それを検証環境にインポート、検証環境でスケジュールを実行して、まったく同じ結果を得られるかを検証します。

以下の案を思いつきましたが、イマイチぴんときません。何かいい方法を教えてください。

案1 DBをDBリンクで接続し、オブジェクトブラウザのオブジェクト比較機能を使う。
→簡単にできるが、結果を得るの時間がかかりすぎる。

案2 DBをDBリンクで接続し、検証用プロシージャを作成して比較する。
→user_tables, user_tab_columnsなどを使うプロシージャの作成が面倒。

案3 処理実行後に、本番と検証環境でそれぞれテーブルごとにエクスポートし、エクスポートファイルをUNIXでソートした上で、uniqコマンドで比較する。
→これが現実的?

まったく同じジョブの内容でスケジューリング方法を変えて実行した時、その前後でDBの内容が同一であるか検証する方法を考えています。

DBはoracle9、テーブル数は約100強、エクスポートすると約500MBです。

検証方法は、処理前に本番データをエクスポートし、それを検証環境にインポート、検証環境でスケジュールを実行して、まったく同じ結果を得られるかを検証します。

以下の案を思いつきましたが、イマイチぴんときません。何かいい方法を教えてください。

案1 DBをDBリンクで接続し、...続きを読む

Aベストアンサー

案3のエクスポートは、オラクルのエクスポート形式だと、
バイナリ形式(独自フォーマット)ですので、ソートができません。

CSVなどのテキスト形式で抜き出す必要があります。
その際、ORDER指定すれば、抜き出した後にソートの手間は
割愛できると思います。

Q同一テーブル内での比較(最新データによる比較)

大変申し訳ありません。本日も質問させてもらったのですが、一部情報(履歴)が不足していて追加で質問させてください。
以下のようなテーブルがあり、価格が異なるところを差額一覧を出したいと思っております。
(先ほどは2名の方に回答頂き、すみませんベスト10の設定がわからず設定できなくて、すみませんでした。)

【テーブル構成】
商品ID、商店ID、価格(円)、履歴

というテーブルがあり、

商品A、商店1、1000、1
商品A、商店2、1500、1
商品A、商店3、800、1
商品A、商店1、2000、2
商品A、商店2、2500、5
商品A、商店3、1800、3
商品B、商店1、2000、1
商品B、商店2、1700、1
商品B、商店3、2600、1
商品B、商店1、2500、4
商品B、商店2、2000、6
商品B、商店3、2800、7
・・・(多くの商品データがあります)

というデータが格納されております。
商品と商店の区分ごとに履歴の最も大きいものを取り出し (←追加)
商店1を基準に、商品毎に商店2、3の価格差を大きい順にソートして出したいと考えています。
SQL分ではどのように記載すれば良いでしょうか?

(実際に比較したデータは以下を抽出し)【履歴の古いのは無視】
商品A、商店1、2000、2
商品A、商店2、2500、5
商品A、商店3、1800、3
商品B、商店1、2500、4
商品B、商店2、2000、6
商品B、商店3、2800、7
・・・(多くの商品データがあります)


(今回の場合の希望出力が以下のような感じです。)
価格差、商品名、商店 (←綱目です。)
800、商品B、商店3
500、商品A、商店2
-200、商品A、商店3
-500、商品B、商店2

ご教授頂けると幸いです。
ちなみに、教えて頂いたSQLをもとに以下のようにやってみましたが、うまくいきませんでした。。。
全くよくわかっていません。少し解説を入れて頂けると幸いです。
------------------------------------
SELECT
a.価格 - b.価格 AS 価格差,
a.商品ID AS 商品名,
a.商店ID AS 商店
FROM 対象テーブル a
INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1')
WHERE a.商店ID <> '商店1'
AND a.履歴 = (SELECT MAX(a.履歴)) AND b.履歴 = (SELECT MAX(b.履歴)) 【←追加】
ORDER BY a.価格 - b.価格 DESC;
----------------------------------------
select
t2.価格-t1.価格 as 価格差
,t1.商品名
,t1.商店
from テーブル1 as t1
left join
(
select 価格,商品 from テーブル1 where 商店=商店1
) as t2 on t1.商品 = t2.商品
where t1.商店<>商店1
AND a.履歴 = (SELECT MAX(a.履歴)) AND b.履歴 = (SELECT MAX(b.履歴)) 【←追加】
ORDER BY t2.価格 - t1.価格 DESC;

大変申し訳ありません。本日も質問させてもらったのですが、一部情報(履歴)が不足していて追加で質問させてください。
以下のようなテーブルがあり、価格が異なるところを差額一覧を出したいと思っております。
(先ほどは2名の方に回答頂き、すみませんベスト10の設定がわからず設定できなくて、すみませんでした。)

【テーブル構成】
商品ID、商店ID、価格(円)、履歴

というテーブルがあり、

商品A、商店1、1000、1
商品A、商店2、1500、1
商品A、商店3、800、1
商品A、商店1、2000、2
商品A、商...続きを読む

Aベストアンサー

商品B-商店3の価格差は 2800 - 2500 なので300になる気がしますが・・・。

それで良いのなら、下記の様なSQLでよろしいかと。

----------------------------------------
SELECT
a.価格 - b.価格 AS 価格差,
a.商品ID AS 商品名,
a.商店ID AS 商店
FROM 対象テーブル a
INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1')
WHERE a.商店ID <> '商店1'
AND a.履歴 = (SELECT MAX(履歴) FROM 対象テーブル c WHERE a.商店ID = c.商店ID AND a.商品ID = c.商品ID)
AND b.履歴 = (SELECT MAX(履歴) FROM 対象テーブル d WHERE b.商店ID = d.商店ID AND b.商品ID = d.商品ID)
ORDER BY a.価格 - b.価格 DESC;
----------------------------------------

a, b, に対して、それぞれ、商店IDと商品IDが同じものの中で履歴が最大の行だけを抽出しています。
同じ事は EXISTS 句を使っても表現できます。

----------------------------------------
SELECT
a.価格 - b.価格 AS 価格差,
a.商品ID AS 商品名,
a.商店ID AS 商店
FROM 対象テーブル a
INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1')
WHERE a.商店ID <> '商店1'
AND NOT EXISTS (SELECT * FROM 対象テーブル c WHERE a.商店ID = c.商店ID AND a.商品ID = c.商品ID AND a.履歴 < c.履歴)
AND NOT EXISTS (SELECT * FROM 対象テーブル d WHERE b.商店ID = d.商店ID AND b.商品ID = d.商品ID AND b.履歴 < d.履歴)
ORDER BY a.価格 - b.価格 DESC;
----------------------------------------

こっちは a, b, に対して、それぞれ、商店IDと商品IDが同じでそれより履歴が大きな行が存在しないものだけを抽出しています。
結果として、商店IDと商品IDが同じものの中で履歴が最大の行を取出す事になり、前のSQLと同じ意味になります。

また、サブクエリーで絞り込んでしまい、それを INNER JOIN する方法も有りますね。

----------------------------------------
SELECT
a.価格 - b.価格 AS 価格差,
a.商品ID AS 商品名,
a.商店ID AS 商店
FROM
(
SELECT * FROM 対象テーブル c
WHERE 商店ID <> '商店1'
AND NOT EXISTS (SELECT * FROM 対象テーブル d WHERE c.商店ID = d.商店ID AND c.商品ID = d.商品ID AND c.履歴 < d.履歴)
) a
INNER JOIN
(
SELECT * FROM 対象テーブル e
WHERE 商店ID = '商店1'
AND NOT EXISTS (SELECT * FROM 対象テーブル f WHERE e.商店ID = f.商店ID AND e.商品ID = f.商品ID AND e.履歴 < f.履歴)
) b
USING (商品ID)
ORDER BY a.価格 - b.価格 DESC;
----------------------------------------


http://gihyo.jp/dev/serial/01/sql_academy2/000901
http://gihyo.jp/dev/serial/01/sql_academy2/000902
http://codezine.jp/article/detail/907

商品B-商店3の価格差は 2800 - 2500 なので300になる気がしますが・・・。

それで良いのなら、下記の様なSQLでよろしいかと。

----------------------------------------
SELECT
a.価格 - b.価格 AS 価格差,
a.商品ID AS 商品名,
a.商店ID AS 商店
FROM 対象テーブル a
INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1')
WHERE a.商店ID <> '商店1'
AND a.履歴 = (SELECT MAX(履歴) FROM 対象テーブル c WHERE a.商店ID = c.商店ID AND a.商品ID = c.商品ID)
AND b.履歴 = (SELEC...続きを読む

Qテーブルの差分を抽出したいのですが。。。

mysqlでUSER_TABLとUSER_CHK_TABL一致しないデータ全てを出力したいのですがmysqlだと『NOT EXISTS』が使えないので困ってます。

TABLE構造はUSER_TABLとUSER_CHK_TABLも下記です。
create table USER_TABL (USERNAME varchar(255),MAIL_ADDRESS varchar(255));

oracleならこんな感じかと思ったのですが。。。
select * from USER_TABL
where NOT EXISTS (select * from USER_CHK_TABL)

Aベストアンサー

>ご回答頂いたSQLはUSER_TABLに存在しUSER_CHK_TABLに存在しないレコードが全て抽出可能ですか?

はい。
LEFT JOIN をして、USER_CHK_TABLに該当するレコードがない場合、カラムの値がNullになることを利用したSQLです。

>お互いのTABLEに存在しないレコードの抽出する事も可能ですか?

#1のSQLのテーブルを逆にしたら、
「USER_CHK_TABL に存在し、USER_TABL に存在しないレコードを抽出」はできます。
UNION がつかえれば、くっつけておしまいなんでしょうけど。
それ以外の方法は残念ながら思いつきません。

Q別のDBからテーブルをコピーする方法

SQL Server2005 Express Edition を使っています。
異なるDB間(同じコンピュータ内)で、テーブルをコピーしたいの
ですが・・・
コピー元DB名:DB_A
コピー元テーブル名:dbo.顧客
コピー先DB名:DB_B

テーブルのコピーは select * into ・・・ from ・・・ を使えばできそうですが、別DBの場合の方法がわかりません。
お教えいただければ幸いです。
よろしくお願いいたします。

Aベストアンサー

別のDBでも同じインスタンス内ならば同じです。

SELECT * INTO DB_B.dbo.顧客 FROM DB_A.dbo.顧客

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

Q他のデータベースとのテーブル結合

いつもお世話になっております。
VB.netでwindowsアプリケーションの作成しているところです。
SQLサーバーのテーブルを参照していますが、テーブルの結合は同じデータベース内にないと結合できないのでしょうか?

'SQL接続処理
Dim strConn As String = "Password='';User ID=sa;Initial Catalog=test;Data Source=server1"

と、testというデータベースがありその中に幾つかテーブルがあります。
このtestデータベースにないテーブルが必要になり、aaaデータベース内の
テーブルを結合しようとしたのですが、出来ません。
Catalog=test,aaaとやってみたり、SELECT * FROM tbl1,aaa.tbl2などとしてみましたが、遠いようです。
SQLのクエリを使って、テーブルの追加をすると同じデータベース内のテーブルしか出てこないので、出来ないのかなと思っていますがどうでしょうか?

わかる方がいましたら教えてください。

いつもお世話になっております。
VB.netでwindowsアプリケーションの作成しているところです。
SQLサーバーのテーブルを参照していますが、テーブルの結合は同じデータベース内にないと結合できないのでしょうか?

'SQL接続処理
Dim strConn As String = "Password='';User ID=sa;Initial Catalog=test;Data Source=server1"

と、testというデータベースがありその中に幾つかテーブルがあります。
このtestデータベースにないテーブルが必要になり、aaaデータベース内の
テーブルを結合しよう...続きを読む

Aベストアンサー

select * from tbl1,[aaa].[dbo].[tbl2]
のように、[データベース名].[オーナー].[テーブル名]の様式で指定すれば、良いかと思います。
(当然、権限の問題がない前提ですが・・)

Qデータベース内のテーブル名の取得

お世話になります。
初心者的な質問でしたらすいません。
SQL文にてデータベース内のテーブル名を
調べることができると聞いたことがあるのですが、
可能でしょうか。

もし、可能であれば、SQLの記述を教えてください。
お願いします。

Aベストアンサー

select * from tab;

私の場合、テーブル名だけ手っ取り早く知りたいとき、↑を打ちます。その他の情報も知りたいときは#2さんの仰るとおり、user_tablesで取得します。

QあるDBから別のDBのテーブルをselectしたい

mysqlのデータベースAとBが存在するとして、
Aをuseしている状態で、Bのデータベースのテーブルをselectするには、どのような構文でSQLを実行すればよいでしょうか。

Aベストアンサー

現在ログイン中ユーザー名で、B のデータベースへのアクセス権を持っているなら、table名の前にデータベース名を付けるだけですよ。
select * from B.tablename

show databases;
で、表示されるデータベースなら可能でしょう。


人気Q&Aランキング