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

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

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

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

5回答

4195閲覧

一つのカラムに複数のデータを入れたいのですが、、、

cofee

総合スコア44

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2018/01/29 03:55

編集2018/01/30 05:08

チェックボックスで選択された値をカラーコードとしてDBに保存しています。
このチェックボックスは複数選択できるようにしているのですが、複数選択すると
|color|
|1,2|

となってしまい、表示する際に「varchar の値 '1,2' をデータ型 int に変換できませんでした。」
とエラーが出てしまいます。

表示する際は、カラーコードテーブルとjoinして表示していて、
チェックボックスで一つだけを選択すると正しく表示されています。

どうしたら複数のデータを表示させることができるのでしょうか?
よろしくお願いします。

表示する際に
|user_id|name|color |
|01 |a |ブラック,ホワイト|

と表示させたいです。

index.blade

php

1 <label><input type="checkbox" name="color[]" class="ib" value="1">ブラック</label> 2 <label><input type="checkbox" name="color[]" class="ib" value="2">ホワイト</label> 3 <label><input type="checkbox" name="color[]" class="ib" value="3">グレー</label> 4

Controller

php

1$colors = Request::Input('color'); 2 3//配列を文字列に変換してテーブルに登録しています。 4$color = implode(",",$colors);

表示する際のSQL

sql

1select user_id,name,colorname 2from( 3 select *, value as cl 4 from sample as s outer apply string_split(s.color,',') 5 ) as a 6 inner join master_color as c 7 on c.color_cd = a.cl 8

これで
|user_id|name |cl |
|1 |aaa |ブラック|
|1 |aaa |ホワイト|
このような結果になったのですが、clを,区切りにして1レコードに格納したいです。
よろしくお願いします。

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

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

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

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

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

guest

回答5

0

まず、同一 name のものがあった場合は、

color=1&color=2

のような形でブラウザからデータが送られます。それを CakePHP 側で解釈して、['color' => '1,2'] のような形で保持し、利用しています。
ですから利用する際には、「,でくっついてきているかも知れないので、その想定で事前に分割して適切に処理する」必要があるのです。(explode を使って string[] の形にして、その中にあるかどうかで見ていく)

DB 上での構造が分からないのですが、そもそも複数値を選択できるなら、選択カラー情報を別テーブルに保存してjoinする形になるのが一般的です。そうなってないのであれば、まずDB構造を見直したほうが良いと思われます。

投稿2018/01/29 05:05

tacsheaven

総合スコア13703

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

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

cofee

2018/01/29 05:18 編集

回答ありがとうございます。 複数選択された場合に、配列では保存できないのでControllerでimplodeして,で区切り、文字列に変換してテーブルに保存しています。 やはり選択カラー情報を別テーブルで作成するのがいいのでしょうか。
mtdsnsk

2018/02/06 00:52

設計思想によりますので、個人的には「カンマ区切りで文字列として保存し、読み出すときにパースして扱う」はアリだと思います。 今後の拡張性などを考えてカラー情報テーブルを分けるのは正規化という意味では良い方法です。 例えば、そのカラーコードをもとにデータベースを検索する時など。 小規模であれば、そこまで気にしなくても良いのですが、大規模になると文字列での検索は高負荷なので、そのカラムを検索に使うか?をまずは一つの指針に置いても良いかもしれません。
guest

0

idcolor
1001
1002

みたいにやって、group_cocantで他のテーブルから色名をとってきて結合します

sample

SQL

1create table color(c_id int primary key,c_name varchar(30)); 2insert into color values(1,'ブラック'),(2,'ホワイト'),(3,'グレー'); 3 4create table user_color(u_id int ,c_id int,unique(u_id,c_id)); 5insert into user_color values(100,1),(100,2);

SQL

1select u_id,group_concat(c_name order by t1.c_id) as color 2from color as t1 3inner join user_color as t2 on t1.c_id=t2.c_id 4group by u_id

投稿2018/01/29 04:06

編集2018/01/29 04:33
yambejp

総合スコア114583

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

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

sazi

2018/01/29 04:41

SQL Serverみたいですけど
yambejp

2018/01/29 05:08

saziさん、ありがとうございます よく確認してませんでした SQL SERVERは専門外なので意味のない回答になっているかもしれません。 あしからずご容赦下さい
cofee

2018/01/29 05:09

回答ありがとうございます。 また、サンプルも書いてくださりありがとうございます。
cofee

2018/01/29 05:10

group_concatというものがあるとは知らなかったので勉強になりました。
sazi

2018/01/29 05:34

>cofeeさん SQL Serverにはgroup_concatはありません。
guest

0

colorテーブルを別に作成して上手くいきました。ありがとうございました。

投稿2018/01/31 09:35

cofee

総合スコア44

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

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

0

「varchar の値 '1,2' をデータ型 int に変換できませんでした。」

上記エラーはSQL上で暗黙の型変換が行われ、オプションが一つのみ選択の場合は変換できるが、複数になると','で区切られているので型変換できないことによるエラーだと思われます。

SQL Server 2016以降なら、STRING_SPLIT()FOR XML PATH('')の組み合わせでSQLのみでも何とかできますが、そもそもオプション値を1つのカラムに','区切りで格納しているのですから、それをSQL上でマスターで変換しようとするのは非効率です。

SQLでの取得時に変換ではなく、データ取得後にphp側で変換したほうが良いと思います。

追記

SQL Server2017なら、STRING_AGG()も使用できるのでSTRING_SPLIT()と組み合わせて、以下のようなサンプルになります。

