首先我們有兩張表
第一個是食物所需要的材料
第二張是一個食物的名字和圖片
首先如果我們要查詢一個菜的名字圖片和所需要的材料,我們第一步是通過第一張表的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
結果如圖
大功告成