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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

3回答

5267閲覧

mysql 複数行を1行にまとめる方法

u-sukesan

総合スコア156

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

0クリップ

投稿2016/07/20 02:05

編集2016/07/20 02:41

下記のようなテーブルから

テーブルA

user_id key value 1 name 高橋 1 kana たかはし 1 add 東京都 1 mail abc@def.gh 1 tel 000-000-0000

現在下記のselect文で取得しており

function GetRecordset($sql,$param,$htmlchar=false){ $ret = null; $conn = ConnectDB(); if(is_null($conn)){return $ret;} $sql=mb_convert_encoding($sql,'utf8','auto'); $sth = $conn->prepare($sql); if($sth->execute($param)){ $ret = $sth->fetchAll(PDO::FETCH_ASSOC); $ret = htmlspecialchars_decodeArray($ret); if($htmlchar) $ret = htmlspecialcharsArray($ret); } return $ret; } $sql = "SELECT key,value FROM テーブルA WHERE user_id=:user_id;"; $param = array(':user_id' => $user_id); $result = GetRecordset($sql,$param); if(is_null($result)){ $err = ERR_DATABASE; } elseif(count($result)==0){ $err = ERR_NO_RECORD_FETCHED; }else{ return $result; }

以下のような結果が返ってきます。

array( [0]=>array([key]=>'name',[value]=>'高橋'), [1]=>array([key]=>'kana',[value]=>'たかはし'), [2]=>array([key]=>'add',[value]=>'東京都'), [3]=>array([key]=>'mail',[value]=>'abc@def.gh'), [4]=>array([key]=>'tel',[value]=>'000-000-000') )

下記のような配列で1行で取得したいです

array( 'name'=>'高橋', 'kana'=>'たかはし', 'add'=>'東京都' ・・・)

GROUP_CONCATも検討しましたが、理想の配列にはならないため質問させていただきました。
よろしくお願いいたします。

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

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

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

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

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

ttyp03

2016/07/20 02:14

PHPの質問ですよね?タグにPHPを追加するのと、PHPのコードを掲載し、現状どういうデータになっているのかを提示した方が良いです。
u-sukesan

2016/07/20 02:25

ご指摘ありがとうございます。 タグの追加と現状の結果を追記しました。
yodel

2016/07/20 02:35

PHPでsqlを実行してfetchしている箇所を記載した方が良いのでは。
u-sukesan

2016/07/20 02:42

PHP部分を修正しました。 ややこしくなるかと思い、控えました。 大変失礼しました
guest

回答3

0

ベストアンサー

PHPで配列を処理したほうがスマートな気がしますが、SQLでやるならこんな感じに書けると思います。

SQL

1SELECT 2MAX(CASE WHEN `key`='name' THEN `value` ELSE '' END) AS `name`, 3MAX(CASE WHEN `key`='kana' THEN `value` ELSE '' END) AS `kana`, 4MAX(CASE WHEN `key`='add' THEN `value` ELSE '' END) AS `add`, 5MAX(CASE WHEN `key`='mail' THEN `value` ELSE '' END) AS `mail`, 6MAX(CASE WHEN `key`='tel' THEN `value` ELSE '' END) AS `tel` 7FROM テーブルA 8GROUP BY `user_id`

投稿2016/07/20 02:48

編集2016/07/20 02:49
dupont_kedama

総合スコア925

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

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

yambejp

2016/07/20 02:54

ああ、確かにこのケースならMAXで十分ですね
u-sukesan

2016/07/20 03:26

回答ありがとうございます。 説明不足で大変申し訳ございません。 DBレコードには user_id key value 1 name 高橋 1 kana たかはし 1 add 東京都 1 mail abc@def.gh 1 tel 000-000-0000 2 2 3 3 とその他のuser_idも含むためwhere区 が必要になります。 GROUP BY と where 区の併用はできませんよね お手数おかけします
dupont_kedama

2016/07/20 03:32

user_id=1を条件に抽出したいなら WHERE user_id = 1 をGROUP BY の前に入れてみてください。併用は可能です。
u-sukesan

2016/07/20 04:05

ありがとうございます。 実現できました。
guest

0

SQLで作成してみました。

Table

1show columns from tableA 2+---------+-------------+------+-----+---------+-------+ 3| Field | Type | Null | Key | Default | Extra | 4+---------+-------------+------+-----+---------+-------+ 5| user_id | int(11) | YES | | NULL | | 6| skey | varchar(40) | YES | | NULL | | 7| svals | varchar(40) | YES | | NULL | | 8+---------+-------------+------+-----+---------+-------+

