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で違うテーブルの値を比較して値に差」の質問画像

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

A 回答 (4件)

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システムでも
使える可能性が高い)かと思います。
    • good
    • 1
この回答へのお礼

後者のものが使うこと出来ました
大変参考になりました
ありがとうございます!

お礼日時:2010/09/05 09:21

No.1です。


自分への返信の後半部分はNo.2さん宛のものですかね?
DB2は触ったことがないのですが、MINUSの代わりに EXCEPT を使えばよさそうです。

SELECT
A1,A2,A4
FROM Aテーブル
EXCEPT
SELECT
B1,B2,COUNT(*)
FROM Bテーブル
GROUP BY B1,B2
    • good
    • 1
この回答へのお礼

ありがとうございます 助かりました!

お礼日時:2010/09/05 09:20

考え方を整理します。


(1)BテーブルのB1、B2をキーとして件数を取得
(2)Aテーブル上で同じキーを持ち、かつ(1)の数と
  A4の値が異なるものを抽出

SELECT A.* FROM Aテーブル A
INNER JOIN
(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
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
Oracleで上記のような結果を得たいと思っていた次第なのですが、私が間違いをしておりました。
DB2 9.5が大元になっており一部のデータをOracleへコピーしています。
Oracle側はBテーブルを持っていないためOracleではそもそも比較しようがないことがわかりました。
そこで大元のDB2でやってみたのですが、どうやらせっかく御教示いただいたSQLがエラーになってしまします。

意味がよくわからなくて大変申し訳ないのですが、ご回答いただいたSQLの構文でJOINの後に“(”があると
無効な識別子みたいなエラーを吐き出します。
規格とかが根本から違うのでしょうか?

本当にポカミスですみません。。。

お礼日時:2010/08/24 21:26

記載の内容が全てで難しいこと考えなくていいなら、minusを使ってはいかがでしょうか?



SELECT
A1,A2,A4
FROM Aテーブル
MINUS
SELECT
B1,B2,COUNT(*)
FROM Bテーブル
GROUP BY B1,B2

これでBテーブルの件数とA4の値が一致しないAテーブルのレコード(全項目ではないですが)が抽出できます。

余談ですが、B1は主キーとは言わないです。主キーとはテーブル内の一意のレコードを特定できるものを言います。
あと、Oracleのバージョンも書いた方がいいと思います。バージョンによって使用できるSQLも違ってきますので。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
Oracleで上記のような結果を得たいと思っていた次第なのですが、私が間違いをしておりました。
DB2 9.5が大元になっており一部のデータをOracleへコピーしています。
Oracle側はBテーブルを持っていないためOracleではそもそも比較しようがないことがわかりました。
そこで大元のDB2でやってみたのですが、どうやらせっかく御教示いただいたSQLがエラーになってしまします。

意味がよくわからなくて大変申し訳ないのですが、ご回答いただいたSQLの構文でJOINの後に“(”があると
無効な識別子みたいなエラーを吐き出します。
規格とかが根本から違うのでしょうか?

本当にポカミスですみません。。。

お礼日時:2010/08/24 21:26

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

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

Qyyy/mm/dd/形式

データベースから
yyy/mm/dd/形式
で取得するsql文を教えて下さい

サーバ
19991111

表示
1999/11/11

すいませんなぜが自分が実行すると
エラーになります

Aベストアンサー

一度日付型に変換して、再度CHARに変換すれば
問題なくいけると思います。
(to_dateとto_char関数を使用します。)

to_char(to_date(FIELD_NAME,'YYYYMMDD'),'YYYY/MM/DD')
でいけると思います。

Q14桁の日付(YYYYMMDDHHMMSS)を日付(YYYY/MM/DD)に変換できますか?

データとして14桁の値で日付が登録されています。
この14桁の値(YYYYMMDDHHMMSS)を日付(YYYY/MM/DD)に変換できますか?
やりたい事はこの14桁の値から現在の日付から過去1年以内のデータを取得したいと思っていますが・・・
どのようにしたらいいのでしょうか?
申し訳ありません、アドバイスいただけませんでしょうか?
宜しくお願いします。

Aベストアンサー

こんにちわ。

> この14桁の値(YYYYMMDDHHMMSS)を日付(YYYY/MM/DD)に変換できますか?
文字型データを日付に変換するのであれば、TO_DATE() を使用します。
単純に変換する場合は、to_date(col, 'YYYYMMDDHHMISS') です。
※ 時間は24時間表記の'HH24' の可能性もあるので確認して下さい。

今年1の1月1日からと言う事であれば、変換した日付を年で切り捨てます。
→ trunc(to_date(col, 'YYYYMMDDHH24MISS'))
正確に1年前であれば、add_months で12ヶ月前を算出します。
→ add_months(to_date(col, 'YYYYMMDDHH24MISS'), -12)
更に月で切り捨てれば、該当月の1日を算出できます。
→ trunc(add_months(to_date(col, 'YYYYMMDDHH24MISS'), -12), 'MM')

OTN Japan (http://www.oracle.com/technology/global/jp/index.html)
でマニュアルを入手できますので、詳細はSQL リファレンスで確認して下さい。

こんにちわ。

> この14桁の値(YYYYMMDDHHMMSS)を日付(YYYY/MM/DD)に変換できますか?
文字型データを日付に変換するのであれば、TO_DATE() を使用します。
単純に変換する場合は、to_date(col, 'YYYYMMDDHHMISS') です。
※ 時間は24時間表記の'HH24' の可能性もあるので確認して下さい。

今年1の1月1日からと言う事であれば、変換した日付を年で切り捨てます。
→ trunc(to_date(col, 'YYYYMMDDHH24MISS'))
正確に1年前であれば、add_months で12ヶ月前を算出します。
→ add_months(to_date(col, 'YYYY...続きを読む

QSQL xx件目からxx件目までを抽出したい

SQLを習いはじめました。
ユーザーIDが100件あるテーブルの30件目~50件目の
ユーザIDを抽出し、別テーブルに登録をしたいと思っています。
『このxx件目からxx件目まで』の抽出のしかたがわかりません。
どなたかわかる方がいましたら教えてください。

DECLARE
CURSOR cursor_name IS SELECT USER_ID FROM TBL_USERID ;
getid VARCHAR2(16);
ryear NUMBER := '2008';
ryear2 NUMBER := '08';
rmonth NUMBER;
rday NUMBER;
usercnt NUMBER;
rcnt NUMBER := '0';
--処理開始
BEGIN
SELECT count(USER_ID) INTO usercnt FROM TBL_USERID ;
OPEN cursor_name ;
LOOP
FETCH cursor_name INTO getid ;
EXIT WHEN cursor_name%NOTFOUND;

--月でループ(1~12月)
For rmonth IN 1..12
LOOP
--日でループ(1~22日)
For rday IN 1..22
LOOP
--スケジュール1件目
rcnt := (rcnt + 1);
INSERT INTO TBL_SCH
(
SCHEDULE_ID
,USER_ID
,UPDATE_DATETIME
) VALUES (
ryear || Trim(TO_CHAR(rmonth,'00')) || Trim(TO_CHAR(rday,'00')) || Trim(TO_CHAR(rcnt,'00000000'))
,'getid'
,SYSTIMESTAMP
);
END LOOP;
END LOOP;
END LOOP ;
CLOSE cursor_name ;
END ;

SQLを習いはじめました。
ユーザーIDが100件あるテーブルの30件目~50件目の
ユーザIDを抽出し、別テーブルに登録をしたいと思っています。
『このxx件目からxx件目まで』の抽出のしかたがわかりません。
どなたかわかる方がいましたら教えてください。

DECLARE
CURSOR cursor_name IS SELECT USER_ID FROM TBL_USERID ;
getid VARCHAR2(16);
ryear NUMBER := '2008';
ryear2 NUMBER := '08';
rmonth NUMBER;
rday NUMBER;
usercnt NUMBER;
...続きを読む

Aベストアンサー

分析関数を使った例。SQL SERVER2005から、ORACLEなら8iのEE(9iからはSTANDARD EDITIONも)から使えます。
SELECT A.*
FROM
( SELECT *,ROW_NUMBER() OVER( ORDER BY ソートキー項目 ) RN
FROM テーブル名 ) A
WHERE RN BETWEEN 30 AND 50

Qテーブルの項目が異なるテーブルの結合方法

こんばんは。
すみませんが、下記のように出力するSQLを教えて下さい。

[処理table]のstatusが「新規」のに該当する場合、[処理table]の内容を、
[処理table]のstatusが「新規」のに該当しない場合、[処理ログテーブル]
の「日付」が現在日付に近い内容のみを出力する。

 氏名 project名 status 日付
------+----------+-------+-------
 鈴木 softA  新規
 大塚 softB  承認   08/20
 大沢 softC  新規

を期待しています。
SQLの経験が少ない為、悩んでます。
「UNION ALL 」について調べて見ましたが、カラム数が異なるのでNGと判断
しました。
「それぞれの条件の結果を縦につなげて…」とイメージしてみたのですが、
それに相当する資料が見当たらず、悩んでいます。
tableの[処理ログtable]の「日付」を[処理table]の項目とすればよ
いのですが、現在のDB設計がこのようになってしまっているので、改善できま
せん。

補足もしますので、お忙しいところすみませんが、宜しくお願いします。

-説明-

[顧客table](主キー:顧客ID)
顧客ID 氏名
------+-------
020001 鈴木
020002 大塚
020003 大沢

[処理table](主キー:通番(自動発番))
通番 顧客ID projectID status
----+-------+----------+-----------
0001 020001   0001 新規
0002 020003   0003 新規
0014 020002   0004 承認

[処理ログtable](主キー:通番(自動発番))
通番 顧客ID projectID status 日付
----+-------+----------+-------+------
0032 020002   0004 修正  08/02
0033 020002   0004 修正  08/15
0034 020002   0004 承認  08/20

[projecttable](主キー:projectID)
projectID project名
---------+----------------
  0001 softA
  0002 softB
  0003 softC
  0004 softF

こんばんは。
すみませんが、下記のように出力するSQLを教えて下さい。

[処理table]のstatusが「新規」のに該当する場合、[処理table]の内容を、
[処理table]のstatusが「新規」のに該当しない場合、[処理ログテーブル]
の「日付」が現在日付に近い内容のみを出力する。

 氏名 project名 status 日付
------+----------+-------+-------
 鈴木 softA  新規
 大塚 softB  承認   08/20
 大沢 softC  新規

を期待しています。
SQLの経験が少ない為、悩んでます。
「UNION ALL...続きを読む

Aベストアンサー

こんにちは、

> カラム数が異なるのでNGと判断しました。
status が「新規」の場合、NULL を日付として返してやれば、
UNION ALL でOk ですょ。

QPL/SQLでの集計とテーブルの結合の仕方

いつもお世話になっております。
pl/sqlでの処理なのですが、タイトルのとおり
テーブルの結合と集計で分からないところがあり、
こちらで質問させていただきました。

処理内容は
あるグループでレコードを集計し、
そのグループが重複する他のテーブルと結合したいと
考えております。

【テーブル1】
(班) (回数) (秒)
aaa| 10| 100
aaa| 20| 200
bbb| 10| 150
bbb| 20| 100
ccc| 10| 100
ccc| 30| 250
: : :

まずこれを集計し、件数を追加して
(班) (回数) (秒) (件)
aaa| 30| 300| 2
bbb| 30| 250| 2
ccc| 40| 350| 2
: : : :

というようにまとめ、

【テーブル2】
(年月) (班) (円)
200904| aaa| 1000
200905| bbb| 1500
200904| ccc| 2000
: : :

というテーブルと結合して
(年月) (班) (回数) (秒) (円×件)
200904| aaa| 30| 300| 2000
200905| bbb| 30| 250| 3000
200904| ccc| 40| 350| 4000
: : : : :

という形にしたいのですが可能でしょうか?
例に挙げたのは3件しかありませんが
テストデータは1万件以上ありそれを処理します。
初心者なので、テーブルの結合の仕方、
集計の仕方が分からず行き詰っております。
どなたか、お力を貸していただけないでしょうか。
よろしくお願いいたします。

いつもお世話になっております。
pl/sqlでの処理なのですが、タイトルのとおり
テーブルの結合と集計で分からないところがあり、
こちらで質問させていただきました。

処理内容は
あるグループでレコードを集計し、
そのグループが重複する他のテーブルと結合したいと
考えております。

【テーブル1】
(班) (回数) (秒)
aaa| 10| 100
aaa| 20| 200
bbb| 10| 150
bbb| 20| 100
ccc| 10| 100
ccc| 30| 250
: ...続きを読む

Aベストアンサー

select
テーブル2.年月 "年月",
テーブル2.班 "班",
テーブル1集計結果.回数計 "回数",
テーブル1集計結果.秒計 "秒",
テーブル1集計結果.件 * テーブル2.円 "円×件"
from
(select 班,sum(回数) 回数計,sum(秒) 秒計,count(*) 件 from テーブル1 group by 班) テーブル1集計結果,
テーブル2
where テーブル1集計結果.班=テーブル2.班
;


このQ&Aを見た人がよく見るQ&A

おすすめ情報