转载: http://blog.csdn.net/guoxilen/article/details/24332517
一、说明
当在一张表的某个字段中存储了另外一张表的多个ID时常用查询
二、准备
假设有一博客,每一个主题允许有多个类别。数据库设计时建了类别和主题两张表,主题对类别的关联设置在主题表中。
- -- 类别表DDL
- CREATE TABLE `T_CATEGORYS` (
- `C_ID` int(11) NOT NULL,
- `C_NAME` varchar(255) NOT NULL,
- PRIMARY KEY (`C_ID`)
- )
- -- 主题表DDL
- CREATE TABLE `T_TOPIC` (
- `T_ID` int(11) NOT NULL,
- `T_NAME` varchar(255) NOT NULL,
- `T_CATEGORYS` varchar(128) NOT NULL,
- PRIMARY KEY (`T_ID`)
- )
- -- 准备类别数据
- INSERT INTO `T_CATEGORY` (`C_ID`, `C_NAME`) VALUES ('1', 'Struts');
- INSERT INTO `T_CATEGORY` (`C_ID`, `C_NAME`) VALUES ('2', 'Spring');
- INSERT INTO `T_CATEGORY` (`C_ID`, `C_NAME`) VALUES ('3', 'iBatis');
- INSERT INTO `T_CATEGORY` (`C_ID`, `C_NAME`) VALUES ('4', 'Hibernate');
- -- 准备主题数据
- INSERT INTO `xilen_dev`.`T_TOPIC` (`T_ID`, `T_NAME`, `T_CATEGORYS`) VALUES ('1', 'SSI整合示例', '1,2,3');
- INSERT INTO `xilen_dev`.`T_TOPIC` (`T_ID`, `T_NAME`, `T_CATEGORYS`) VALUES ('2', 'SSH整合示例', '1,2,4');
三、查询
1、查询多ID的字段中包含某个ID的记录
SQL:
- -- 查询类别包含了iBatis(id=3)的主题记录
- SELECT * FROM T_TOPIC WHERE FIND_IN_SET(3, T_CATEGORYS)
2、查询多ID字段中这些ID所代表的记录
SQL:
- -- 查询主题 SSH整合示例(id=2) 包含的类别记录
- SELECT * FROM T_CATEGORY c WHERE (SELECT FIND_IN_SET(c.C_ID,t.T_CATEGORYS) from T_TOPIC t where t.T_ID=2)
3、查询时将多ID的字段的ID转换为对应的标识
SQL:
- -- 查询主题表时将类别的ID转换为类别的NAME
- SELECT t.T_ID AS topicId,
- (SELECT GROUP_CONCAT(c.C_NAME) FROM T_CATEGORY c WHERE FIND_IN_SET(c.C_ID,t.T_CATEGORYS)) AS categoryName
- FROM T_TOPIC t
4、补充
FIND_IN_SET函数默认是以符号 , 作为分割符的,如果多ID字段使用的这个默认的分隔符,而是以如 | 的符号作为分隔符,那么:
- -- 非 , 作为分隔符时,先REPLACE函数替换它
- SELECT * FROM T_TOPIC WHERE FIND_IN_SET(3, REPLACE(T_CATEGORYS,'|',','))