search

Home  >  Q&A  >  body text

MYSQL精确搜索和PHP数组操作的问题

mysql中的TAG字段包含如下情况

php
php,mysql
jquery
html
php
ruby
java,jquery,js
java
html
css

我希望能通过mysql一次搜索出所有不重复的tag,就像这样的结果

php
mysql
jquery
html
ruby
java
css

如果一次搜索不出来的话通过尽可能简单的PHP数组操作一下也行,请高手指点

大家讲道理大家讲道理2902 days ago568

reply all(5)I'll reply

  • PHP中文网

    PHP中文网2017-04-10 13:13:08

    额,一个SQL操作成功貌似对我难度有点大,我的想法是:

    • 先老老实实的读取
    code:
        SELECT * FROM tag
    
    result example:
        $result = array('php','php,mysql','jquery','html','php','ruby','java,jquery,js','java','html','css');
    • 利用implode函数连接数组变成字符串(连接用的字串为,)
    code:
        $result = implode(',',$result);
    
    result example:
        $result = 'php,php,mysql,jquery,html,php,ruby,java,jquery,js,java,html,css';
    • 利用explode函数剪断字符串重新变成数组(剪断用的字串为,
    code:
        $result = explode(',',$result);
    
    result example:
        $result = Array ( [0] => php [1] => php [2] => mysql [3] => jquery [4] => html [5] => php [6] => ruby [7] => java [8] => jquery [9] => js [10] => java [11] => html [12] => css );
    • 最后利用array_unique 函数去除重复值即可
    code:
        $result = array_unique($result);
    
    result example:
        $result = Array ( [0] => php [2] => mysql [3] => jquery [4] => html [6] => ruby [7] => java [9] => js [12] => css )

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 13:13:08

    我的理解是你的表中个别记录存在用“,”分隔的tag,但是你在查询SQL时希望将“,”分隔的tag像独立记录那样查询,并去重。
    我说下我在SQL里处理这个事情的思路,当然如果数据量大的话性能肯定很差,因为涉及到太多的字符串操作,而本身mysql不支持split。如果使用一条SQL把它查出来,首先需要总结你的数据的规律,比如你的记录中含有“,”分隔的tag数最多有多少个,我下面的代码假设根据你的数据:

    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

    可以得到结果:

    tag
    php
    jquery
    html
    ruby
    java
    css
    mysql
    js

    方法很笨,分别通过四次查询得到结果后合并去重,分别是

    1. 查询无逗号分隔的记录中的所有tag并去重(去重的目的是减少合并时的数据量);
    2. 查询有逗号分隔的记录中的第一个tag,然后去重;
    3. 查询有逗号分隔的记录中的第二个tag,然后去重;
    4. 查询有逗号分隔的记录中的第三个tag,然后去重;
    5. 合并以上所有记录后再次去重,得到结果;

    一个复合SQL就得到了结果,当然这个SQL的扩展性很差,性能也不好,如果你的数据格式做了变化,甚至单条记录中的逗号数更多的时候,这条SQL就game over了。建议通过sp来动态实现,这样可以更好的适应单条记录中tag规模的增长,否则像我上面那样,逗号一多就崩溃了。如果是在php或java里做这个事情,我相信方便的多。

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 13:13:08

    为什么不用 group by

    reply
    0
  • 迷茫

    迷茫2017-04-10 13:13:08

    用POSTGRESQL可以这么实现:

    select distinct(unnest(string_to_array(tag,','))) from test;

    MYSQL没有实验环境,原理差不多。主要是将字符串以逗号进行分割成数组,再将该数组进行转换成行,最后distinct

    reply
    0
  • 黄舟

    黄舟2017-04-10 13:13:08

    $result=$db->get_var("select GROUP_CONCAT(tag) from tags");
    $result = array_unique(explode(',',$result));

    reply
    0
  • Cancelreply