2014-03-04 37 views
1

我试图创建一个“eBay”风格类别菜单,当用户从多选字段中选择一个项目时,它将添加一个新的多选以及任何子类别,如果子类别包含子类别添加一个新的多选与子子类别。使用JOIN NULL值在数据库中匹配列名称

我有这个主要工作,但我在数据库方面遇到麻烦。我有一个名为categories的主表,其中包含CatIDCategory两列。 categories表中有三排“摩托车”,“动力运动”和“零件&配件”

当用户选择摩托车时,应该创建一个新的多重选择并提出摩托车品牌。另一方面,如果用户选择Powersports,则应创建新的多下拉列表并列出Powersport车辆类型“Dirtbike”,“PWC”,“Snowmobile”等。选择其中之一将带来Powersports-> Vehicle Type- >品牌多选。

问题是我不知道如何在数据库中正确引用所有这些信息。

例如: 主要分类(类)

+-------+---------------------+ 
| CatID | Category   | 
+-------+---------------------+ 
|  1 | Motorcycles   | 
|  3 | Parts & Accessories | 
|  2 | Powersports   | 
+-------+---------------------+ 

摩托车子类别:(motorcycle_brands)

+-------+-------+-------------------------+ 
| CatID | SubID | SubName     | 
+-------+-------+-------------------------+ 
|  1 |  1 | American Classic Motors | 
|  1 |  2 | American Ironhorse  | 
|  1 |  3 | Aprilia     | 
|  1 |  4 | Benelli     | 
|  1 |  5 | Big Dog     | 
+-------+-------+-------------------------+ 

电源体育子类别:(powersport_categories)

+-------+-------+--------------------------------+----+ 
| CatID | SubID | SubName      | ID | 
+-------+-------+--------------------------------+----+ 
|  2 |  1 | ATVs       | 1 | 
|  2 |  2 | Dune Buggies/Sand Rails  | 2 | 
|  2 |  3 | Go Karts: High-Performance  | 3 | 
|  2 |  4 | Personal Watercraft   | 4 | 
|  2 |  5 | Powersport Vehicles Under 50cc | 5 | 
+-------+-------+--------------------------------+----+ 

所以如果我运行以下命令:

SELECT * FROM categories C 
LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID 
LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID 
WHERE C.CatID = 1 LIMIT 5; 

我得到这个:

+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+ 
| CatID | Category | CatDBTable  | CatID | SubID | SubName     | CatID | SubID | SubName | ID | 
+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+ 
|  1 | Motorcycles | motorcycle_brands |  1 |  1 | American Classic Motors | NULL | NULL | NULL | NULL | 
|  1 | Motorcycles | motorcycle_brands |  1 |  2 | American Ironhorse  | NULL | NULL | NULL | NULL | 
|  1 | Motorcycles | motorcycle_brands |  1 |  3 | Aprilia     | NULL | NULL | NULL | NULL | 
|  1 | Motorcycles | motorcycle_brands |  1 |  4 | Benelli     | NULL | NULL | NULL | NULL | 
|  1 | Motorcycles | motorcycle_brands |  1 |  5 | Big Dog     | NULL | NULL | NULL | NULL | 
+-------+-------------+-------------------+-------+-------+-------------------------+-------+-------+---------+------+ 

通知所有的NULL值在末尾。有没有办法摆脱这些空值?它在我的代码中导致其他问题,因为当它将这个数组返回到我的PHP脚本时,SubIDSubName数组字段为空,因为它与最后一组为NULL。但是,如果我运行与上述相同的查询替换1与2然后我得到我想要的值,因为他们没有被重复的列名称重写。

也许我正在讨论这一切错误我打算在所有表格中为子类别设置相同的SubIDSubName列,但看起来它可能会导致我的悲伤。我这样做的原因是因为否则我不得不根据选择的值来编写一个单独的查询,我希望基本上有一个查询将基本上为每个子选项执行。这里有什么改进吗?

+0

,而不是''试试你想要的具体列名的select查询 – krishna

回答

1

1)尝试这样的事情(你也应该看看下面我的其他点):

SELECT C.CatID, C.Category, C.CatDBTable, MB.SubID AS MbSubID, MB.SubName AS MbSubName, PC.SubID AS PcSubID, PC.SubName AS PcSubName, PC.ID AS PcID FROM categories C 
LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID 
LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID 
WHERE C.CatID = 1 LIMIT 5; 

2)你的数据库结构可能会变得更好和更具扩展性(如果你需要为例添加一个第四度子),如果您使用以下方法:

只有一个表名的类别,其具有以下栏目:

  • ID
  • PARENT_ID(可为空的)
  • 深度
  • 名称

如下将使用它:

  • “摩托车”,这是一个主类别将有:(ID => 1, parent_id => null,depth => 0,name =>摩托车)
  • “美国经典汽车”是“摩托车”的子版本将有:(ID => 4,parent_id => 1,depth => 1, name => American Classic Motors)
  • “全地形车”,这是 “美国经典汽车” 的子将有:(ID => 5,PARENT_ID => 4,深度=> 2,名称=>耐震)
+0

我曾想过类似于你的第二个答案的结构,但我想这可能是难以维持。我认为只需为每个类别分别提供不同的表格,subCat,subSubCat等等。 – Yamaha32088

1

试试:

SELECT C.CatID,C.Category,MB.CatID as MBCatID,MB.SubID as MBSubID,MB.SubName as MBSubName,IFNULL(PC.CatID,'') as PCCatID,IFNULL(PC.SubID,'') as PcSubID,IFNULL(PC.SubName,'') as PcSubName,IFNULL(PC.ID,'') as PCID FROM categories C 
    LEFT JOIN motorcycle_brands MB ON MB.CatID = C.CatID 
    LEFT JOIN powersport_categories PC ON PC.CatID = C.CatID 
    WHERE C.CatID = 1 LIMIT 5; 

中看到结果SQL Fiddle