質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

解決済

Android Room DBのselectの抽出/集計結果を別のテーブルへinsertしたいのですが、想定と違う結果がinsertされてしまいます。

Yakusugi
Yakusugi

総合スコア70

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1回答

0評価

0クリップ

101閲覧

投稿2022/05/12 12:36

編集2022/05/14 08:37

Javaを使ってAndroidの家計簿アプリを作成しています。
DBはAndroid Roomを使用しており、ここではSQLに関しての質問になります。

下記はDBにアクセスするDAOクラスに記載したSQLで、
ここでやりたいことは、元となるデータが記載されたテーブル「budget_tracker_table」からselectで抽出/集計した結果を、もう一つのテーブル「budget_tracker_table_alias」にinsertする事です。
下記では、SQLの内容を少し変え、Group by product_typeとしました。
意図としては、ユーザ入力値の日付(from)、日付(to)、店名から、指定された日付の間で、指定の店名で購入した商品のリストを取得し、さらにそのリストの中で、商品種類(product_type)を洗い出し、どういった商品の種類(電化製品、食品など)が購入されたかをパーセンテージで表示するSQLを組みたいと思っています。

BudgetTrackerAliasDao.java

@Query("insert into budget_tracker_table_alias (date_alias, store_name_alias, product_name_alias, product_type_alias, price_alias, product_type_percentage) select date, store_name, product_name, product_type, price, count(product_type) * 100.0 / (select count(*) from budget_tracker_table where date >= :date1 and date <= :date2 and store_name LIKE '%' || :storeName || '%') as 'Percentage' from budget_tracker_table where date >= :date1 and date <= :date2 and store_name LIKE '%' || :storeName || '%' group by product_type;") void insert(String date1, String date2, String storeName);

想定では、上記SQLを実行すると、ユーザ入力値のdate1(始まりの日付)、date2(終わりの日付)、storeName(店名)を元に、
budget_tracker_tableからデータを抽出/集計し、その結果をbudget_tracker_table_aliasにinsertするはずでした。
また、日付の間隔が大きければ、複数のデータが入るはずだったのですが、実際に実行してみると、
budget_tracker_table_aliasにinsertされたレコード数は想定よりも少ない結果となりました。

抽出元となるbudget_tracker_tableのデータは下記のようになっています。

2 2020-01-02 Google Store Pixel 6 Pro gadget 125000 17 2022-4-22 Amazon echo show 333 gadget 30000 18 2022-4-22 amazon tiger mask toy 1500 19 2022-4-22 Google store pixelbook gadget 45099 20 2022-4-22 Google store echo show gadget 1500 23 2022-4-26 Amazon echo show 2222 gadget 159999 24 2022-4-23 amazon renpho smart nawatobi gadget 3000 25 2022-4-26 Google store pixel 6a gadget 54000

上記状態で、下記SQLを実行します。

insert into budget_tracker_table_alias (date_alias, store_name_alias, product_name_alias, product_type_alias, price_alias, product_type_percentage) select date, store_name, product_name, product_type, price, count(product_type) * 100.0 / (select count(*) from budget_tracker_table where date >= :date1 and date <= :date2 and store_name LIKE '%' || :storeName || '%') as 'Percentage' from budget_tracker_table where date >= :date1 and date <= :date2 and store_name LIKE '%' || :storeName || '%' group by product_type;

budget_tracker_table_aliasには下記のデータが入りました。
ただ、SQLではLIKE検索でamazonとしているので、本来であればID「17」「23」が入っているはずだったのですが、
当該レコードのみが入っていませんでした。

146 2022-4-23 Amazon renpho smart nawatobi gadget 3000 75.0 147 2022-4-22 amazon tiger mask toy 1500 25.0

当該事象解決の為、ご助力頂けますと幸いです。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

jimbe

2022/05/12 18:27 編集

LIKE が group by の後ろにあるのは変ではないでしょうか。 データの選択条件は where で指定するべきもので、それからどの列の値で纏めるのかを指定するのが group by だと思いますが。
Yakusugi

2022/05/13 05:55

ご回答ありがとうございます。 ご指摘通り、group by句からLIKEを消し、where句に追記したところ、 少なくとも指定外の店名が入ることはなくなりました。 ただ、上記でも編集・追記しましたが、本来入るべきレコードが一件入っておらず、 こちらに関して解決の為の提案などがあれば、ご教示お願いいたします。
jimbe

2022/05/13 07:08

作成されている SQL は、 insert 文だったり select 文だったり集計していたりと、幾つかの文が組み合わさっています。 insert 文や集計の select は対象データが定まらなければ意味がありませんので、まずは対象データを抽出する select 文だけをテストしたほうが良いように思います。
hoshi-takanori

2022/05/13 07:13

group by store_name でお店ごとに集計してるので、SQL 的には集約関数を使ってないカラム (date, product_name, product_type, price) を指定するとエラーになるはずですが、SQLite だと通っちゃう (グループの中から適当な行の情報が出てる) ようですね。 お店ごとの集計なので、小文字の amazon のように 1 件しかないのが正常で、大文字の Amazon が 2 件出てくるのはおかしいのですが、よく見たら Amazon の後ろにスペースが…。
Yakusugi

2022/05/13 13:14

ご回答ありがとうございます。 確かにご指摘の通り、店名にスペースが入っていたりしており、 スペースを消した状態で再度試してみましたが、やはり意図した結果は得られませんでした。 ご指摘の中で、集計関数を使っていないカラムを指定するとエラーになるはずとのことですが、 意図した通り、指定日付内のデータ全てを抽出するためのヒントがあれば、ご教示頂けますと幸いです。
hoshi-takanori

2022/05/13 15:34

どういう結果を期待してますか?
Yakusugi

2022/05/13 23:36

日付で2022-4-22から2022-4-26を指定し、店名でAmazonを指定した場合、 現状のDBでは下記4つのレコードを抽出・集計した結果がbudget_tracker_table_aliasに入ると期待していました。 17 2022-4-22 Amazon echo show 333 gadget 40000 18 2022-4-22 amazon tiger mask toy 1500 23 2022-4-26 Amazon echo show 2222 gadget 159999 24 2022-4-23 Amazon renpho smart nawatobi gadget 3000 ただ、よくよく考えるとgroup by product_nameとしているので、 budget_tracker_table_aliasに入った集計結果では、gadgetが75%で、toyが25%だったので、 集計結果の数値的には間違ってないんですよね。。。 なので、結果としては、期待していた集計結果が取れているので、 問題ないのかなという結論に達しました。 ヒントを色々頂きありがとうございました。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。