2017-05-09 11 views
0

私は、放棄された "Joomgalaxy" Joomlaプラグインのエントリの古いデータベースを持っています。複数テーブルのMySQL JOINステートメント

は3つのテーブル、joomgalaxy_entriesjoomgalaxy_fields、およびentriesテーブルからjoomgalaxy_entries_data

identries_dataテーブルでentry_idと一致するが、実際のフィールド名が別のテーブルに保存され、fields

あります缶誰かが正しいSQLステートメントで私を助けてくださいあなたがで見ることができるような結果を得るために究極の目標?私のMySQLの知識は非常に基本的なもので、私の検索ではLEFT JOINを使う必要があるように思えますが、戻り値の列名としてfield_nameの値を使用する方法がわかりません

ありがとうございます!

joomgalaxy_entries

--------------------------------------- 
| id | title | longitude | latitude | 
--------------------------------------- 
| 50 | John | -79.333333 | 43.669999 | 
| 51 | Bob | -79.333333 | 43.669999 | 
--------------------------------------- 

joomgalaxy_fields

これはそれをシンプルに保つためにちょうど2つの例を以下で、そこにちょうどこれらの2以上のもの、それは動的に処理することができなければならないであろうカラム名としてfield_nameを使用します。

-------------------------------- 
| id | field_type | field_name | 
-------------------------------- 
| 1 | textbox | websiteurl | 
| 2 | dropdown | occupation | 
-------------------------------- 

joomgalaxy_entries_data

「技術的には」任意の重複したエントリ(fieldidentry_id)があってはならない、上記の列名などからfield_nameを使用して影響を与えてはならないというのが私の理解からして、そこに終わるとどうなるでしょうか?

------------------------------------- 
| fieldid | field_value | entry_id | 
------------------------------------- 
| 1  | google.com | 50 | 
| 2  | unemployed | 50 | 
| 1  | doctor.com | 51 | 
| 2  | doctor  | 51 | 
------------------------------------- 

究極の目標

最終的に結果のこのタイプを取得しようと、私は次のようになり、データをエクスポートするためのMySQL Workbenchでそのステートメントを使用することができます。

------------------------------------------------------------------ 
| id | title | longitude | latitude | websiteurl | occupation | 
------------------------------------------------------------------ 
| 50 | John | -79.333333 | 43.669999 | google.com | unemployed | 
| 51 | Bob | -79.333333 | 43.669999 | doctor.com | doctor  | 
------------------------------------------------------------------ 

編集: 2つのフィールド以外にも、websiteurloccupationの2つのフィールドがあります。例えば、理論上は、理論上はfield_nameから値を引き出すと列名に使用されます

+0

重複して閉じるように投票してください。 http://stackoverflow.com/questions/1241178/mysql-rows-to-columnsを参照してください –

答えて

1

CASEステートメントのような条件付きロジックと、max()のような集計関数を使用することができますまたはmin()列としてこれらの値を返すために:

SELECT je.id, 
    je.title, 
    je.longitude, 
    je.latitude, 
    max(case when jf.fieldid = 1 then jed.field_value end) as WebsiteUrl, 
    max(case when jf.fieldid = 2 then jed.field_value end) as Occupation 
FROM joomgalaxy_entries je 
INNER JOIN joomgalaxy_entries_data jed 
    on je.id = jed.entry_id 
GROUP BY je.id, 
    je.title, 
    je.longitude, 
    je.latitude 

あなたはすべてのjoomgalaxy_entriesを返すようにしたい場合は、JOIN INNERを使用するだけで参加する一致する行がない場合でも、各テーブル内の値を持つjoomgalaxy_entries行を返します他のテーブルでは、INNER JOINをLEFT JOINに変更します。

+0

応答をありがとう、私は説明を更新し、複数のフィールドがあり、それらはすべて動的なので、私は特定のハードを使用することはできません50行のサブクエリを持たないコード化フィールド名 – sMyles

0

最初のステップは簡単です:

SELECT JE.id, JE.title, JE.longitude, JE.latitude 
FROM joomgalaxy_entries JE 

今あなたが参加する必要があり:

SELECT JE.id, JE.title, JE.longitude, JE.latitude, 
     JD.* 
FROM joomgalaxy_entries JE 
JOIN joomgalaxy_entries_data JD 
    ON JE.id = JD.entry_id 

今、あなたはこれはあなたしかいない2依存列

