資料庫表簡介:物品表 `id` int(11) '物品id,唯一標識', `name` varchar(255) '物品名稱', `level` int(11) '物品類別等級,禮品包為最高級1,類別為2級,詳細物品為3級', `parentId` int(11) '只有3級詳細物品有上級id', ...
資料庫表簡介:物品表
`id` int(11) '物品id,唯一標識',
`name` varchar(255) '物品名稱',
`level` int(11) '物品類別等級,禮品包為最高級1,類別為2級,詳細物品為3級',
`parentId` int(11) '只有3級詳細物品有上級id',
`childIds` varchar(255) '只有1級禮品包級有包含所有3級物品id的字元串,id之間用","隔開',
問題描述:利用sql語句簡化代碼,讓Java代碼可以直接通過jdbc查詢獲取下述集合
1、根據輸入的1級的id查詢其包含的所有3級物品信息
2、根據輸入的1級的id查詢其包含的所有3級物品對應的2級物品類別信息
>>>>>>>>>>>>>>>>>>>>>>>>solution>>>>>>>>>>>>>>>>>>>>>>>>>>>
問題1:因為in(childIds)使用針對字元串不能遍歷childIds中所有id,又要避免在Java代碼中先獲取childIds,再split(",")之後迴圈獲取對應good對象。巧妙利用childIds欄位中id用","隔開的特性,所有使用FIND_IN_SET(id,str)函數。
select g.* from good g where FIND_IN_SET(g.id,(select childIds from good where id =1)); #假設輸入1級id為1
查詢結果:返回1級下所有3級物品集合
>>>>>>>>>>>>>>>>>>>>>>>>solution>>>>>>>>>>>>>>>>>>>>>>>>>>>
問題2:首先利用問題一種所查信息獲取所有的parentId
select distinct g.parentId from good g where FIND_IN_SET(g.id,(select childIds from good where id =1))
既然parentId都已經查出來了,按以往辦法先獲取所有parentId集合,再遍歷查詢出所有該1級childIds中的3級物品對應的2級物品類別信息。解決辦法使用GROUP_CONCAT(id)將所查parentId拼接成"3,4,5"這樣的字元串。
先看看GROUP_CONCAT的用法:
select GROUP_CONCAT(L2ids.parentId) from
(select distinct g.parentId from good g where FIND_IN_SET(g.id,(select childIds from good where id =1))) L2ids
再使用問題1中的解決辦法查詢所有2級物品信息:
select g.* from good g where FIND_IN_SET(g.id,
(select GROUP_CONCAT(L2ids.parentId) from
(select distinct g.parentId from good g where FIND_IN_SET(g.id,(select childIds from good where id =1))) L2ids))
總結:在一般的表格帶參數查詢的函數中,可以先想想如何利用sql查詢出所預期的結果,避免大規模的使用Java代碼進行迴圈遍歷。嗯,真香~