从与给定categoryID关联的所有子类别级别中选择列表

时间:2014-06-04 08:27:30

标签: mysql sql

我希望我能够解释得这么好。我有四个级别的类别,具有以下表格结构:

类别(catlevel = 0)

record_id   category
--------------------
1           Antiques & Collectibles
2           Art
3           Baby Gear

子类别(catlevel = 1)

record_id  category_id  subcategory
----------------------------------
1          3            Baby room & furniture
2          3            Backpacks & carrier
3          3            Bath time

subsubcategories(catlevel = 2)

record_id  subcategory_id  subsubcategory
---------------------------------------
1          1               Bookcases & shelves
2          1               Cushions
3          1               Lamps & lighting
4          1               Wall hangings & paintings

subsubsubcategories(catlevel = 3)

record_id  subsubcategory_id  subsubsubcategory
---------------------------------------------
1          4                  Animals
2          4                  Fairy tales
3          4                  Names & letters

我还有一个清单表如下。列表只有一个详尽的类别,即创建列表时,您必须在尽可能低的类别级别精确定义。即如果仍有较低的类别级别,您必须继续选择子类别,直到没有更低的级别。

record_id   catid   catlevel  title
-------------------------------------------------------
1           1        3        Wooden Animal Wall Hanging
2           1        2        Wooden Book Case
3           3        1        Bubble Bath

"catid"是我们所讨论的任何级别的唯一ID

"catlevel"定义实际的类别级别,因此级别“0”将是顶级“类别”,而级别“3”将是最低的“SubSubSubcategory”级别

网站前端有搜索功能。输入关键字并从下拉框中选择顶级类别(catlevel = 0)。您只能在此阶段选择顶级类别,不能选择较低的子类别级别。

我希望此搜索能够返回不仅位于该顶级类别下的列表,还会返回任何关联的子类别级别,直至catlevel 3。

因此,对于上面的示例,如果我在搜索框中输入“wooden”并从类别下拉列表中选择“Baby Gear”,我应该从“Listings”表中获取前两个记录。

1 个答案:

答案 0 :(得分:1)

这可能需要加入每个类别级别的列表表。

也许是这样,在高级别类别中检查'baby gear',找到任何匹配并使用coalesce来获得第一级匹配细节。不利的一面是,这将使用索引很差(可能不是一个额外的问题,使用%....%会阻止正在使用的索引)

SELECT DISTINCT COALESCE(b1.record_id, b2.record_id, b3.record_id) AS record_id,
        COALESCE(b1.catid , b2.catid , b3.catid ) AS catid,
        COALESCE(b1.catlevel, b2.catlevel, b3.catlevel) AS catlevel,
        COALESCE(b1.title, b2.title, b3.title) AS title
FROM categories a
INNER JOIN subcategories b ON a.record_id = b.category_id
LEFT OUTER JOIN listings b1 ON b1.catlevel = 1 AND b.record_id = b1.catid
INNER JOIN subsubcategories c ON b.record_id = c.subcategory_id
LEFT OUTER JOIN listings b2 ON b2.catlevel = 2 AND b.record_id = b2.catid
INNER JOIN subsubsubcategories d ON c.record_id = d.subsubcategory_id 
LEFT OUTER JOIN listings b3 ON b3.catlevel = 3 AND b.record_id = b3.catid
WHERE a.category = 'Baby Gear'
AND (b1.title LIKE '%wooden%'
OR   b2.title LIKE '%wooden%'
OR   b3.title LIKE '%wooden%')

也可以将多个查询联合在一起执行此操作: -

SELECT l.record_id, l.catid, l.catlevel, l.title
FROM categories a
INNER JOIN subcategories b ON a.record_id = b.category_id
INNER JOIN listings l ON l.catlevel = 1 AND b.record_id = l.catid
WHERE a.category = 'Baby Gear'
AND l.title LIKE '%wooden%'
OR   
UNION
SELECT l.record_id, l.catid, l.catlevel, l.title
FROM categories a
INNER JOIN subcategories b ON a.record_id = b.category_id
INNER JOIN subsubcategories c ON b.record_id = c.subcategory_id
INNER JOIN listings l ON l.catlevel = 2 AND b.record_id = l.catid
WHERE a.category = 'Baby Gear'
AND l.title LIKE '%wooden%'
UNION
SELECT l.record_id, l.catid, l.catlevel, l.title
FROM categories a
INNER JOIN subcategories b ON a.record_id = b.category_id
INNER JOIN subsubcategories c ON b.record_id = c.subcategory_id
INNER JOIN subsubsubcategories d ON c.record_id = d.subsubcategory_id 
INNER JOIN listings l ON l.catlevel = 3 AND b.record_id = l.catid
WHERE a.category = 'Baby Gear'
AND l.title LIKE '%wooden%'

如果重新设计数据库以使用嵌套集模型,则此问题可能会更容易解决。