我希望我能够解释得这么好。我有四个级别的类别,具有以下表格结构:
record_id category
--------------------
1 Antiques & Collectibles
2 Art
3 Baby Gear
record_id category_id subcategory
----------------------------------
1 3 Baby room & furniture
2 3 Backpacks & carrier
3 3 Bath time
record_id subcategory_id subsubcategory
---------------------------------------
1 1 Bookcases & shelves
2 1 Cushions
3 1 Lamps & lighting
4 1 Wall hangings & paintings
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”表中获取前两个记录。
答案 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%'
如果重新设计数据库以使用嵌套集模型,则此问题可能会更容易解决。