0

私は2つのテーブルを持っています

company および company_meta

会社のテーブルには次のものがあります

------------------------
id | title | city
------------------------
1 | abc | nice city
2 | def | awesome city
------------------------

company_meta には

------------------------------------------------
id | company_id | meta_key | meta_value
------------------------------------------------
1 | 1 | feature_parking | Yes
2 | 1 | feature_fireexit | Yes
3 | 2 | feature_parking | No
4 | 2 | feature_gym | Yes
------------------------------------------------

今、私はLaravelでこれらの2つのテーブルを結合し、次のように印刷したいと考えています

Company 1 : nice city
Parking : Yes
Fire Exit : Yes
Gym : No (if not mentioned it must automatically consider as NO)

Company 2 : awesome city
Parking : No
Fire Exit : No
Gym : Yes

Foreach ステートメントを使用します。

このようなメタを使ったテーブル関係については、Wordpress DB を見て思いつきました。また、誰かがこのタイプの関係メソッドと呼ばれるものを教えてくれるので、同じことについてもっとグーグルで検索します.

また、DB 関係を作成する他のより良い方法はありますか? 私の DB には約100,000 の企業データがあり、各企業にはそれぞれ 10 ~ 12 の特徴があります。そのため、非常に大きなデータベースになります。

4

2 に答える 2

1

subquery以下のクエリでもこれを行うことができます。言及されていない場合は、自動的に NO と見なす必要があります。

SELECT  
q.company_id,q.company_name,
CASE WHEN q.parking IS NULL THEN 'No' ELSE q.parking END AS parking,
CASE WHEN q.fireexit IS NULL THEN 'No' ELSE q.fireexit END AS fireexit,
CASE WHEN q.gym IS NULL THEN 'No' ELSE q.gym END AS gym
 FROM (
SELECT cm.`company_id`,
(SELECT `title` FROM `company` WHERE id=cm.`company_id`) AS company_name,
(SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_parking') AS parking,
(SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_fireexit') AS fireexit,
(SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_gym') AS gym 
 FROM `company_meta` cm GROUP BY cm.`company_id` ) q

wordpress$wpdbで、データベース インタラクションのグローバル変数を定義します。

global $wpdb;

$results= $wpdb->get_results("    SELECT  
    q.company_id,q.company_name,
    CASE WHEN q.parking IS NULL THEN 'No' ELSE q.parking END AS parking,
    CASE WHEN q.fireexit IS NULL THEN 'No' ELSE q.fireexit END AS fireexit,
    CASE WHEN q.gym IS NULL THEN 'No' ELSE q.gym END AS gym
     FROM (
    SELECT cm.`company_id`,
    (SELECT `title` FROM `company` WHERE id=cm.`company_id`) AS company_name,
    (SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_parking') AS parking,
    (SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_fireexit') AS fireexit,
    (SELECT `meta_value` FROM `company_meta` WHERE company_id=cm.`company_id` AND meta_key ='feature_gym') AS gym 
     FROM `company_meta` cm GROUP BY cm.`company_id` ) q");

foreach($results as $r){

echo "Company ".$r->company_id ." : ".$r->company_name;
echo "Parking : ".$r->parking;
echo "Fire Exit : ".$r->fireexit;
echo "Gym : ".$r->gym;
}

ここにあなたのフィドルがあります

私はそれがあなたにとって完璧に機能することを願っています

于 2013-07-07T17:47:15.877 に答える
1

これは1 対多の関係です。おっしゃる通り、悪くはないようです。この種の設計は、各企業が持つ可能性のあるメタ属性の数を事前に知らなくても問題ありません。

両方のテーブルを効率的にマージできるように、2 番目のテーブルの *company_id* 列にインデックスを追加することをお勧めします。予想されるデータベース サイズについて心配する必要はありません。膨大な数のレコードではありません (データベースは数百万のレコードを処理するように設計されています)。特定の機能セットの有無に基づいてデータをフィルタリングする場合は、*meta_key* に別のインデックスを追加することもできます (つまり、機能 A と B を持ち、C を持たないすべての企業を教えてください)。

于 2013-07-07T17:22:01.907 に答える