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

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

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

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

Ruby on Rails

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

Q&A

解決済

3回答

3786閲覧

テーブルの結合について(複数キー)

退会済みユーザー

退会済みユーザー

総合スコア0

SQL

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

Ruby on Rails

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

0グッド

1クリップ

投稿2017/01/22 23:50

###前提・実現したいこと

railsを使用しています。

【カテゴリテーブル】

id|name|
1|野菜|
2|果物|
3|炭水化物|

【買い物テーブル】

id|person|c1|c2|c3|
1|たかし|1|2|3|

c1、c2、c3はカテゴリテーブルと関連付けています。

求める結果
1|たかし|野菜|果物|炭水化物|

とカテゴリ名をsqlで算出したいのです。

としたいのですが、どのようなsqlであれば実現できるでしょうか?
railsを利用しているので単純なsqlとrailsでの表現方法も教えていただけるとありがたいです。

よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

多対多のモデルを作るとすっきりするかもです

Person テーブル

idperson
1Alice
2Bob

Category テーブル

idname
1野菜
2果物
3炭水化物

PersonCategory テーブル(ひも付きを持つテーブル)

idperson_idcategory_id
111
212
313
422

↑のようにするとPersonCategoryを経由して
Alice(id: 1) が 野菜(id: 1), 果物(id: 2), 炭水化物(id: 3)
Bob(id: 2) が 果物(id: 2)
とひもづいているとわかります

また、上記のテーブルを持つ場合のRailsのモデルの書き方

ruby

1class Person < ActiveRecord::Base 2 has_many :categories, through: :person_categories 3 4 def category_names 5 categories.map(&:name) 6 end 7end

ruby

1class Category < ActiveRecord::Base 2 has_many :persons, through: :person_categories 3end

ruby

1class PersonCategory < ActiveRecord::Base 2 belongs_to :category 3 belongs_to :person 4end

rails consoleで実行すると

alice = Person.find_by(name: 'Alice') alice.categories # => [1,2,3] alice.category_names # => ['野菜', '果物', '炭水化物'] bob = Person.find_by(name: 'Bob') bob.categories # => [2] bob.category_names # => ['果物']

参考URL: http://ruby-rails.hatenadiary.com/entry/20141204/1417688260

投稿2017/01/26 05:12

satoshih

総合スコア797

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

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

退会済みユーザー

退会済みユーザー

2017/01/26 10:17

ありがとうございます。 レコード数が少ないのでテーブルの作成は避ける形でsqlのみで強引にトライしていたのですが、railsだったらこのテーブルからスマートに取得できるんですね。 これだと単純で楽ですね。
satoshih

2017/01/26 10:29

データの数が増えるとschemaを変更しないといけないようなテーブルの持ち方は 現実的では無いですね。 特に買い物とかだと、たかしくんは何種類のものを買い物をしてもいいとおもうので 柔軟に対応出来るモデルの設計が良いかと思われます。
guest

0

一応正規化を含めた簡単なsampleだけ提示しておきます
railsにそのまま応用できるかどうかはわかりませんが
概ね以下のような考え方をすればよいかとおもいます

  • 元テーブル作成、データ投入

SQL

1create table tbl_c(cid int not null primary key,name varchar(20)); 2insert into tbl_c values(1,'野菜'),(2,'果物'),(3,'炭水化物'); 3 4create table tbl_k(kid int not null,person varchar(20)); 5insert into tbl_k values(1,'たかし'); 6 7create table tbl_ck(kid int,cid int); 8insert into tbl_ck values(1,1),(1,2),(1,3); 9
  • kidをベースにした購入物名の列記

SQL

1select t1.kid,person,names 2from tbl_k as t1 3inner join ( 4select kid,group_concat(name) as names 5from tbl_c as t2 6inner join tbl_ck as t3 on t2.cid=t3.cid 7group by kid 8) as t4 on t1.kid=t4.kid; 9 10

投稿2017/01/24 04:10

yambejp

総合スコア114505

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

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

退会済みユーザー

退会済みユーザー

2017/01/26 10:09

何度もありがとうございます。 かなり複雑なsqlになるんですね。参考にさせていただきます。
guest

0

SQLでならこんな感じですかね。同一テーブルを別名を使って複数回 JOIN します。

SQL

1SELECT t.id, t.person, ta.name, tb.name, tc.name 2FROM 買い物テーブル AS t 3LEFT OUTER JOIN カテゴリテーブル AS ta ON (ta.id=t.c1) 4LEFT OUTER JOIN カテゴリテーブル AS tb ON (tb.id=t.c2) 5LEFT OUTER JOIN カテゴリテーブル AS tc ON (tc.id=t.c3)

そもそも買い物テーブルの構造がどうかとは思いますが。

投稿2017/01/23 03:09

tacsheaven

総合スコア13703

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

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

Orlofsky

2017/01/23 05:06

買い物数が増えると大変なことになりますね。汗
yambejp

2017/01/23 05:27

元のデータのもたせ方が悪いのでカラムが増えればjoinが増えるのはどうしようもないでしょう。 そもそもc1とc2、c3の間に相関関係やなんらかの優先順位があるのでしょうか? c1~3までは同じ内容を単に3つ並べているだけであれば正規化して idに対するカテゴリは列記した別データで持たせるほうが効率的です
退会済みユーザー

退会済みユーザー

2017/01/23 07:33

ありがとうございます。 歪な構成ですが、レコード数は1000以下で少ないので力技でトライしています。 確かに別にテーブルを用意したほうがスマートですね。
Panzer_vor

2017/01/23 09:44

> dare_subさん 別にテーブルを持つというよりかは、 テーブル構造にテコ入れすれば解決する課題だったりしますよ。 列に横持ちさせる、でなく行持ちさせるに発想を切り替えれば良いです。 その場合はカラムを追加しての複合主キーを張る・・・という所謂連関エンティティとする手法となりますが。 (※買い物をする人の情報をマスタ化すると、もはやテンプレですね)
退会済みユーザー

退会済みユーザー

2017/01/23 13:53

ありがとうございます。 ちょっと今の私のレベルでは理解しきれないですね。勉強したいと思います。
Orlofsky

2017/01/24 14:10

dare_subさん お勉強の範囲なら良いですが、実務でテーブル設計していたら大変なことになります。 とりあえず、正規化を勉強されると良いでしょう。当面、第1正規化から第3正規化まで身に着けてください。 http://www.atmarkit.co.jp/ait/articles/1109/07/news124.html
退会済みユーザー

退会済みユーザー

2017/01/26 10:06

すいません。実務で利用しています(´□`;) 身内だけの管理画面でレコード数自体が少ないので力技でごまかしている部分があります。 正規化、勉強します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問