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

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

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

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

PHP

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

Q&A

解決済

3回答

1199閲覧

テーブルAにデータを格納した時に自動付与されるIDをテーブルBのカラムにしたい。

yas_usa

総合スコア14

MySQL

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

PHP

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

0グッド

0クリップ

投稿2018/03/22 09:01

前提

MysqlをPHPからいじりたいのですが、外部に公開されていない事とアナリティクスでアクセス状態やPDFのダウンロード状況を把握するためセッションにアカウント名を入れてGETで動かしています。

データベースには、お知らせというテーブルがあり、その中にはIDとタイトルとお知らせ内容があります。
IDはAUTO_INCREMENTで自動で振っています。

|ID|タイトル|内容|
|:3|:---○--:|---:|
|:2|:---○--:|---:|
|:1|:-------:|---:|

実現したいこと

お知らせが作成された時点で別テーブルのカラムをお知らせIDとして増やし、ユーザーがお知らせを読んでお知らせを読みましたと言うボタンをクリックしたら、カラム読んだというサインとして下記の様に○が入るようにしたいと思います。

|ユーザー|ID1|ID2|ID3|ID4|
|:hoge1 |:○:|:○:|:○:|--:|
|:hoge2 |:○:|:--:|:○:|--:|
|:hoge3 |:--:|:○:|:○:|--:|

該当のソースコード

