ジメジメする梅雨のお悩み、一挙解決! >>

■table a のテーブル構成
date a_id b_id c_id a_count
■table b のテーブル構成
date a_id b_id c_id b_count value

上記の2つのテーブル構成から、
■date a_id b_id c_id毎の集計データ
date a_id b_id c_id a_count b_count value
を抽出するSQLが知りたいです。

table aにあって、table bに存在しない。又は逆もある為、
union
しかないと思うのですが、思いつきません。。

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

A 回答 (5件)

たびたびすみません。



訂正版です。もしよろしければ、お試しください。

select
ifnull(A.`date`,B.`date`) as `date`,
ifnull(A.`a_id`,B.`a_id`) as `a_id`,
ifnull(A.`b_id`,B.`b_id`) as `b_id`,
ifnull(A.`c_id`,B.`c_id`) as `c_id`,
 a_count,b_count,`value`
from A
left join B
on A.`date`=B.`date`
and A.a_id=B.a_id
and A.b_id=B.b_id
and A.c_id=B.c_id
union
select
ifnull(A.`date`,B.`date`) as `date`,
ifnull(A.`a_id`,B.`a_id`) as `a_id`,
ifnull(A.`b_id`,B.`b_id`) as `b_id`,
ifnull(A.`c_id`,B.`c_id`) as `c_id`,
 a_count,b_count,`value`
from A
right join B
on A.`date`=B.`date`
and A.a_id=B.a_id
and A.b_id=B.b_id
and A.c_id=B.c_id
    • good
    • 0

#3です。



#3のSQLでは、重複排除がうまく行きません。
失礼しました。
    • good
    • 0

>今回は取得するカラムが結合するテーブル毎に異なるので一発


UNIONだけでは無理なので

これはどういう意味でしょうか?
質問にある「やりたいこと」に、変更はないのですよね?

(date,a_id,b_id,c_id)で、お互いを対応付けているのでしょうか?

前半がAにだけあるもの、AとB両方にあるものを検索し、
後半がBにだけあるもの、AとB両方にあるものを検索、
unionで繋げるとともに(AとB両方にあるものの一方を)重複排除です。

前半と後半で、leftとrightの指定と、selectの並びで両方にある列をA側にするかB側にするかを変更するだけですよ?

select
A.`date`,A.a_id,A.b_id,A.c_id, # A側を表示
 a_count,b_count,`value`
from A
left join B # Bに対応行がない場合あり
on A.`date`=B.`date`
and A.a_id=B.a_id
and A.b_id=B.b_id
and A.c_id=B.c_id
union
select
B.`date`,B.a_id,B.b_id,B.c_id, # B側を表示
 a_count,b_count,`value`
from A
right join B # Aに対応行がない場合あり
on A.`date`=B.`date`
and A.a_id=B.a_id
and A.b_id=B.b_id
and A.c_id=B.c_id
    • good
    • 0

full [outer] joinは、MySQL 5.1時点でも、未サポートになっています。


MySQL 5.0.19での動きを確認して見たところ、full joinに完全に蓋はされておらず、構文エラーにならずに動いてしまうこともありますが、full joinの動きではありません。

MySQL 5.0.xなら、left join + right join + unionで代替できます。

SQL例としては、次のような指定になります。

select * from t1 left join t2 on t1.c1=t2.c1
union
select * from t1 right join t2 on t1.c1=t2.c1
    • good
    • 1
この回答へのお礼

full outer joinというのがオラクル等にはあるのですね。ありがとうございます。

教えていただいたSQLは大変すばらしいのですが、今回は
取得するカラムが結合するテーブル毎に異なるので一発
UNIONだけでは無理なので、SQLを2回流して、
プログラムの方でデータを作成するという結論に至りました。

お礼日時:2007/07/27 11:49

mysqlのバージョンによって処理がことなります。



今回の案件は完全外部結合なので4.1以降・・・かな

テンポラリを使えば3.23系でも実現は可能です
    • good
    • 0
この回答へのお礼

完全外部結合というのですね。ありがとうございます。
すみませんバージョン書いていませんでした。
MySQL5.0.22になります。
テンポラリも検討してみますね。

お礼日時:2007/07/27 10:33

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

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

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

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

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

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

QSQL文について(片方のテーブルに存在しないレコード抽出)

以下のような2つのテーブルがあったとして、
2つともに存在する「店コード」を抽出するのはSQLは分かるのですが、
片方に存在しない「店コード」(以下の例の場合、「2」)を抽出するSQLを
一文で書くにはどうすればいいのでしょうか?

<店テーブル>
店コード住所・・・(その他、基本情報)
1aaa
2bbb
3ccc

<販売テーブル>
店コード販売品目・・・(その他、販売数など)
1xxx
3zzz

Aベストアンサー

オプティマイザ次第だけど、NOT-INは、あまりお勧めでない。
外部結合も索引があっても有効に使われないので、お勧めでない。

select * from A where not exists(select 1 from B where A.店コード=B.店コード);

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

Q片方のテーブルに存在しないレコード取得したい

OracleのSQL文を教えて下さい。

-tableA-
key1,key2
001,1
002,2
002,1
003,2

-tableb-
key1,key2
001,1
002,1

取得したいレコード
002,2
003,2

お願いします。

Aベストアンサー

select * from tableA
where not exists (
select * from tableB
where tableA.key1 = tableB.key1
and tableA.key2 = tableB.key2
);

でどうでしょう?

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q表の結合について

2つのテーブルがあります。(それぞれNo列が主キーです)

表A(名称:Tbl_A)に2レコードあります。
No, Str  ←列名
10,str_1  ←データ
20,str_2  ←データ

表B(名称:Tbl_B)に2レコードあります。
No, Name  ←列名
10,Name_1 ←データ
30,Name_3 ←データ


このテーブルを結合して、以下のデータ(3レコード)を抽出するSQL文を教えてください。

No, Str, Name   ←列名
10,str_1,Name_1 ←データ
20,str_2,(null) ←データ
30,(null),Name_3 ←データ


ポイントは、「どちらかの表にあるデータは全て抽出したい」ということです。
よろしくお願いします。

Aベストアンサー

幹を作って、外部結合。

select a.no,b.str,c.name
from
(select no from tbl_a union select no from tbl_b) a,
tbl_a b,
tbl_b c
where a.no=b.no(+) and a.no=c.no(+)
;

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

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システムでも
使える可能性が高い)かと思います。

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

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を使うとか、レコードの更新時刻を突っ込むとか。

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む


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

人気Q&Aランキング

おすすめ情報