マンガでよめる痔のこと・薬のこと

SQl勉強中の初心者です
結合したテーブルのSUMの値が思うように集計できません。
以下のような2つのテーブルがあったとします。

テーブルA
Date,ConNo
2016-05-15,test001
2016-05-15,test001
2016-05-25,test002
2016-05-25,test002
2016-05-25,test002

テーブルB
ConNo,line,Amt
test002,1,1500
test002,2,1500
test002,3,1500

select A.Date,A.ConNo,Sum(B.RAmt) as B_sum
from テーブルA A left outer join テーブルB B on A.ConNo= B.ConNo
group by A.Date,A.ConNo
into :arDate,:arConNo,:arAmt;

テーブルAを主として、group byしたときに、対応するテーブルBをSUMしたいのですが、
SUMした値が以下のようにデータ数分倍になってしまいます。
2016-05-15,test001,0
2016-05-25,test002,13500

以下のような結果にする場合は、どう書けばいいのでしょうか?
2016-05-15,test001,0
2016-05-25,test002,4500


宜しくお願いします

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

A 回答 (2件)

なんかテーブルAのデータの持ち方がSQLらしくない


2016-05-15,test001が2つあって
2016-05-25,test002が3つある必要があるのでしょうか?
それぞれのデータの相関関係はあるのでしょうか?
テーブルの設計についてすこし知識を深めたほうが良いと思います

今のものを使う前提であれば一度テーブルAをユニークなデータに
つぶしてから、結合するのが妥当ですが

SELECT A.Date,A.ConNo,Sum(B.Amt) as B_sum
FROM (select DISTINCT Date,ConNo
from tableA ) AS A
left join tableB as B on A.ConNo= B.ConNo
group by A.Date,A.ConNo

ただしこの場合、2016-05-15のSUMは0ではなくNULLです
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

おっしゃる様にデータだけ見ると意味ある構造なの?
ってなりますよね。
今回の質問では必要項目しか載せていないので、余計にそう思われたのかもしれません。
ただ、テーブル設計についても知識は深めていければと思っています。

今日は外出なので、後日試してみます。

お礼日時:2016/06/02 12:59

たぶん



テーブルA
Date,ConNo,line

にして

select A.Date, A.ConNo, sum(B.Amt)
from A
left join B on A.ConNo = B.ConNo and A.line = B.line
group by A.Date, A.ConNo

とすれば解決
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

今日は外出なので、後日試してみます。

お礼日時:2016/06/02 13:00

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

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

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

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

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

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

Q複数のテーブルから値を合計出力するSQLについて

複数のテーブルから値を合計出力するSQLについて

以下の様な3つのテーブルがあり、それぞれのテーブルから値を合計した結果を取得したいと思っております。
この場合のSQL文をご教授いただけないでしょうか?
拙い説明でお分かりに難いかと思いますが、何卒、宜しくお願いします。

●テーブル

t1(テーブル1)
id, 会員ID, 日付, 金額

t2(テーブル2)
id, 会員ID, 日付, 金額

t3(テーブル3)
id, 会員ID, 日付, 金額


●期待する結果
上記、テーブル内の会員ID、日付が同じものの金額を合計して取得。(1行で出力)
いずれかのテーブルに「会員ID」が一つしか存在しない場合も、「日付」、「金額」を取得して「合計金額」に反映。
もし、各テーブル、レコードの「金額」が「0」または「null」の場合は「0」として処理する。


●期待出力結果イメージ

会員ID | 日付 | 合計金額 |
--------------------------------
m001 | 2011/07/20 | 1500 |
--------------------------------
m001 | 2011/06/10 | 2000 |
--------------------------------
m002 | 2011/06/05 | 1000 |
--------------------------------
m003 | 2011/05/25 | 0 |
--------------------------------
m001 | 2011/03/05 | 3000 |

※「合計金額」は、「t1(テーブル1)」~「t3(テーブル3)」の中に含まれていた金額の合計。

複数のテーブルから値を合計出力するSQLについて

以下の様な3つのテーブルがあり、それぞれのテーブルから値を合計した結果を取得したいと思っております。
この場合のSQL文をご教授いただけないでしょうか?
拙い説明でお分かりに難いかと思いますが、何卒、宜しくお願いします。

●テーブル

t1(テーブル1)
id, 会員ID, 日付, 金額

t2(テーブル2)
id, 会員ID, 日付, 金額

t3(テーブル3)
id, 会員ID, 日付, 金額