SELECT JE.id, JE.title, JE.longitude, JE.latitude, 
     MIN(CASE WHEN fieldid = 1 THEN JD.field_value END) as WebsiteUrl, 
     MIN(CASE WHEN fieldid = 2 THEN JD.field_value END) as Occupation 
FROM joomgalaxy_entries JE 
JOIN joomgalaxy_entries_data JD 
    ON JE.id = JD.entry_id 
GROUP BY JE.id, JE.title, JE.longitude, JE.latitude 

に行を変換する必要がありますフィールドの数が動的な場合は、別のaproachが必要になります。これは動作するはず

+0

応答ありがとう、正しくあり、複数のフィールドがあり、それらはすべて動的なので、50行のサブクエリを持たない特定のハードコード化フィールド名は使用できません – sMyles

0

:websiteurlや職業のいずれかがnullだった場合は、左が参加持っている理由があろうと

select id, title, longitude, latitude, 
    (select field_value from joomgalaxy_entries_data jed 
     where fieldid = (select id from joomgalaxy_fields 
         where field_name = 'websiteurl') 
     and jed.entry_id = je.id 
     ) as websiteurl, 
    (select field_value from joomgalaxy_entries_data jed 
     where fieldid = (select id from joomlgalaxy_fields 
         where field_name = 'occupation') 
     and jed.entry_id = je.id) as occupation 
    from joomgalaxy_entries je; 

注意、しかし、この解決策はとにかく、その場合には動作するはずです。

+0

応答をありがとう、私は説明を更新し、複数のフィールドがあり、それらはすべて動的なので、私は50 +サブクエリの行を持たない特定のハードコードフィールド名を使用することはできません – sMyles

+0

Yikes!それはあなたの問題を少し難しくします。 :)しかし、私はいくつかのオプションを試してみて、新しい答えを追加しました。お役に立てれば! –

1

あなたはこのような単純なクエリSELECT書くことができます:正直なところ、私は何を求めていることは可能であるかわからない... :)

SELECT je.id, je.title, je.longitude, je.latitude, 
(SELECT field_value FROM joomgalaxy_entries_data WHERE fieldid = 1 AND entry_id = je.id) AS websiteurl, 
(SELECT field_value FROM joomgalaxy_entries_data WHERE fieldid = 2 AND entry_id = je.id) AS occupation 
FROM joomgalaxy_entries je; 
+0

回答ありがとうございます。これはサブクエリの方がはるかに優れていることを実際に理解して理解するのに役立ちましたが、残念ながらこれは数多くのフィールドがあり、すべて動的です – sMyles

0

まあ、確かにそれは少し難しくなります静的なSQLクエリを使用します。しかし、もし私が間違っていたら、誰かが話してくれると確信しています。 SQL動的

では、次のSQLを実行した場合、それが生成されます、これは、MySQLと仮定すると生成 -

オプション1:

は、私はあなたが試すことができますいくつかのオプションを持っている、と述べたこと動的サブクエリ:

select concat('(select field_value from joomgalaxy_entries_data jed ', 
       'where fieldid = (select id from joomgalaxy_fields ', 
       'where field_name = ''', field_name, ''') ', 
       'and jed.entry_id = je.id) as ', field_name, ',') 
       from joomgalaxy_fields; 

は、そのコマンドの結果を取り、テキストエディタにコピー&ペーストし、先頭に次の行を追加します。

select id, title, longitude, latitude, 

そして最後に、このの残り:

from joomgalaxy_entries je; 

次に、あなたの新しい特級クエリを実行しているどのくらいのデータに応じて、コピーのカップ、ランチ、または良い夜の睡眠をつかむ行きますあなたのデータベースに。

また、SQLを手作業で編集する必要がないように、これらのすべてをストアドプロシージャに追加することもできます。また、私の構文はMySQLのために働くことに注意してください。他のデータベースには異なる連結演算子があるため、該当する場合は回避する必要があります。また、50以上の副問合せでは、このuber-queryは非常に遅く、このオプションを実行可能にするには遅すぎる可能性があります。

オプション2 - あなたが望むように構造化テーブルを作成し、

を移入がうまくいけば、これは自明であるが、ちょうどjoomgalaxy_fieldsテーブルから必要なすべての列を持つ新しいテーブルを作成します。次に、各列を別々に、簡単なSQLコマンドでなければならない一連のものに分けて配置します。あなたが指定したと信じているデータベースがもはや使用されていない場合にのみ、このオプションは有効です。そこから結果はちょうど:

select * from my_new_table; 
関連する問題