首先我们有两张表
第一个是食物所需要的材料
第二张是一个食物的名字和图片
首先如果我们要查询一个菜的名字图片和所需要的材料,我们第一步是通过第一张表的FoodId去左连接查询上面的Materia表,相同FoodId所对应的食物所需要的的所有食材,
SELECT Food.FoodId, FoodName, ImgUrl, FoodMaterial.MaterialName, FoodMaterial.MaterialVolume FROM Food LEFT JOIN FoodMaterial ON ( FoodMaterial.FoodId= Food.FoodId ) WHERE Food.FoodId= 21
结果是这样显示的
我们会发现一个食材的材料他就要单独的占一条数据,这样的话我们在前台循环使用的时候会有很大的麻烦,所有我们想能不能把相同的食物的食材查询出来后,把他们放在一行里面用逗号隔开。
所有接下来我们尝试把第一张表也就是食材那张表里面一个食物里面的所有食材放在一行,然后这时候就要引出我们今天的主角Stuff函数,
首先我们来看看这个函数
STUFF函数: stuff(param1, startIndex, length, param2) 一、作用
他是将param1中自startIndex起(从1开始),删除length个字符,然后用param2替换删掉的字符。 二、参数 param1 一个字符数据表达式。param1可以是常量、变量,也可以是字符列或二进制数据列。 startIndex 一个整数值,指定删除和插入的开始位置。如果 startIndex或 length 为负,则返回空字符串。如果startIndex比param1长,则返回空字符串。startIndex可以是 bigint 类型。 length 一个整数,指定要删除的字符数。如果 length 比param1长,则最多删除到param1 中的最后一个字符。length 可以是 bigint 类型。 三、返回类型 如果param1是受支持的字符数据类型,则返回字符数据。如果param1是一个受支持的 binary 数据类型,则返回二进制数据。
大概的了解了下这个函数,那么怎么应用到我们这个例子里面呢
首先我们解决刚才说的那个问题
SELECT FoodId,MaterialName=STUFF( (SELECT',' +MaterialName FROM FoodMaterial WHERE FoodId=A.FoodId FOR XML path('')),1,1,'' ) FROM FoodMaterial A GROUP BY FoodId
看看效果
然后我们将查询出来的结果和Food那张表进行连接查询,差FoodId=21的那个菜所需要的原材料
SELECT Food.FoodName, B.FoodId, B.MaterialName, Food.ImgUrl FROM Food LEFT JOIN ( SELECT FoodId, MaterialName = STUFF( ( SELECT ',' + MaterialName FROM FoodMaterial WHERE FoodId = A.FoodId FOR XML path ( '' ) ), 1, 1, '' ) FROM FoodMaterial A GROUP BY FoodId ) AS B ON ( Food.FoodId= B.foodId ) WHERE B.foodId= 21
结果如图
大功告成