2

私が持っているもの:

階層的にリストされたカテゴリの表: カテゴリー表

商品一覧です。この列は次category_idを参照していcategory.idます。 ここに画像の説明を入力

私がやろうとしていること:

lft指定された値を持つカテゴリの製品をカウントするクエリを設計しようとしていrgtます。
例: lft=2rgt=の間11には、ID が3、 、の 3 つの「即時サブカテゴリ」が4あり5ます。wirelessの範囲内の直接のサブカテゴリではないため、サブカテゴリが含まれていないことlftを確認してください。ただし、このサブカテゴリの製品は、下の図からわかるようrgtに、その直接のサブカテゴリの一部としてカウントされます。には 1 つの直接製品があり、別の製品はそのサブカテゴリに関連しています。headphoneHeadphonewireless

結果は次のようになります。

ここに画像の説明を入力

lft指定されrgtた値内の直接のサブカテゴリを取得するクエリを作成することができました。

    SELECT node.name,node.id, (COUNT(parent.name) - 1) AS depth
    FROM category AS node,
        category AS parent
    WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND parent.lft BETWEEN {$lft} AND {$rgt}
    GROUP BY node.name
    HAVING depth = 1
    ORDER BY node.lft

lftこのクエリは、最後の図のように=2rgt=の場合にサブカテゴリを取得しますが11、カウントが欠落しています。

私はかなり長い間その結果の表を正しく取得するために実験を行ってきましたが、これが私が思いついたものですが、残念ながら、私が知らない何らかの理由でうまく機能しません. これに関する助けに感謝します。

            SELECT parent.name, COUNT(product.category_id)
    FROM category AS node1 ,
            product, (
                SELECT node.name,node.id,node.lft,node.rgt, (COUNT(parent.name) - 1) AS depth
                FROM category AS node,
                    category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                    AND parent.lft BETWEEN {$lft} AND {$rgt}
                GROUP BY node.name
                HAVING depth = 1
                ORDER BY node.lft
            ) as parent
    WHERE node1.lft BETWEEN parent.lft AND parent.rgt
            AND node1.id = product.category_id
    GROUP BY parent.lft
    ORDER BY parent.lft

更新: SQL フィドルを作成しようとしましたが、エラーの膨大なリストが表示されました:

    CREATE TABLE category 
        (
         id int auto_increment primary key, 
         name varchar(20), 
         lft varchar(20),
          rgt varchar(20)
        );

    INSERT INTO category
    (name, lft,rgt)
    VALUES
    ('ELECTRONICS','1','18'),
    ('TV & audio','2','11'),
    ('Home theater','3','4'),
    ('Blu-ray','5','6'),
    ('Headphone','7','10'),
    ('Wireless','8','9'),
    ('Gaming','12','17'),
    ('Game consoles','13','14'),
    ('Video games','15','16');

    CREATE TABLE product 
        (
         id int auto_increment primary key, 
         name varchar(20), 
         category_id varchar(20)
        );
    INSERT INTO product
    (category_id, name)
    VALUES
    ('4','Sony Blu-ray player'),
    ('5','Beats Solo HD'),
    ('6','Beats Solo HD wireless'),
    ('8','PlayStation'),
    ('8','Xbox');       
4

1 に答える 1

0

次のようなものよりも簡単(?)でしょうか?

SELECT category.name, COALESCE(C.total,0) as products
  FROM category 
  LEFT JOIN
    (SELECT category_id, count(*) as total FROM product GROUP BY category_id) AS C
  ON C.category_id = category.id
  WHERE category.lft > @min_range AND category.rgt < @max_range

「ノイズ」を無視すると、これはカテゴリ テーブルと各カテゴリの製品数との間の単なる左結合 (製品なしでカテゴリを保持するため) です。

テスト ケースを使用すると、以下が生成されます。

+--------------+----------+
| name         | products |
+--------------+----------+
| Home theater |        0 |
| Blu-ray      |        1 |
| Headphone    |        1 |
| Wireless     |        1 |
+--------------+----------+
4 rows in set (0.00 sec)

ご覧のとおり、予想される結果には表示されないワイヤレスの結果が生成されますが、問題の説明を理解していると、そこにあるはずです。

于 2013-08-10T09:54:59.140 に答える