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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SQLite

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

SQL

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Q&A

解決済

1回答

617閲覧

[SQlite,Ruby,Rails]tableから取得してきたhashの値のデータを思ったように並び替えたい

Tamusu

総合スコア8

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SQLite

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

SQL

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

0グッド

0クリップ

投稿2020/10/26 05:30

編集2020/10/26 10:14

前提・実現したいこと

昨日に引き続き、わからないことが出てきてしまったので、再度質問します。
sqlを使い3っつのテーブルを結合させて取得してきたデータを、思ったような形に並べ替えたいです。

存在するテーブルの説明

stores table

table

1code|name |image |access_walk|pr |budget| 2a |〇〇屋|https://~~~|5 |文字 |3000 | 3b |????????屋|https://~~~|6 |文字 |3000 | 4c |△△屋|https://~~~|7 |文字 |3000 | 5. 6.

drink_prices table

store_code|drink_id |drink_price| a |1 |300 | a |1 |320 | a |2 |500 | b |1 |200 | b |2 |350 | c |1 |400 | c |3 |600 | . .

同じstore_code 内で drink_id が同じで、 drink_price だけが違うものがあります。
これは、同じミックスジュースでもサイズが違うなどの理由で同じ drink_id の drink_price だけ違う物がデータとして入っています。

drinks table

id|name 1 |ミックスジュース 2 |トマトジュース 3 |お茶 . .

これらのテーブルをまとめるsql文

sql

1select 2 drink_prices.store_code, 3 stores.name, 4 image, 5 access_walk, 6 pr, 7 budget, 8 drink_price, 9 drinks.name 10from 11 drink_prices 12 INNER JOIN drinks ON drink_prices.drink_id = drinks.id 13 INNER JOIN stores ON drink_prices.store_code = stores.code 14where drink_prices.id in(select min(drink_prices.id) from drink_prices INNER JOIN drinks ON drink_prices.drink_id = drinks.id group by store_code, drinks.name);

これの文を打つ理由としては、
drink_prices tableを基準にして3っつのテーブルを結合したうえで、drink_prices tableの被っているnameのデータを省いています。

この時点ですでに1つ思い通りにデータが取れていなくて、取得したデータは以下のようなものになっています。

hash

1[{"store_code"=>"a", "name"=>"ミックスジュース", "image"=>"https://~~~.jpg", 2 "access_walk"=>5, "pr"=>"pr文", "budget"=>3000, "drink_price"=>300}, 3 4{"store_code"=>"a", "name"=>"トマトジュース", "image"=>"https://~~~.jpg", 5 "access_walk"=>5, "pr"=>"pr文", "budget"=>3000, "drink_price"=>500}, 6 7{"store_code"=>"b", "name"=>"ミックスジュース", "image"=>"https://~~~.jpg", 8 "access_walk"=>6, "pr"=>"pr文", "budget"=>3000, "drink_price"=>200}, 9 10{"store_code"=>"b", "name"=>"トマトジュース", "image"=>"https://~~~.jpg", 11 "access_walk"=>6, "pr"=>"pr文", "budget"=>3000, "drink_price"=>350,}, 12. 13. 14]

sql文では、drinks.name と stores.name をselectで指定しているのですが、取れているのはdrinks.nameだけになってしまいました。〇〇屋というお店の名前が抜けてしまっています。

このデータ形式を、以下のような形に変えたいと思っています。

[{"store_code"=>"a", "name"=>"〇〇屋", "image"=>"https://~~~.jpg", "access_walk"=>5, "pr"=>"pr文", "budget"=>3000, "drink_price"=>300, "name"=>["ミックスジュース","トマトジュース"]}, {"store_code"=>"b", "name"=>"????????屋", "image"=>"https://~~~.jpg", "access_walk"=>6, "pr"=>"pr文", "budget"=>3000, "drink_price"=>200, "name"=>["ミックスジュース","トマトジュース"]}, . . ]

store_code a の中に、飲み物の名前が"name"=>["ミックスジュース","トマトジュース"]のような形にしたいです。
drink_priceの値も複数あるのにもかかわらず1つになっているのは、ここの値は最小の値を取りたいと考えているからです。
同じstore_codeの

  • store_code
  • stores.name
  • image
  • access_walk
  • pr
  • budget