SQL

1create table sample(user_id varchar(255), name varchar(255), color_list varchar(255)); 2create table color(color integer, colorname varchar(255)); 3 4insert into sample values('test1','test1_name','1,2'), ('test2','test2_name','1'); 5insert into color values(1,'ブラック'), (2,'ホワイト');

SQL

1select a.user_id, a.name 2 , STRING_AGG(c.colorname,',') as color_name_list 3from ( 4 select *, value as color 5 from sample OUTER APPLY STRING_SPLIT(color_list, ',') 6 ) a inner join color as c 7 on c.color = a.color 8group by a.user_id, a.name

STRING_SPLIT()によって','区切りの文字を行として展開し、マスターと結合。
結合して取得した色の名称をSTRING_AGG()で行に纏める。
※group by しているのは、一旦行として展開されているので、再度集約する必要が有る為。

投稿2018/01/29 05:26

編集2018/01/29 11:52
sazi

総合スコア25138

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

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

cofee

2018/01/29 10:54

回答ありがとうございます。 php側で取得する前に上記のエラーが出てしまいます... SQL Serverは2017を使用しているので上記の関数が使えるのですが、具体的にどのように使えばよろしいのでしょうか? 自分で調べたのですが、いまいち理解できませんでした。 よろしくお願いします。
sazi

2018/01/29 11:59 編集

>php側で取得する前に上記のエラーが出てしまいます... SQLでのエラーですから、SQLを変更しないなら当然です。 SQL自体も結合して取得するのではなく、別々に取得する必要があります。 一応SQLで取得するサンプルを追記しました
cofee

2018/01/30 00:11

サンプルまでありがとうございます! 上記のサンプルを自分の環境に置き換えて試したのですが、inner join の前の a の箇所で波線が付き、列colorがaに対して複数回指定されましたと出て実行できませんでした。
cofee

2018/01/30 01:05 編集

また、v17.4なのですが、STRING_AGGは組み込み関数として認識されません。と出てしまいました。 FOR XML PATH('')を使用すれば同じようなことができるのでしょうか?
sazi

2018/01/30 02:01

v17.3で実行して検証しています。 単にクライアントにインストールしているバージョンがそれで、実際に接続しているバージョンが違うということはないですか? SQLのエラーに関しては元の環境では、sampleとcolorでcolorと言うカラムがそれぞれに存在しているからだと思います。別名を付与( as xxx)して見て下さい。
sazi

2018/01/30 02:09

FOR XML PATH('')については、STRING_AGG()のリンク先にサンプルがあります。
cofee

2018/01/30 03:36

接続しているバージョンが違うみたいでした、、 ありがとうございます。サンプル見てみます。
guest

0

ベストアンサー

「varchar の値 '1,2' をデータ型 int に変換できませんでした。」というエラーはどこで出ているでしょうか。
(PHP? SQL Server?)

カラーコードを表示用文字列に変換する処理はどこで行っていますか?(PHP? SQL文のCase文? ストアドプロシージャとか使ってますか?)

エラーが出ている箇所のソースを貼り付けた方が 回答が付きやすいと思います。

※なお、既存のシステムが元々こういう造りになっていて今から直すのは難しい・・・というのであれば仕方ありませんが、新規に実装しているのであれば yambejp さんが書かれているように設計を変えた方が良いと思います。
1つのカラムに複数の値を保持する方法は 一般的にあまりよくない設計とされています。

追記

うーん... テーブル構造を変えるのが無理なら、以下の感じでしょうか。

  1. color, sample1 は join しないで 別々に取ってくる。(クエリを2回発行)
  2. php のコードで、sample1 をLOOPでまわして 一行ずつ処理。

sample1.color をカンマで分割して、color テーブルの値から 対応する colorname を取得する。

でもテーブル構造を変更できるなら、そちらの方が良いと思いますよ。

追記2

現状

■sample1 |user_id |name |color | |01 |a |1,2 | |02 |a |1 |

修正案

■sample1 |user_id |name | |01 |a | |02 |a | ■sample1color |user_id |color | |01 |1 | |01 |2 | |02 |1 |

...あれ、キーは user_id で良いんでしょうか。name も含みます?
(同じuser_idで、name の違うレコードが存在したりしますか?)

まあ とりあえずこういう形にして、sample1, sample1color, color を join して出す、のが良いと思います。

投稿2018/01/29 04:27

編集2018/01/30 01:24
sk_3122

総合スコア1126

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

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

cofee

2018/01/29 05:08

回答ありがとうございます。 質問を編集しました。よろしければ確認お願いします。
cofee

2018/01/29 10:57

追記ありがとうございます。 とりあえず、チェックボックスの配列のデータを「,区切りの文字列」に変換してテーブルに格納しているのですが、このやり方は合っているのでしょうか? よろしくお願いします。
sk_3122

2018/01/30 01:21

1つの項目に複数の値を入れる(今回みたいにカンマ区切りで入れる等)というのは、よくないやり方とされています。回答の方に追記しますね。
cofee

2018/01/30 01:38

サンプルありがとうございます! テーブルを新たに作成するやり方も検討してみます。 また、取得したデータをHTMLの<table>の中で1レコードずつ表示するのが最終目標です。 ですので、カラーコードを名前に変換した後にまた,区切りの文字列に戻したいのですが、そのやり方はどうしたらいいのでしょうか、、、 質問を編集したのでよかったらご確認お願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問