ニュース.php
$stmt = $mysqli->prepare("INSERT INTO topics (news, info) VALUES (?, ?, ?)");
$stmt = $mysqli->prepare("ALTER TABLE 別テーブル ADD '.$id.' INT(4) NULL AFTER 'ユーザー'");
$stmt->bind_param('ss', $_POST["news"], $_POST["info"]);
if($stmt->execute())
if($_SERVER['REQUEST_METHOD'] === 'POST') {
$url = $_SERVER["REQUEST_URI"];
header("Location: topicall.php");

<form method="POST" action="別テーブル.php"> <input type="hidden" name="account" value="<?php echo htmlspecialchars($_SESSION["account"], ENT_QUOTES); ?>"> <input type="hidden" name="<?php echo $nid; ?>" value="○"> <input type="submit" class="primary" value="お知らせを確認しました!"> </form>

で、お知らせテーブルは出来ているのですが、カラムを増やす事ができません。

当方PHPとMysqlをまっさらから始めて一週間ほどで、根本的な間違いやセキュリティーの問題があるだろうと言う事は分かっています。

良い手があればと思うのですが、どなたかご教授頂けると幸いです。

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

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

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

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

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

guest

回答3

0

テーブルのレイアウトをオンラインで変更するようなことはやっちゃ駄目です。
行として追加するようにしましょう。

見た目で横に展開したいような場合は、GROUP_CONCAT()が使用できます。

MySQLのGROUP_CONCATがアツい
他にも参考になる記事はありますので、検索してみてください。

投稿2018/03/22 09:14

sazi

総合スコア25188

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

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

sazi

2018/03/22 09:44

幾つか回答が寄せられたので、混乱しないようにコメントしておきます。 私の回答で、 >行として追加するようにしましょう。 部分の具体的なものが、luckerさんの回答 >GROUP_CONCAT() を使用しない方法が yambejpさんの2番目のSQLです。 ※カラムを増やさないというのは全員同じです。
yas_usa

2018/03/24 08:49

何故オンラインで使ってはいけないのか分かりませんが、 こちらもGROUP_CONCAT()も参考にさせていただきます。 ありがとうございました!
sazi

2018/03/24 11:06

オンラインで使っちゃいけないのは、照会や更新などとのタイミングが取りずらく、場合によってはデータ破損となる可能性があるからです。 敢えてそんな危険は冒さない方が良いという事です。
yas_usa

2018/03/25 15:40 編集

そのようなリスクがあるためという事なんですね。 無知の為、理由も含めてご教授頂けるのは非常にありがたいです! ありがとうございます。
guest

0

ベストアンサー

とにかくデータの持ち方が悪いです。
まずはuserとdocを分けて、user_docという中間テーブルを持ちます

sql

1create table user(uid int unique,uname varchar(30)); 2insert into user values(1,'hoge1'),(2,'hoge2'),(3,'hoge3'); 3create table doc(did int unique,dname varchar(30)); 4insert into doc values(1,'fuga1'),(2,'fuga2'),(3,'fuga3'); 5create table user_doc(uid int,did int,unique(uid,did)); 6insert into user_doc values(1,1),(1,2),(1,3),(2,1),(2,3),(3,2),(3,3);

その上で、userテーブルとuser_docテーブルを利用して表をつくります

SQL

1select t1.uid 2,case sum(t1.did=1) when 0 then '' when 1 then '○' end as ID1 3,case sum(t1.did=2) when 0 then '' when 1 then '○' end as ID2 4,case sum(t1.did=3) when 0 then '' when 1 then '○' end as ID3 5,case sum(t1.did=4) when 0 then '' when 1 then '○' end as ID4 6from user_doc as t1 7left join user as t2 on t1.uid=t2.uid 8group by uid;

横方向へIDを自動的に増やしていくのにはプロシージャというもので処理します
今回は煩雑にナリそうなので、上記まで理解することをおすすめします

プロシージャまで

docにfuga4を追記した上でリストを自動でつくります

  • 元データ

SQL

1create table user(uid int unique,uname varchar(30)); 2insert into user values(1,'hoge1'),(2,'hoge2'),(3,'hoge3'); 3create table doc(did int unique,dname varchar(30)); 4insert into doc values(1,'fuga1'),(2,'fuga2'),(3,'fuga3'),(4,'fuga4'); 5create table user_doc(uid int,did int,unique(uid,did)); 6insert into user_doc values(1,1),(1,2),(1,3),(2,1),(2,3),(3,2),(3,3);
  • プロシージャ作成(1回だけ実効する)

SQL

1drop procedure if exists myproc; 2delimiter // 3create procedure myproc() 4begin 5declare a int; 6declare b varchar(100); 7declare done int default 0; 8declare cur cursor for 9select did,dname from doc order by did; 10declare continue handler for sqlstate '02000' set done=1; 11set @sql='select t3.uname,t2.* from (select t1.uid '; 12open cur; 13repeat 14fetch cur into a,b; 15if not done then 16set @sql=concat (@sql,',case sum(t1.did=',a,') when 0 then "" when 1 then "○" end as ',b,' '); 17end if; 18until done end repeat; 19close cur; 20set @sql=concat (@sql,'from user_doc as t1 '); 21set @sql=concat (@sql,'group by uid ) as t2 '); 22set @sql=concat (@sql,'inner join user as t3 on t2.uid=t3.uid '); 23prepare stmt from @sql; 24execute stmt; 25end 26// 27delimiter ;
  • 実行

SQL

1call myproc;

投稿2018/03/22 09:32

編集2018/03/22 09:49
yambejp

総合スコア114829

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

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

yambejp

2018/03/22 09:50

せっかくなのでプロシージャのsampleも付けておきます
sazi

2018/03/22 11:33

えー、group_concat()推し、じゃなかったんですか。
yambejp

2018/03/22 11:35

group_concat()推しですよ。 でもさきにsaziさんが書いてたのでプロシージャにしてみました
sazi

2018/03/22 11:52

えー、group_concat()の結果をカラム分割してくれるストアドだったら良かったのに。
yas_usa

2018/03/24 18:14 編集

具体的なコードを出していただけたのでBAにさせていただきます。 色々テストしながら試させていただきます。 ありがとうございました!
guest

0

カラムは alter table で増やせるんですが、
https://www.dbonline.jp/mysql/table/index20.html

そういう事は、是非、止めましょう。

###既読テーブル

ユーザー*ID*
hoge11
hoge13
hoge22
hoge41
hoge44

(* プライマリキー)

こんなテーブルを作って、既読の情報だけ格納します。
読みだすときはユーザーをキーとして、お知らせテーブルと既読テーブルをJOINします。

ポイントは、ユーザーとIDに対して複合プライマリキーを指定する事です。

投稿2018/03/22 09:20

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yas_usa

2018/03/24 08:44

JOINまで分かっていないのですが、さらに精進します。 概念のヒントになりました、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問