SQL

1select t1.svals name, t2.svals kana, t3.svals adds, t4.svals mail, t5.svals tel 2from tableA t1 3join tableA t2 on t1.user_id=t2.user_id 4join tableA t3 on t1.user_id=t3.user_id 5join tableA t4 on t1.user_id=t4.user_id 6join tableA t5 on t1.user_id=t5.user_id 7where t1.skey='name' and t2.skey='kana' and t3.skey='add' and t4.skey='mail' and t5.skey='tel' 8and t1.user_id=1; 9 10+--------+--------------+-----------+------------+--------------+ 11| name | kana | adds | mail | tel | 12+--------+--------------+-----------+------------+--------------+ 13| 高橋 | たかはし | 東京都 | abc@def.gh | 000-000-0000 | 14+--------+--------------+-----------+------------+--------------+ 151 row in set (0.00 sec)

投稿2016/07/20 03:14

A.Ichi

総合スコア4070

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

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

0

この手のインタラクティブにデータを管理する方法は
一覧表に戻すときには項目の数だけleft joinします。

SQL

1create table tbl_a(`user_id` int,`key` varchar(20),`value` varchar(100),unique(`user_id`,`key`)); 2insert into tbl_a values(1,'name','高橋'),(1,'kana','たかはし'),(1,'add','東京都'),(1,'mail','abc@def.gh'),(1,'tel','000-000-0000');

特定のユーザーは同じ名前のkeyを持てない制約をつけておいてください

表示方法は以下

SQL

1select t0.`user_id`,t1.value as `name`,t2.value as `kana`,t3.value as `add`,t4.value as `mail`,t5.value as `tel` 2from (select distinct user_id from tbl_a) as t0 3left join tbl_a as t1 on t0.user_id=t1.user_id and t1.key='name' 4left join tbl_a as t2 on t0.user_id=t2.user_id and t2.key='kana' 5left join tbl_a as t3 on t0.user_id=t3.user_id and t3.key='add' 6left join tbl_a as t4 on t0.user_id=t4.user_id and t4.key='mail' 7left join tbl_a as t5 on t0.user_id=t5.user_id and t5.key='tel';

場合によってはピボットテーブル的な処理もできるかもしれませんが
上記で十分かと

追記

※ピボット処理を追記しておきます

SQL

1select `user_id` 2,group_concat(if(`key`='name',value,'') separator '') as `name` 3,group_concat(if(`key`='kana',value,'') separator '') as `kana` 4,group_concat(if(`key`='add',value,'') separator '') as `add` 5,group_concat(if(`key`='mail',value,'') separator '') as `mail` 6,group_concat(if(`key`='tel',value,'') separator '') as `tel` 7from tbl_a 8group by `user_id`;

投稿2016/07/20 02:38

編集2016/07/20 02:52
yambejp

総合スコア114505

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

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

u-sukesan

2016/07/20 02:46

いただいた回答のような結合を以下の2つのテーブル間で行っているものもあるのですが LEFT JOINというのは2つのテーブルの結合だけで利用するわけではないのですね 一度やってみます
u-sukesan

2016/07/20 03:26

回答ありがとうございます。 説明不足で大変申し訳ございません。 DBレコードには user_id key value 1 name 高橋 1 kana たかはし 1 add 東京都 1 mail abc@def.gh 1 tel 000-000-0000 2 2 3 3 とその他のuser_idも含むためwhere区 が必要になります。 GROUP BY と where 区の併用はできませんよね お手数おかけします
yambejp

2016/07/20 04:18

本筋からすこし離れますが命題のようなデータ管理はあまり推奨されません。 たとえばテーブルの項目管理をする場合、「必須項目」と「任意項目」があります。 とくに名前、よみがな、住所、メールアドレス、電話番号などは すべて必須項目でよいかと思います。 そうなると最初からuser_idを主キーにして一覧にしておけばいいでしょう 一方任意項目については趣味とかペットとか、かならずしもあるかどうかわからない ものを管理します。項目がすくなければ必須項目のように管理してもいいですし 項目が多ければ今回の命題のような管理の方が効率的になります。 あとは正規化を含めて学習しながら拡張していってください
dupont_kedama

2016/07/20 05:00

私もyambejpさんの最後のコメントに概ね同意です。 このような設計を「エンティティ・アトリビュート・バリュー (Entity-Attribute-Value)」と呼び、「SQLアンチパターン」という書籍でも避けるべき設計の例として挙げられています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問