php
php,mysql
jquery
html
php
ruby
java,jquery,js
java
html
css
中最多一条记录含有三个tag,含有两个逗号。先用代码创建你所说的场景数据:
/*!40101 SET NAMES utf8 */;
create table `tags` (
`tag` varchar (150)
);
insert into `tags` (`tag`) values('php');
insert into `tags` (`tag`) values('php,mysql');
insert into `tags` (`tag`) values('jquery');
insert into `tags` (`tag`) values('html');
insert into `tags` (`tag`) values('php');
insert into `tags` (`tag`) values('ruby');
insert into `tags` (`tag`) values('java,jquery,js');
insert into `tags` (`tag`) values('java');
insert into `tags` (`tag`) values('html');
insert into `tags` (`tag`) values('css');
然后执行如下SQL查询:
SELECT DISTINCT tag FROM (
SELECT DISTINCT tag FROM tags WHERE tag NOT LIKE '%,%'
UNION
SELECT DISTINCT SUBSTRING_INDEX(tag , ',', 1) AS tag FROM tags WHERE tag LIKE '%,%'
UNION
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING(tag ,INSTR(tag ,',')+1),',', 1) AS tag FROM tags WHERE SUBSTRING(tag ,INSTR(tag ,',')+1) LIKE '%,%'
UNION
SELECT DISTINCT SUBSTRING_INDEX(tag , ',', -1) AS tag FROM tags WHERE tag LIKE '%,%'
) t
额,一个SQL操作成功貌似对我难度有点大,我的想法是:
我的理解是你的表中个别记录存在用“,”分隔的tag,但是你在查询SQL时希望将“,”分隔的tag像独立记录那样查询,并去重。
我说下我在SQL里处理这个事情的思路,当然如果数据量大的话性能肯定很差,因为涉及到太多的字符串操作,而本身mysql不支持split。如果使用一条SQL把它查出来,首先需要总结你的数据的规律,比如你的记录中含有“,”分隔的tag数最多有多少个,我下面的代码假设根据你的数据:
中最多一条记录含有三个tag,含有两个逗号。先用代码创建你所说的场景数据:
然后执行如下SQL查询:
可以得到结果:
方法很笨,分别通过四次查询得到结果后合并去重,分别是
一个复合SQL就得到了结果,当然这个SQL的扩展性很差,性能也不好,如果你的数据格式做了变化,甚至单条记录中的逗号数更多的时候,这条SQL就game over了。建议通过sp来动态实现,这样可以更好的适应单条记录中tag规模的增长,否则像我上面那样,逗号一多就崩溃了。如果是在php或java里做这个事情,我相信方便的多。
为什么不用 group by
用POSTGRESQL可以这么实现:
MYSQL没有实验环境,原理差不多。主要是将字符串以逗号进行分割成数组,再将该数组进行转换成行,最后distinct