MySQLの表示について質問です。

テーブル構成が以下のようになっているとします。

■mainテーブル
[id][name][g_id]
1 姓   1
2 名   1
3 年齢  0

■groupテーブル
[g_id][name]
1   名前


そして、PHPを使い以下のように表示させたいと思っています。

<table border="1">
<tr>
<th>グループ名</th>
<th>表示名</th>
</tr>
<tr>
<td rowspan="2">名前</td>
<td>姓</td>
</tr>
<tr>
<td>名</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>年齢</td>
</tr>
</table>


どういうSQL文を書けばよいのでしょうか?MySQLは4.1.22を使っています。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/07/14 22:24:08
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:pahoo No.1

回答回数5960ベストアンサー獲得回数633

コメント欄に書き込めないので、質問欄にて失礼します。

mainテーブルとgroupテーブルの間に関係があるという前提だと思うのですが、その条件を具体的にお知らせください。


[group.名前] と [main.名] が合致するということですか?

それとも、[group.名前] の内容は [main.姓] と [main.名] の和に合致するということですか? この場合、[group.名前] の中の姓名の間に空白文字が含まれているということはありませんよね?

id:kt26

main、groupと、どちらのテーブルにも「g_id」がありますが、mainテーブルのレコードをグループ扱いさせる為に、このようなテーブル設計にしています。(つまり、グループ化したくない場合は、g_idの値が0のままです)


例文で言いますと、mainテーブルの「姓・名」にg_idが付いていますので、これは「グループ化したいレコード」となり、そのグループ名が「名前」と言うことです。

mainテーブルの「年齢」にはグループ名が付いていませんので、年齢のグループ名は表示されません。


目的は質問下部に書いたような表示ですので、テーブル設計がまずければそちらを変更しても構いません。

2008/07/10 16:54:26
id:pahoo No.2

回答回数5960ベストアンサー獲得回数633

ポイント20pt

少なくとも2つのSQL文が必要です。

以下のアルゴリズムで、ご質問のHTMLを生成できます。


(1)ループ開始
select * from group where 1; にヒットする毎

(2)gidの値を$gidに代入する

(3)<td rowspan="2"> の rowspan の値を求める
select * from main where gid=$gid;
(4)<td> 部分を求める
(3)のSQL文で name の値を表示する。

(5)ループ終了

id:kt26

回答ありがとうございます。ただ疑問点が2つあります。


1:(4)で表示しても質問のtable表示にはならないのでは?(rowspan の値を取得した後、tdをwhileで繰り返しても、横表示になります)

2:(1)だと「グループ化しているもののみ」表示であるので、グループ化していないmainテーブルの内容を表示できないのでは?


2はUNIONなどでグループ化していないテーブルを結合する方法があると思いますが、1の表示面については良い案が思い浮かびません。

2008/07/10 18:41:27
id:chuken_kenkou No.3

回答回数722ベストアンサー獲得回数54

ポイント60pt

こんな感じでどうでしょうか?

-- 表定義
create table `main`
(id           int primary key,
 name         varchar(10),
 g_id         int);
create table `group`
(g_id         int primary key,
 name         varchar(10));

-- テストデータ格納
insert into `group` values(1,'名前');

insert into `main` values
(1,'姓',1),
(2,'名',1),
(3,'年齢',0);

-- 検索
select
  g.name as グループ名,
  m.name as 表示名
 from `main` as m
  left join `group` as g on m.g_id=g.g_id
 order by
  case when g.g_id>0 then g.g_id
       else 99999
  end,
  m.id
;

g_id=0の場合は、g_idとして存在しえない最大値(今回の例では99999)でソートし、最後に表示するようにしています。

同じグループに属する項目が複数存在する場合、2項目目以降のグループ名を表示したくないといった場合は、SQLで無理矢理実現しようとするよりは、php側で出力抑止する方が簡単です。

id:kt26

参考にさせていただきます。ありがとうございました。

2008/07/14 22:23:36

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません