Best unofficial Apache Server developers community
Username
Forgot password?
Sign in with Twitter account
Sign in with Facebook account

Distinct Table field tags

0

47 views

I have a table with a field (cat_tags) which contain the following rows:-

    row1 - yam, potato, onion, pepper
    row2 - onion, pepper, beans
    row3 - pepper, beans, rice
    row4 - rice, potato, pepper, yam
    row5 - beans, rice, onion, food
    .....
    .....
    .....

pls how can I get a DISTINCT list of items and the number of times(frequency) they occurred in the entire table field?

Eg. pepper x 4 onion x 3 yam x 2

thank you in advance

asked May 19, 2011 8:23 am CDT
posted via StackOverflow

3 Answers

3
 

First normalize your table(s).

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 an item into your database using the following series of queries:

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')

If you want to simplify the addition of items and streamline your php code,
use a blackhole table and a trigger on that table.

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 ;

If you use the trigger you can just insert into the blackhole table and the trigger will then update all your 3 tables.

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

All your tables will be automagically updated.

Back to your question

You can then select from this using this query:

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

Links:
blackhole: http://dev.mysql.com/doc/refman/5.1/en/blackhole-storage-engine.html
replace into: http://dev.mysql.com/doc/refman/5.1/en/replace.html
Triggers: http://dev.mysql.com/doc/refman/5.1/en/triggers.html
Create table: http://dev.mysql.com/doc/refman/5.1/en/create-table.html

answered May 23, 2011 12:29 pm CDT
1
Best answer
 

If I have understood your question correctly, this should work:

    $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);

answered May 23, 2011 12:29 pm CDT
2
 

You should first normalize your table structure. It is not compliant with the first normal form, making the requested operation way more complicated than it needs to be.

answered May 23, 2011 12:29 pm CDT

Your answer

Join with account you already have


Sign in with Twitter account
Sign in with Facebook account
Sign in with Google Friend Connect

Preview
Similar questions