テーブル構成が以下のようになっているとします。
■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> </td>
<td>年齢</td>
</tr>
</table>
どういうSQL文を書けばよいのでしょうか?MySQLは4.1.22を使っています。
コメント欄に書き込めないので、質問欄にて失礼します。
mainテーブルとgroupテーブルの間に関係があるという前提だと思うのですが、その条件を具体的にお知らせください。
[group.名前] と [main.名] が合致するということですか?
それとも、[group.名前] の内容は [main.姓] と [main.名] の和に合致するということですか? この場合、[group.名前] の中の姓名の間に空白文字が含まれているということはありませんよね?
少なくとも2つのSQL文が必要です。
以下のアルゴリズムで、ご質問のHTMLを生成できます。
(2)gidの値を$gidに代入する
(5)ループ終了
回答ありがとうございます。ただ疑問点が2つあります。
1:(4)で表示しても質問のtable表示にはならないのでは?(rowspan の値を取得した後、tdをwhileで繰り返しても、横表示になります)
2:(1)だと「グループ化しているもののみ」表示であるので、グループ化していないmainテーブルの内容を表示できないのでは?
2はUNIONなどでグループ化していないテーブルを結合する方法があると思いますが、1の表示面については良い案が思い浮かびません。
こんな感じでどうでしょうか?
-- 表定義 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側で出力抑止する方が簡単です。
参考にさせていただきます。ありがとうございました。
main、groupと、どちらのテーブルにも「g_id」がありますが、mainテーブルのレコードをグループ扱いさせる為に、このようなテーブル設計にしています。(つまり、グループ化したくない場合は、g_idの値が0のままです)
例文で言いますと、mainテーブルの「姓・名」にg_idが付いていますので、これは「グループ化したいレコード」となり、そのグループ名が「名前」と言うことです。
mainテーブルの「年齢」にはグループ名が付いていませんので、年齢のグループ名は表示されません。
目的は質問下部に書いたような表示ですので、テーブル設計がまずければそちらを変更しても構いません。