web-dev-qa-db-ja.com

カテゴリとそのすべて(nレベル)のサブカテゴリのIDを選択するにはどうすればよいですか?

親カテゴリのほかに、すべての子行を再帰的に収集したいと思います。

(疑似コード)_SELECT IDs FROM #_categories WHERE parent = father_

代替として、_SELECT IDs WHERE the first part of path is the parent's path_。

これは正しいです?最も効率的な方法は何ですか?

さらに良い:

私が必要とするものを達成するための標準的な方法(おそらくContentModelCategoriesにあります)はありますか? ContentModelCategories::getItems(true)を使用する必要がありますか?すでに「親」カテゴリIDを持っている場合、どのように呼び出すのですか?

実用的な例は本当に感謝されます。

1
smz

私がこれを「私の答え」として公開するのは気が進まない。おそらくPHPと私がJoomlaプログラマーであることがいかに悪いかを示すためですが、動作するように...ここにあります:

static function GetCategoriesWithChildren($categories) {
   $results = array();
   $db = JFactory::getDbo();
   foreach ($categories as $baseCategory)
   {
      $query = $db->getQuery(true);
      $query->select('c.path');
      $query->from('#__categories AS c');
      $query->where('c.published > 0');
      $query->where('c.id = ' . $baseCategory);
      $db->setQuery($query);
      $fathersList = $db->loadObjectList();
      foreach ($fathersList as $father)
      {
         $results[] = $baseCategory; // This adds the father only if it is published
         $query = $db->getQuery(true);
         $query->select('c.id');
         $query->from('#__categories AS c');
         $query->where('c.published > 0');
         $query->where('c.path LIKE \'' . $father->path . '/%\'');
         $db->setQuery($query);
         $children = $db->loadObjectList();
         foreach ($children as $category)
         {
            $results[] = $category->id;
         }
      }
   }
   return $results;
}

この関数は、引数としてカテゴリIDの配列を取り、それらすべてのIDと任意の子カテゴリのIDを含む配列を返します。

誰かがそれをより良くすることができるならば、私は心から感謝し、私の「選択された答え」をそれに変えます。ありがとう!

乾杯!

smz

0
smz

ここでmysql結合マップを確認してください: http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg

それらの1つはあなたが探しているものです。

2
user1507

サブクエリを使用してみてください...父親のカテゴリのIDがわかっていて、エイリアスが一意であることを考えると、このアイデアを試すことができます(PHPに変換する必要があります)またはもちろん、引用符付きのSQLコードなど):

SELECT id 
FROM categories 
WHERE path LIKE CONCAT(%,(SELECT alias FROM categories WHERE id = yourid),%) 
AND WHERE id NOT IN 
  (SELECT id 
   FROM categories 
   WHERE alias LIKE CONCAT(%,(SELECT alias FROM categories WHERE id = yourid))
);

最後の部分は、あなたの父親カテゴリーの父親カテゴリーの戻りを防ぐことです。別のクエリでエイリアスを取得して、このクエリを簡略化し、2番目のサブクエリを回避することもできます(これも冗長です)。より効率的なソリューションを考えるのは今では遅すぎます。それは他の人に任せます。結果にはおそらく親カテゴリは含まれませんが、そのカテゴリのIDはすでにわかっています。

未検証。

編集:エイリアスの代わりにパスを使用します

SELECT id
FROM categories
WHERE path LIKE CONCAT(
  (SELECT path 
   FROM categories
   WHERE id = yourid),%);
1
elk