お世話になります。
==
SELECT
ROUND(AVG( 基準日終値*( CASE 基準年月
WHEN '202012' THEN 1 WHEN '202011' THEN 1 WHEN '202010' THEN 0.25
END )),2,1) AS 最小終値
FROM ~
==
java(Servlet)で、上記のクエリで平均値を取得すると、
74.39 が返ります。このときgetBigDecimalで値を取得しています。
上記のクエリをDB(SQL Server Management Studio )上で直に実行すると、
74.40が返ります。また、Excelで計算すると、やはり74.40が返ります。
何故、javaの場合、74.39が返るのでしょうか?
getBigDecimalで値を取得していますが、これを
getStringやgetDoubleに変更しても結果は同じでした。
ちなみに、平均値を算出する値は以下の通りです。
77.15
75.91
75.33
75.49
74.98
74.33
74.71
74.4
74.51
75.06
74.44
74.91
73.55
73.8
73.28
73.67
73.68
73.27
72.52
73.35
74.31
74.15
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
SQLServerには詳しくありません。あしからず。
- ROUND (Transact-SQL)
引数
...
length numeric_expression を丸める際の有効桁数です。
function 実行する操作の種類です。 ... 0 以外の値を指定した場合、... は切り捨てられます。
件のSQL。
sql
1SELECT ROUND(AVG(基準日終値*...),2,1)
functionには1を渡しています。lengthで「切り捨て」ですね。
基準日終値の型がなんだかわかりませんが、件のデータをdoubleで計算すると、74.39999999999999
です。切り捨てれば74.39
。
何故、javaの場合、74.39が返るのでしょうか?
74.39999999999999
を、切り捨てて74.39
。
上記のクエリをDB(SQL Server Management Studio )上で直に実行すると、74.40が返ります。
round関数の定義をみると、むしろ、この結果のほうが疑わしいのではないかと。
kotlin
1import org.junit.jupiter.api.Test 2import java.math.BigDecimal 3 4class HogeAvg { 5 @Test 6 fun aa() { 7 val values: List<String> = data.trim().split("""\s+""".toRegex()) 8 println(values) 9 10 val doubleAverage = values.map { it.toDouble() }.average() 11 println("doubleAverage: ${doubleAverage}") 12 // doubleAverage: 74.39999999999999 13 14 val bigDecimalAverage = 15 values 16 .map { it.toBigDecimal() } 17 .fold(BigDecimal.ZERO) { a, b -> a + b } / values.size.toBigDecimal() 18 println("bigDecimalAverage: ${bigDecimalAverage}") 19 // bigDecimalAverage: 74.40 20 } 21 22 val data = """ 2377.15 2475.91 2575.33 2675.49 2774.98 2874.33 2974.71 3074.4 3174.51 3275.06 3374.44 3474.91 3573.55 3673.8 3773.28 3873.67 3973.68 4073.27 4172.52 4273.35 4374.31 4474.15 45 """.trimIndent() 46}
投稿2021/04/10 13:18
総合スコア4061
0
ベストアンサー
SQLServerには詳しくありません。あしからず。
float型というのがあるんですね。
基準日終値の型 decimal(16, 6) と float だけのテーブルをつくってためしてみました。
create table test (decValue decimal(16,6), floatValue float)
結果。
select avg(decValue) as _dec_avg, round(avg(decValue),2,1) as _dec_round, avg(floatValue) as _float_avg, round(avg(floatValue),2,1) as _float_round from test avg: [(_dec_avg, 74.400000), (_dec_round, 74.400000), (_float_avg, 74.39999999999999), (_float_round, 74.39)]
件のSQLは、こう。
sql
1ROUND( 2 AVG(基準日終値 3 * ( 4 CASE 基準年月 5 WHEN '202012' THEN 1 6 WHEN '202011' THEN 1 7 WHEN '202010' THEN 0.25 8 END 9 ) 10 ) 11 ,2,1) AS 最小終値
基準年月が202010のとき、0.25 を掛けてます。この結果として、最小終値がfloat型になっているのではないでしょうか。
kotlin
1import java.sql.DriverManager 2 3object HogeTest { 4 @JvmStatic 5 fun main(args: Array<String>) { 6 val url = "jdbc:sqlserver://localhost" 7 val conn = DriverManager.getConnection(url, "sa", "password@12345") 8 println("conn: ${conn}") 9 10 conn.createStatement().let { st -> 11 val sql = """drop table if exists test""" 12 println(sql) 13 st.execute(sql) 14 st.close() 15 } 16 17 conn.createStatement().let { st -> 18 val sql = """create table test (decValue decimal(16,6), floatValue float)""" 19 println(sql) 20 st.execute(sql) 21 st.close() 22 } 23 24 """insert into test values(?, ?)""".let { sql -> 25 println(sql) 26 conn.prepareStatement(sql).let { st -> 27 dataList.trim().split("""\s+""".toRegex()) 28 .forEach { data -> 29 st.setBigDecimal(1, data.toBigDecimal()) 30 st.setBigDecimal(2, data.toBigDecimal()) 31 st.execute() 32 } 33 st.close() 34 } 35 } 36 37 conn.createStatement().let { st -> 38 val sql = """select * from test""" 39 println(sql) 40 st.executeQuery(sql).let { rs -> 41 while (rs.next()) { 42 val row = (1..rs.metaData.columnCount).map { index -> 43 rs.metaData.getColumnName(index) to rs.getString(index) 44 } 45 println("row: ${row}") 46 } 47 rs.close() 48 } 49 st.close() 50 } 51 52 println("----") 53 54 conn.createStatement().let { st -> 55 val sql = """ 56 select 57 avg(decValue) as _dec_avg, 58 round(avg(decValue),2,1) as _dec_round, 59 avg(floatValue) as _float_avg, 60 round(avg(floatValue),2,1) as _float_round 61 from test""".trimIndent() 62 println(sql) 63 st.executeQuery(sql).let { rs -> 64 while (rs.next()) { 65 val row = (1..rs.metaData.columnCount).map { index -> 66 rs.metaData.getColumnName(index) to rs.getBigDecimal(index) 67 } 68 println("avg: ${row}") 69 } 70 rs.close() 71 } 72 st.close() 73 } 74 75 } 76 77 val dataList = """ 7877.15 7975.91 8075.33 8175.49 8274.98 8374.33 8474.71 8574.4 8674.51 8775.06 8874.44 8974.91 9073.55 9173.8 9273.28 9373.67 9473.68 9573.27 9672.52 9773.35 9874.31 9974.15 100 """.trimIndent() 101}
conn: ConnectionID:1 ClientConnectionId: 6e2f8d13-0f16-4b7c-a773-7444fb6d5d3d drop table if exists test create table test (decValue decimal(16,6), floatValue float) insert into test values(?, ?) select * from test row: [(decValue, 77.150000), (floatValue, 77.15)] row: [(decValue, 75.910000), (floatValue, 75.91)] row: [(decValue, 75.330000), (floatValue, 75.33)] row: [(decValue, 75.490000), (floatValue, 75.49)] row: [(decValue, 74.980000), (floatValue, 74.98)] row: [(decValue, 74.330000), (floatValue, 74.33)] row: [(decValue, 74.710000), (floatValue, 74.71)] row: [(decValue, 74.400000), (floatValue, 74.4)] row: [(decValue, 74.510000), (floatValue, 74.51)] row: [(decValue, 75.060000), (floatValue, 75.06)] row: [(decValue, 74.440000), (floatValue, 74.44)] row: [(decValue, 74.910000), (floatValue, 74.91)] row: [(decValue, 73.550000), (floatValue, 73.55)] row: [(decValue, 73.800000), (floatValue, 73.8)] row: [(decValue, 73.280000), (floatValue, 73.28)] row: [(decValue, 73.670000), (floatValue, 73.67)] row: [(decValue, 73.680000), (floatValue, 73.68)] row: [(decValue, 73.270000), (floatValue, 73.27)] row: [(decValue, 72.520000), (floatValue, 72.52)] row: [(decValue, 73.350000), (floatValue, 73.35)] row: [(decValue, 74.310000), (floatValue, 74.31)] row: [(decValue, 74.150000), (floatValue, 74.15)] ---- select avg(decValue) as _dec_avg, round(avg(decValue),2,1) as _dec_round, avg(floatValue) as _float_avg, round(avg(floatValue),2,1) as _float_round from test avg: [(_dec_avg, 74.400000), (_dec_round, 74.400000), (_float_avg, 74.39999999999999), (_float_round, 74.39)]
最後に。DBeaverで件のDB接続した結果はこうなりました。おもいきり不審ですネ。
select avg(decValue) as _dec_avg, round(avg(decValue),2,1) as _dec_round, avg(floatValue) as _float_avg, round(avg(floatValue),2,1) as _float_round from test ; 表示された検索結果 74.400000 74.400000 74.40 74.39 コピペした検索結果 74.400000 74.400000 74.39999999999999 74.39
どんなツールでSQLの実行結果を確認されたのかしりませんが、そのツールで表示されている結果は、見えている結果は、ホントウの値なのでしょうか?すくなくともDBeaverのデフォルト設定では、そうではないみたいです。
投稿2021/04/13 01:32
総合スコア4061
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/12 01:43