をまとめ、

同じstore_codeの

  • drink_price

の最小の値を1つとり、

  • drinks.name

をstore_codeごとに配列としてまとめたいです。

tableに問い合わせる段階で整形するのか、取り寄せた後に整形するのか、どちらがやりやすいのかもわからず困っています...

結局知りたいこと

  • tableを結合した結果、同名のカラム(今回はname)が2つ以上ある場合、これを出力後に判別する方法。または、判別できるよう形で出力にする方法。
  • { store_code,

stores.name,
image,
access_walk,
pr,
budget,
drink_price,
drinks.name[]
}
のデータ形式に出力する方法。または、tableからデータを取得した後に、上記の形式にデータを整形する方法。

補足情報(FW/ツールのバージョンなど)

Rails 6.0.3.4
ruby 2.6.5
sqLite3

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

name が2つあるので
stores.name as store_name, drinks.name as drink_name
とするのが良いでしょう。

確認しておきたいのですが 
drink_prices table では飲み物によって価格が異なります。
なのに「以下のような形に変えたいと思っています」では料金はひとつだけです。
それで良いのでしょうか? 良い場合 どの料金を採るのでしょうか

org.group_by{|s| s["store_code"]}. map{|k,ary| ary.first["drink_price"]=ary.map{|a| a["drink_price"]}.min;[k,ary]}. map{|k,ary| ary.inject{|a,s| a["name"]= [a["name"], s["name"]].flatten;a}}

但しこの方法は org の各店舗最初のデータの name と drink_price を破壊します。

破壊しなくなった

org.group_by{|s| s["store_code"]}. map{|k,ary| a0=ary.first.dup; a0["drink_price"]=ary.map{|a| a["drink_price"]}.min; ary.inject(a0){|a,s| a["name"]= [a["name"], s["name"]].flatten;a} }

投稿2020/10/26 09:39

編集2020/10/26 10:53
winterboum

総合スコア23329

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tamusu

2020/10/26 10:03

昨日に続きwinterboumさん、回答ありがとうございます。 料金に関しましては私が完全に書き忘れてしまいました。 料金は、nameに関係なく、同じstore_codeで1番低い値のものが取れていて欲しいです。
Tamusu

2020/10/26 11:49

winterboumさん、回答の修正ありがとうございます。 今打ち込んでみたところ、ほぼほぼ僕の希望通りのデータが取得できました。 ありがとうございます。 みたことのないメソッドをたくさん使っていて、面を食らっています。 一つ確認したいことがありまして、 name=>[""]の部分で、最初に出てきたデータが必ず2つ入ってしまうようになっています。 例えば、 {"store_code"=> "a", "drink_name"=>[ "ミックスジュース", "ミックスジュース", "トマトジュース" ], "pr"=> ....} ( stores.name ad store_name , drinks.name as drink_name のように、カラム名を少し変えています ) というように、配列にした部分は全ての部分で同じ値が頭に入ってしまうようになっています。
winterboum

2020/10/26 12:05

a0=ary.first.dup; の後に a0["name"] = [] を入れてください そうすると a["name"]= [a["name"], s["name"]].flatten  のところを a["name"] << s["name"] にできます。
Tamusu

2020/10/26 12:27

ありがとうございます。 初めの方の部分に a0["name"] = [] を足し、 最後の部分である a["name"]= [a["name"], s["name"]].flatten を書き換え、 @stores_data = @store.group_by{|s|s["store_code"]}.map{|k,ary|a0=ary.first.dup; a0["drink_name"] = []; a0["drink_price"]=ary.map{|a| a["drink_price"]}.min; ary.inject(a0){|a,s| a["drink_name"] << s["drink_name"]}} と書き換え実行しましたが、以下のようなエラーが出るようになってしまいました。 no implicit conversion of String into Integer
winterboum

2020/10/26 13:10

あ、 最後の ]}} のところ ];a}} に。
Tamusu

2020/10/26 13:51 編集

ありがとうございます。動きました。 めっちゃきれいにデータを並び替えられました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問