●期待する結果
上記、テーブル内の会員ID、日付が同じものの金額を合計して取得。(1行で出力...続きを読む

Aベストアンサー

UNIONでt1,t2,t3でテーブルを1個に結合して
Group ByすればOK?

「金額」が「0」または「null」の場合は「0」はNVLで対応


Select 会員ID, 日付, NVL(SUM(金額),0) AS 合計金額 From (
Select 会員ID, 日付, 金額 From t1
UNION ALL
Select 会員ID, 日付, 金額 From t2
UNION ALL
Select 会員ID, 日付, 金額 From t3
)
Group By 会員ID, 日付

QMySQLのselect文で、最大ID値のデータを呼び出す

MySQLのテーブルのフィールド名として「ID」を登録しています。(型はint)
そこで、select文で最大ID値のデータを呼び出すにはどうすればいいのか教えて頂けないでしょうか?

select * from tableA ?????;

Aベストアンサー

MySQL4.1以上で副問い合わせが利用できるはずです。
もっと単純に
SELECT MAX(ID)
 FROM tableA;
とかでもいけそうですけど…全カラム必要なのでしょうか?

参考URL:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/mysql_12.htm

Q3つ以上のテーブルを結合できるか?

初歩的な質問で申し訳ありません。
タイトル通りなのですが、MySQLで、同時に3つ以上のテーブルを結合することは可能でしょうか?
また、可能な場合はどのような命令を出せばいいのでしょうか?
よろしくお願いします。

Aベストアンサー

select * from table1 inner join table2 on table1.id = table2.id inner join table3 on table1.id = table3.id;
とかで確かいける・・・と思います。

Qinner joinをすると数がおかしくなります

SQLのinner joinについてお教え下さい。環境はWin 7 MYQL5です。

t1テーブルのデータ
ID,在庫
001,22

t2テーブルのデータ
ID,出庫
001,17
001,3

SELECT
Sum(t1.stock) AS `在庫`
FROM
t1
where id = '001'

上記SQLの結果は22と表示されます。

SELECT
Sum(t1.stock) AS `在庫`
FROM
t1 INNER JOIN t2 on t1.id = t2.id
where id = '001'

とやると、結果が44になってしまいます。
なぜそんな結果になってしまうのでしょうか?

結果はt1.stockは在庫22なので、22と表示するようにしたいです。
よろしくお願いいたします。

Aベストアンサー

#1の方の回答のようにグループ化
しなければ2レコード出力されます。
22×2だから44は当然の帰結です。
おそらくやりたいことは以下のこと
でしょう。
SELECT A.z AS `在庫`,B.*
FROM (SELECT SUM(stock) AS z
FROM t1 WHERE id='001'
GROUP BY id) A
INNER JOIN t2 B ON A.id=B.id

Qjava 電卓 平方根

こんにちは。趣味でプログラミングをしているものです。
さっそくですが質問させていただきます。

Java で文具店で1000円くらいで売っているような電卓を再現
しようとしているのですが
平方根のボタンを押したときの処理でつまづいています。

3 を入力して平方根のボタンを押すと以下のサイトに表示されている限りにおいては
同じ数値になります。

http://ja.wikipedia.org/wiki/3%E3%81%AE%E5%B9%B3%E6%96%B9%E6%A0%B9

ここで質問の内容について説明させていただきます。
Windows に標準で付属している電卓では
0.5 を入力して平方根のボタンを押し続けると
最後には 1 が表示されます。
ですが、以下に示す自分のコードだと
0.99999999998 と表示されてその後
平方根のボタンを押し続けても同じ結果になります。
0.99999999998 で収束しているのだと思いますが、
(自分の作った電卓では小数点以外の数字は12個表示されるようになっています。)
1 に収束するようにするには、
以下に示す メソッドsqrt 内の計算部分の
割り算のスケールの指定とかを変えれば
うまくいくのでしょうか?
-----------------------------------------------
平方根のボタンを押したときの処理です。
case CalculatorEvent.TYPE_SQRT :
if( negativeflag )
{
if( ! display.showBigMinus )
showNumString = showNumString.substring( 1 );
}
result = sqrt( new BigDecimal( showNumString ) );

//test statement
System.out.println( "from 1446 : " + result.toString() );

result = result.setScale( 32, RoundingMode.HALF_UP );

showNumString = result.toString();
//test statement;
System.out.println( "sqrt result : " + showNumString );
//
.
.
.
.
//以下おもに端数を表示桁数に丸めて、
//負の値の平方根を求めたときは
//絶対値の平方根を求めて表示
// エラーであるマークも表示
// 呼び出し元に例外を投げる
// 呼び出した側で例外を受け取ると
// 電卓のボタンを入力できないようにする
-----------------------------------------------
上記コード test statement は以下の出力結果になると
以後 平方根のボタンを押しても同じ結果が出力されます。

from 1446 : 0.9999999999899999999999499999999994999999999937499999999125000000078125

sqrt result : 0.99999999998999999999995000000000

------------------------------------------------
上記コード中のメソッド sqrt です。

private BigDecimal sqrt( BigDecimal value )
{
BigDecimal two = new BigDecimal( "2" );
BigDecimal x = value.divide( two );
BigDecimal last_x = BigDecimal.ZERO;
BigDecimal gap = x.subtract( last_x );

BigDecimal range = BigDecimal.ONE.movePointLeft( 64 );
BigDecimal t;
while( gap.compareTo(range) > 0 )
{
last_x = new BigDecimal( x.toString() );
//t = value.divide( x, 64, BigDecimal.ROUND_DOWN );

//test statement
t = value.divide( x, 64, RoundingMode.HALF_EVEN );
//
x = x.add( t ).divide( two );
gap = x.subtract( last_x ).abs();
}

return x;
}
-----------------------------------------------
長文になりもうしわけありませんが、
ごぞんじのかた、教えていただけないでしょうか?
よろしくお願いします。

こんにちは。趣味でプログラミングをしているものです。
さっそくですが質問させていただきます。

Java で文具店で1000円くらいで売っているような電卓を再現
しようとしているのですが
平方根のボタンを押したときの処理でつまづいています。

3 を入力して平方根のボタンを押すと以下のサイトに表示されている限りにおいては
同じ数値になります。

http://ja.wikipedia.org/wiki/3%E3%81%AE%E5%B9%B3%E6%96%B9%E6%A0%B9

ここで質問の内容について説明させていただきます。
Windows に標準で付属している電卓...続きを読む

Aベストアンサー

>0.5 を入力して平方根のボタンを押し続けると
>最後には 1 が表示されます

数学的に言うと
X<1の時√X=1になる事は在り得ません
限りなく1に近づくことはあってもX<1の時√X<1です

>自分の作った電卓では小数点以外の数字は12個表示されるようになっています

精度にこだわる計算を行うのであれば
0.9999999999999…=1
が計算結果として表示されるのはまずいのではないでしょうか?

Q平方根 ニュートン法について

こんにちは。趣味でプログラミングをしているものです。
さっそくですが、質問させていただきます。

Javaで文具店などで1000円くらいで市販されている
電卓を再現しようとしているのですが、
質問させていただきたいのは、
平方根の計算についてです。
--------------------------------------------
まずは以下のメソッドのコードを見ていただきたいのですが・・・

このメソッドを用いて3の平方根を求めてみました。

private static BigDecimal sqrt( BigDecimal value )
{
BigDecimal two = new BigDecimal( "2" );
BigDecimal x = value.divide( two );
BigDecimal last_x = BigDecimal.ZERO;
BigDecimal gap = x.subtract( last_x );

BigDecimal range = BigDecimal.ONE.movePointLeft( 11 );//(a)
//int cnt = 0;//(b)
BigDecimal t;
while( gap.compareTo(range) > 0 )//(c)
//while( cnt < 20 )//(d)
{
last_x = new BigDecimal( x.toString() );
t = value.divide( x, 64, BigDecimal.ROUND_DOWN );
x = x.add( t ).divide( two );
gap = x.subtract( last_x );//(e)
//cnt ++; //(f)
}
return x;
}

(a)(c)(e) を用いて実行すると
1.732142857142857142857・・・
と小数部分の142857 が循環する値になりました。

(a)(c)(e) をコメントアウトして
(b)(d)(f) を用いて実行すると
1.732050807568877293527446341505872366942805253
810380628055806979425806427001953125
とwikipedia の「3の平方根」の記事の値と
記述されている範囲では同じ値が得られました。
--------------------------------------------
そこで質問なのですが、
(1)
(a) (c) (e) を用いた場合には、正しい値を得られないのでしょうか?
条件に設定する値などを変えてもだめなのでしょうか?
(2)
自分が作っている電卓では12桁の表示を予定しているのですが
その場合、メソッド sqrt ないの cnt は while ループ内で
いくつまで、インクリメントすればよいのでしょうか?
(3)
インターネットで調べたこのアルゴリズムは
「ニュートン法」だそうですが、
y = x^2 - C の グラフ、接線などを書いてみて
ある程度理解できたのですが、

http://cpplover.blogspot.jp/2010/11/blog-post_20.html

上記サイトではこのアルゴリズムは
バビロニア人の方法(Babylonian method)
というものだそうですが、
バビロニア人は二次関数の微分はわかっていた、
ということでしょうか?
--------------------------------------------
ご存知のかた、教えていただけないでしょうか?
よろしくお願いします。

こんにちは。趣味でプログラミングをしているものです。
さっそくですが、質問させていただきます。

Javaで文具店などで1000円くらいで市販されている
電卓を再現しようとしているのですが、
質問させていただきたいのは、
平方根の計算についてです。
--------------------------------------------
まずは以下のメソッドのコードを見ていただきたいのですが・・・

このメソッドを用いて3の平方根を求めてみました。

private static BigDecimal sqrt( BigDecimal value )
{
BigDecimal two = new BigDeci...続きを読む

Aベストアンサー

示したtoString()による数字の表示例は、BigDecimalクラスのリファレンスより引用したものであります。
BigDecimalは、数字と小数点の有効桁数(スケール)を情報として持ちます。
#1の回答時は、一度toStringで渡しているため、スケールの情報も正しく渡るのか否か疑問がありました。クラスリファレンスの例のように帰ってしまうと2~3桁くらいで丸まってしまわないか、と。

混乱させてしまい申し訳ありません。

-----

再現して確認してみましたが、(a)(c)(e)の場合、

条件判定に使うgapの作り方
gap = x.subtract( last_x );//(e)

ループ終了判定
while( gap.compareTo(range) > 0 )//(c)

この条件がよくなさそうです。この条件によって、ループを2回しか回っていないので結果の精度が良くない。(b)(d)(f)の場合でも、ループを2回実行した場合の結果は、(a)(c)(e)と同様でした。

(1)条件判定に用いるgapの作り方
gap = x.subtract( last_x );//(e)

Xn (プログラム上変数x) と、 Xn-1 (同じくlast_x) の大小関係が保証できないので(一回目のxに依存する)、last_xとxの変化量は絶対値をとった方が良いでしょう。理由はrangeは常にプラスだからです。差分gapがマイナスの場合に不具合が出ます。これが今回、(c)においてループが2回で終わってしまった直接の原因です。

(2)ループ終了判定

(b)(d)(f)では、ループを必ず20回回るので、その分平方根の精度は良くなります。

確認方法は cnt ++; //(f) の下の行に以下のprintを追加して確認しました(toString()は省略できる)。
System.out.println(cnt + " Scale: lastx: " + last_x.scale() + "value: "+ last_x);
System.out.println(cnt + " Scale: t: " + t.scale() + "value: "+ t);
System.out.println(cnt + " Scale: x: " + x.scale() + "value: " + x);
System.out.println(cnt + " Scale: gap: " + gap.scale() + "value: " + gap);

ループ20回目のgapは、20 Scale: gap: 81 value: -2.5806427001953125E-65
すなわち小数点以下81桁まで有効で、-2.58*10^(-64)乗。rangeは10^(-11)乗なので、全然小さい。

(1)(2)より、このように変えてみました。

BigDecimal range = new BigDecimal(1.0e-64);//(a)

while (gap.abs().compareTo(range) > 0) //(c')

結果:
7Scale: lastx: 67value: 1.732050807568877293527446341505872366942805253810380628
0558069794125
7Scale: t: 64value: 1.732050807568877293527446341505872366942805253810380628
0558069794
7Scale: x: 68value: 1.732050807568877293527446341505872366942805253810380628
05580697940625
7Scale: gap: 68value: -6.25E-66

sqrt(3) = 1.73205080756887729352744634150587236694280525381038062805580697940625

ループ7回で抜けてくれました。

示したtoString()による数字の表示例は、BigDecimalクラスのリファレンスより引用したものであります。
BigDecimalは、数字と小数点の有効桁数(スケール)を情報として持ちます。
#1の回答時は、一度toStringで渡しているため、スケールの情報も正しく渡るのか否か疑問がありました。クラスリファレンスの例のように帰ってしまうと2~3桁くらいで丸まってしまわないか、と。

混乱させてしまい申し訳ありません。

-----

再現して確認してみましたが、(a)(c)(e)の場合、

条件判定に使うgapの作り方
gap = x.s...続きを読む

QWHERE句で結合。INNER JOINとの違い

MySQLで複数テーブルからデータ取得する際、
FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、
「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか?

・「INNER JOIN」と同じ意味でしょうか?
・書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

・普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか?
・例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…

Aベストアンサー

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確ですから,join句の使用をお薦めします。

射影…select *
結合…from 表A inner join 表B on 表A.列1 = 表B.列2
選択…where 表A.列3 = 値


> 書き方によっては「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

旧構文で外部結合を記述することもできますが,各データベース製品の独自構文になります。標準SQLの規格ではありません。


> 「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか

そういう制限はありません。

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確です...続きを読む


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

人気Q&Aランキング