2

1 つのテーブルからカテゴリとサブカテゴリを表示するための SQL クエリを作成する際に、多くの問題が発生しています。次の列があります。

category_id
category_name
category_parent
category_order

基本的に私が結果として生成したいのはこのようなものです

parent category 1
sub category 1
sub category 2
parent category 2
sub category 1
sub category 2
sub category 3
parent category 3
sub category 1

category_order が 0 に設定されている場合、カテゴリまたはサブカテゴリは、作成された順序に基づいて並べ替えられる必要があります。そのために、IDでソートする予定です。

可能であれば、UNIONを使用して、それらがすでに順番になっているようにしたいので、ループする必要があります。誰でもこのクエリの作成を手伝ってもらえますか。

実際、私はすでに JOIN を使用するものを持っていますが、結果は私が望むほど正確ではありません。

これは私の以前のクエリです:

SELECT
fcat.id fcat_id,
fcat.name fcat_name,
fcat.order fcat_order,
fcat.parent fcat_parent,
fsub.id fsub_id,
fsub.name fsub_name,
fsub.order fsub_order,
fsub.parent fsub_parent
FROM forum_categories AS fcat
LEFT OUTER JOIN forum_categories AS fsub ON fcat.id = fsub.parent
ORDER BY ISNULL(fcat.order) ASC, fcat.id ASC, ISNULL(fsub.order) ASC, fsub.id ASC

ただし、親カテゴリとサブカテゴリが結合されているため、サブカテゴリは並べ替えられません。私のクエリは親のみをソートします。

4

6 に答える 6

5

ここで興味深いのは順序だと思います。特に、カテゴリ内の順序付けは興味深いものです。これを説明するフィドルを作成しました:http://sqlfiddle.com/#!8/78059/3

クエリは次のとおりです。

select * from (
  select c.*,
  coalesce(nullif(c.parent, 0), c.id) as groupID,
  case when c.parent = 0 then 1 else 0 end as isparent,
  case when p.`order` = 0 then c.id end as orderbyint
  from category c
  left join category p on p.id = c.parent
) c order by groupID, isparent desc, orderbyint, name

親であるかどうかで、各カテゴリに注釈を付けることができます。次に、カテゴリをグループ化できます。各グループ内で、順序は親順序に依存します。parent.orderここでは、が 0 のときに id に基づいてorderbyint並べ替えを行っていnameます。

于 2013-06-29T18:59:49.857 に答える
2

ツリーの深さが 2 に制限されている場合:

select c1.*, 
       c2.*,
       if (c2.category_parent is NULL, "parent category", "sub category") as text
from cat c1 left join cat c2 
    on c1.category_id = c2.category_parent
order by c1.category_id, c2.category_id

条件を使用してc2.category_parent is NULL、カテゴリのレベルをテストできます。

于 2013-06-29T17:56:16.600 に答える
0

簡単な方法を見つけました。階層とアルファベット順に並べられています。

まず、例を見るために必要な SQL を入れます。

CREATE TABLE IF NOT EXISTS `categories` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_parent` int(11) NOT NULL,
  `category_name` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
  PRIMARY KEY (`category_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;

結果を得るための高速挿入:

INSERT INTO categories( category_id, category_parent, category_name) VALUES (1, 0, 'カテゴリ番号 1'), (2, 0, 'カテゴリ番号 2'), (3, 0, 'カテゴリ番号 3'), (4, 0, 'カテゴリ番号 4'), (5, 0, 'カテゴリ番号 5'), (6, 0, 'カテゴリ番号 6'), (7, 2, 'カテゴリ 2 の最初のサブカテゴリ'), (8, 2, '2 番目のサブカテゴリカテゴリ 2 のサブカテゴリ'), (9, 2, 'カテゴリ 2 の 3 番目のサブカテゴリ (アルファベット順のため最初に表示する必要があります)'), (10, 1, 'カテゴリ番号 1 の最初のサブカテゴリ'), (11, 1 , 'カテゴリ番号 1 の 2 番目のサブカテゴリ (アルファベット順のため、最初に表示する必要があります)');

そしてSQL文:

SELECT category_id,category_parent,category_name,
(CASE
    WHEN category_parent=category_id OR category_parent=0  THEN category_id
    WHEN category_parent<>category_id THEN category_parent
END) AS 'the_parent'
FROM categories ORDER BY the_parent ASC, category_parent ASC, category_name ASC

役に立つことを願っています

于 2015-01-19T17:11:16.680 に答える
0

私は同じ問題を抱えていて、多くの例またはTomasとJTsengのソリューションをテストしました。これらには、番号順またはサブカテゴリ順がありませんでした。JTseng クエリを変更しましたが、(私にとっては) これで問題ありません。

SELECT c.*,
  CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order,
  CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid ,
  CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order
FROM `category` c
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id
ORDER BY  sort_order , catid, subcat_order

このソリューションを作成したのは、3 つの文字列で構成される連結文字列を作成して順序付けを行うソリューションをテストした後です。親とその子は、子の順序に従って並べ替えられます (親の猫を最初に配置するために、0 に設定された仮想のサブの猫の並べ替え順序が与えられました)。しかし、この文字列の順序付けは、数字ではなくアルファベット順でした。したがって、JTseng がこのように行ったように、順序付け文字列を追加の数値フィールドに転置します。

  • 最初の CASE WHEN は、カテゴリが親かどうかを検出するためにあります。親の場合、親の並べ替え順序が維持され、サブカテゴリの場合、その並べ替え順序は親の並べ替え順序に置き換えられます
  • 2 番目の CASE WHEN は、途中でサブカテゴリ ID をその親カテゴリ ID に置き換えるために使用されます (これは JTseng グループ ID と同等です)。
  • 3 番目の CASE WHEN は、親のサブソート順を 0 に設定し、サブキャットのソート順を維持するために使用されます

LEFT JOIN アクションを表示するには、phpMyAdmin ページで次のクエリを実行します。

SELECT c.cat_id as ccatid,c.cat_sort_order as ccatsortorder, is_par.cat_id as isparcatid,is_par.cat_parent_id as ispar_catparentid,is_par.cat_sort_order as isparcatsortorder,
  CASE WHEN isnull(is_par.cat_id) THEN c.cat_sort_order ELSE is_par.cat_sort_order END as sort_order,
  CASE WHEN isnull(is_par.cat_id) THEN c.cat_id ELSE is_par.cat_id END as catid,
  CASE WHEN isnull(is_par.cat_id) THEN 0 ELSE c.cat_sort_order END as subcat_order
FROM `category` c
LEFT JOIN `category` is_par ON is_par.cat_id = c.cat_parent_id
于 2013-10-13T08:37:40.120 に答える