2017-01-23 8 views
0

カラム 'id'と 'name'を持つサブカテゴリとカラム 'id'、 'name'とforeign key 'subcategory_id '私は望む結果を得るためにMYSQLクエリを見つけることができません

私は、目標オブジェクトの配列であるプロパティ 'goals'を持つサブカテゴリオブジェクトの配列になるクエリが必要です。私はこれを実行しようとしましたThusfar ..結果は他の言語で同じになります(別の構文で)

result = [ 
      {id: 1, name: "name", goals: [{id: 1, name: "goalName"}, {...}, {...}]}, 
      {...}, 
      {...} 
     ] 

しかし: はあまりにも結果はJSコードでどのように見えるかの例を与えますこのように、参加-左に:目標は、単一のサブカテゴリの下にグループ化されていない

SELECT sc.ID as subcatId, sc.name as subcatName, g.ID as ID, g.name as name 
FROM needs_subcategories as sc 
LEFT JOIN needs_goals as g 
ON sc.ID=g.subcategory_id 

しかし..私はクエリで行うことが可能であるべきであるように感じるが、私は/グーグルを把握することはできませんどのように私は私のために質問をフレーズするかわからないので、それを行う方法SQLの知識を覚えておいてください。

あなたは私を助けることを願っています!

ありがとうございます。

+0

最後に、JSからmysqlへの直接アクセスがないことを確認しました。 –

+0

上記の単一のクエリが上記の結果をもたらす方法はありません。すべてのデータを取得し、必要に応じてデータを変換します。 lodashjsは非常に有用なツールかもしれません。あなたがnodejsアプリでデータを取得しているか、ブラウザにデータを送信している場合。 – gaurang171

+0

@RC。私はちょうど返されたい配列を説明するためにJS形式を使用しました..私は同じ形式を使用してNodeJSを使用しています – Guinn

答えて

0

@tadmanが彼のコメントで示唆されているように私はgroupByを使用して、これを解決しました。

私はこのようになります(thisの回答の情報に基づいて)関数を作成:

function processResults(collection, groupKey) { 
    var result = _.chain(collection) 
        .groupBy(groupKey) 
        .toPairs() 
        .map(function (currentItem) { 
         // 'text' and 'children' are the keys I want in my resulting object 
         // children being the property that contains the array of goal objects 
         return _.zipObject(['text', 'children'], currentItem); 
        }) 
        .value(); 
    return result; 
} 

グループ化された目標を持つオブジェクトの配列になり!私は関数を構造化したので(ハードコードされたキー名で)、それは私の特定のケースでしか機能しません。関数を一般化したい場合は、パラメータを追加することができます。

1

あなたはクエリでそれを達成することはできません。 MySQLはそれを行うことはできません。

現在、それぞれのサブカテゴリを持つすべての目標をフェッチしています(サブカテゴリが繰り返されます)。

コードを使用して目的の配列に変換することができます(例:php、他の言語に変換できます)。

$result=array(); 
$lastSubcatId=null; 
$goals=array(); 
while($row=$query->fetch_object()) { //assuming $query is the resultset 
    if($lastSubcatId&&$lastSubcatId!=$row->subcatId) { 
     $row->goals=$goals; 
     $result[]=$row; //or you could assign each desired property 
     $goals=array(); 
    } 
    $goals[]=$row; //or you could assign each desired property 
} 
//surely, there are items left in $goals 
if($lastSubcatId) { 
    $row->goals=$goals; 
    $result[]=$row; //or you could assign each desired property 
} 

しかし、もっと効率的な方法は、複数のクエリで、私が思うに、次のようになります。最後に

$result=array(); 
$subcats=$db->query("SELECT * FROM needs_subcategories"); 
while($subcat=$subcats->fetch_object()) { 
    //you might want to use prepared statements, I'm just simplifying 
    //it will not only be safer, but reusing the prepared statement will increase the performance considerably 
    $goals=$db->query("select * from needs_goals where subcategory_id=".$subcat->ID); 
    $temp=array(); 
    while($goal=$goals->fetch_object()) $temp[]=$goal; 
    $subcat->goals=$temp; 
    $result[]=$subcat; 
} 
+0

文字列連結を使用してクエリにスラミングを行うのは怖いので、これを実動コードではしないことをお勧めします。プレースホルダ値を持つプリペアドステートメントを使用します。 [Sequelize](http://sequelizejs.com)でNode.jsでも可能です。 – tadman

+0

はい...それはコメントが言うことです。 「準備されたステートメントを使用したいと思うかもしれません。私は単純化しています。 – Gabriel

+0

ああ、あなたがスクロールする場合にのみ表示されます。 – tadman

関連する問題