How to search in serialized content - php

I have two tables
Table 1 is:
id | item_id
---------------
1 | a:2:{i:0;s:1:"1";i:1;s:1:"2";}
and the second table is:
tag_id | tag
------------
1 | c
2 | java
I have stored the id of table two in table 1 after serialize. Now I want to search the tag in table 1 by mysql %like% but the problem is that if I want to search the tag have id 1 or 2 in the item_id it will always find the result even if there is not 1 stored by me but this is stored by the serialize function. Now I want to know what should I do? And any better approach/method will also be appreciated!

Serialized data is not suitable for searching.
It's better to improve your table structure:
Table tags is the same as yours.
Table items_tags with stucture:
id - autoincrement field
item_id - ID of item with tag
tag_id - tag ID
With following structure it's much more easier to search items with tags.
Added
Mayankswami, example queries: For all items with specified tag: SELECT item_id FROM items_tags WHERE tag_id=(TAG_ID) For item's tags: SELECT * FROM item_tags AS IT LEFT JOIN tags AS T ON T.id=IT.tag_id WHERE item_id=(ITEM_ID)

Related

Get all row had value in column

How do I get all rows having the value 1, but not 11 in column news_short?
Here's my table:
id | news_short |
1 | 1,2,3,4,5,6,7 |
2 | 2,4,5,6,1,5,6 |
3 | 11,2,5,6,9,4 |
I agree you should normalize. But here is the solution the way it sits.
Select * from table where news_short like '%1,%' and
news_short not like '%11,%';
FIND_IN_SET() returns the position of a string if it is present (as a substring) within a list of strings
so you should search if a value is != 11
eg:
->where("FIND_IN_SET(news_short) !=", 11)
Your best bet would be normalize your schema do not store relations in form of comma separated list instead create a junction table to maintain a m:m many to many or if its one to many relation between main table and these news_short (probably from other table) values,create a new table as news_short with columns main table id and news(table) id and in each row save one association per your_table and news.
If you aren't able to update/change your schema you could use find_in_set() but its not a good option
select *
from your_table
where find_in_set(1, news_short) > 0
demo

Search for records with similar tag id

I have a tagging table that looks like this:
id | product_id | tag_id
---------------------------
1 | 1 | 10
2 | 1 | 12
3 | 2 | 10
4 | 3 | 11
I'm creating a search page which take tags as input by user (1 or more) and search the database for records with those tags present.
For example:
if user entered '10' then with the table above the result would be product_id 1 & 2.
EDIT:
There are 2 user input
Include tag -> search for product with these tags
Exclude tag -> search for products without these tags
So the search query would have to first ignore the exclude tags then search for product with 'include tag'.
EDIT 2:
The user can enter 1 or more tag.
Any idea how to do this?
Run this SQL query :
$includedTags = join(',',$incTagsIdArr);
$excludedTags = join(',',$excTagsIdArr);
$sql = "SELECT product_id FROM $tagTable WHERE tag_id IN ($includedTags) AND tag_id NOT IN ($excludedTags)"
where :
$incTagsIdArr is the array of request tag ids by the user
$excTagsIdArr is the array of excluded tag ids by the user
$tagTable is your "tagging" table name
Here is a fairly simple approach using aggregation and having:
select tt.product_id
from tagtable tt
group by tt.product_id
having sum(tt.tag_id in ($excludedtags)) = 0 and
sum(tt.tag_id in ($includedtags)) = #NumberIncludedtags;
You need to put in the number of included tags for the second condition. Also, this assumes that the tags table does not have duplicated rows (if so, this is easily fixed by using count(distinct), but that clutters the query).

change a table`s status to updated on inserting new values to another table in mysql

I've got two tables which are related to each other. I want to change table 1 status to updated when I insert new values into table 2 and return mysqli_affected_rows() for table 1
table 1: products
id | name
1 | product
table 1: categories
id | name | product_id
1 | cat 1 | 1
2 | cat 2 | 1
is this possible?!
You show the structure of the tables, but don't include any column that should be updated. This makes me think that you don't really want an update. You just want a query that returns whether a given product is in the categories table.
If so, the following may do what you want:
select p.*,
coalesce( (select 1 from categories c where c.productid = p.id limit 1), 0) as InCategories
from products p;
If you try to go another route where you actually store the value in the table, you will need to use a stored procedure or triggers. Do consider, though, what happens when you delete or update a row. insert is not the only way to modify data in a table.

How to match CSV value in column

my mysql table name products.
How can get data this table.
table shema
id| catid |subcatid
-----------------
1 | 5 | 2,3,5
SELECT * FROM products where subcatid=2
not correct
how can write correct sql.
SELECT * FROM products where find_in_set(2,subcatid)
consider to normalize your table

Most used tags - mysql

I am working on a blog. Now I want to display the most used tags of an author. The tags are stored in the articles table, in a column called tags, komma seperated:
Article table (id | authorid | tags):
1 | 1 | soccer, sport
2 | 1 | sport, tennis, injury
3 | 1 | sport, golf, injury
So I want to display author with id 1 and display his 3 most used tags (from the article table as displayed above). In this case that would be: sport, injury, soccer.
Is this possible in MySql?
Yes its possible, but the better answer would be to direct you into a more "Normal" database structure.
You really need a db set up like:
Table of articles, table of tags, table of article_tags containing the IDs of the tag and the article it's assigned to.
You can then query the tags by each article ('X') by looking in article_tags and returning all tag_id's where article_id = ('X').
You should take a look at database normalization -- the wikipedia article is very advanced however it will give you terminology which you can search for to find more articles on the topic.
The basic idea is you'll have another table:
table name: tags
columns: id | name
And then a table to join them:
table name: article_tags
columns: article_id | tag_id
Then you'll join all of the data together in a query in order to display the tag names for each article. It will then be possible to do more advanced queries on the tables to figure out things such as most used tag by article, and most used tag by author.

Categories