不同的表字段标签

时间:2011-05-19 13:23:08

标签: php mysql

我有一个带有字段(cat_tags)的表,其中包含以下行: -

    id - cat_tags - date_added
    1 -   yam, potato, onion, pepper,beans - 23-12-2011
    row1 - yam, potato, onion, pepper  23-12-2011
    row2 - onion, pepper, beans - 23-12-2011
    row3 - pepper, beans, rice - 23-12-2011
    row4 - rice, potato, pepper, yam -  23-12-2011
    row5 - beans, rice, onion, food -  23-12-2011
    .....
    .....
    .....

请问如何获得DISTINCT项目列表以及它们在整个表格字段中出现的次数(频率)?

EG。胡椒x 4
     洋葱x 3
     山药x 2

提前谢谢

3 个答案:

答案 0 :(得分:3)

首先规范您的表格。

Table tags
    id unsigned integer autoincrement primary key,
    tag varchar(40) not null,
    unique index tag(tag)

Table Item_tags
    id unsigned integer autoincrement primary key,
    tag_id integer not null,
    item_id integer not null

Table items
    id unsigned integer autoincrement primary key,
    date_added date not null

使用以下一系列查询将项目插入数据库:

INSERT INTO Items VALUES (null, NOW());
SELECT @last_item_id:= LAST_INSERT_ID();

REPLACE IGNORE INTO tags (tag) VALUES ('pepper', 'onion', 'rice')

INSERT INTO Item_tags 
  SELECT 
    null as id
    , tags.id 
    , last_item_id
  FROM tags WHERE tags.tag IN ('pepper', 'onion', 'rice')

如果您想简化项目的添加并简化您的PHP代码,
在该桌子上使用黑洞桌和触发器。

CREATE TABLE bh_items (
  id unsigned integer autoincrement primary key,
  date_added timestamp,
  tag1 varchar(45) not null, 
  tag2 varchar(45) default null,
  tag3 varchar(45) default null,
  tag4 varchar(45) default null,
  tag5 varchar(45) default null,
  tag6 varchar(45) default null,
  tag7 varchar(45) default null,
  tag8 varchar(45) default null,
  tag9 varchar(45) default null,
  tag10 varchar(45) default null) ENGINE = blackhole;

DELIMITER $$

CREATE TRIGGER ai_bn_items_each AFTER INSERT ON bh_items FOR EACH ROW
BEGIN
  DECLARE last_item_id integer;

  INSERT INTO Items VALUES (null, new.date_added);
  SELECT LAST_INSERT_ID() INTO last_item_id;

  REPLACE IGNORE INTO tags ((null, new.tag1)
                           ,(null, new.tag2)
                           ,(null, new.tag3)
                           ,(null, new.tag4)
                           ,(null, new.tag5)
                           ,(null, new.tag6)
                           ,(null, new.tag7)
                           ,(null, new.tag8)
                           ,(null, new.tag9)
                           ,(null, new.tag10));

    INSERT IGNORE INTO item_tags (item_id, tag_id)
      SELECT last_item_id, tags.tag FROM tags 
      WHERE tags.tag 
        IN (new.tag1, new.tag2, new.tag3, new.tag4, new,tag5
          , new.tag6, new.tag7, new.tag8, new.tag9, new.tag10);
END $$

DELIMITER ;

如果您使用触发器,您只需插入黑洞表,触发器就会更新所有3个表。

INSERT INTO bh_items VALUES (null, null, 'onion', 'rice', 'pepper'
                             , null, null, null, null, null, null, null)

所有表格都会自动更新。

回到你的问题

然后,您可以使用此查询从中进行选择:

SELECT tags.tag, COUNT(*) as freq FROM item_tags 
INNER JOIN tags ON (item_tags.tag_id = tags.id)
GROUP BY item_tags.tag_id

<强>链接:
黑洞:http://dev.mysql.com/doc/refman/5.1/en/blackhole-storage-engine.html
替换为:http://dev.mysql.com/doc/refman/5.1/en/replace.html
触发器:http://dev.mysql.com/doc/refman/5.1/en/triggers.html
创建表格:http://dev.mysql.com/doc/refman/5.1/en/create-table.html

答案 1 :(得分:1)

您应首先normalize您的桌面结构。 它不符合第一个普通形式,使得请求的操作方式比它需要的更复杂。

答案 2 :(得分:1)

如果我已正确理解你的问题,这应该有效:

    $result = mysql_query("SELECT cat_tags FROM table");

    while($row = mysql_fetch_array($result))
    {
        //Split the row into an array based on the comma
        $detail_array = explode(",", $row['cat_tags']);

        //Go through that array and index a master count for each occurence of the same value 
        //Trim due to the spaces after the comma in your field
        foreach($detail_array as $key=>$val)
        {
            $output_array[trim($val)] = $output_array[trim($val)] + 1;  
        }   
    }

    print_r($output_array);