Search in MySQL - Separated Columns - php

I am trying to create a small script in PHP to get data from a MySQL Database.
In my database 'companies' is a column called category where i store my the companies' categories in. For example "1|2" or just "2".
Now i want to search for "2" and my database shall return those two entries with the "1|2" and "2" - but that is my problem.
I tried it with LIKE % etc. but nothing worked as i hoped.
Does anyone may help me out with my small PHP script?

I believe it's a bad idea to store categories in the way you do.
If you use LIKE "%2" or LIKE "%2%" or LIKE "2" statements to get compnaies wich belong to category "2", you will receive companies with categories e.g. 21|12.
It'd be better to take categories away from company table. And add 2 new tables: category(id, name) and company_category(id, compnay_id, category_id). This is how it has to be in RDMS.
But if you have weighty arguments why you do so - it is you deal.
In this I'd suggest wrapping categories in additional |-symbol to get |1|2| or |1|3|23| and using LIKE "%|2|%" statement.
I hope this helps you.

SELECT * FROM cat_baza WHERE subsection = ".$row['id']." or subsection LIKE('%|".$row['id']."|%') or subsection LIKE('".$row['id']."|%') or subsection LIKE('%|".$row['id']."');

Try
SELECT * FROM table
WHERE category LIKE %2% AND NOT LIKE '%|%'

Try this
SELECT * FROM table
WHERE category='2' OR category LIKE '%|2' OR category LIKE '2|%'

SELECT * FROM table
WHERE category REGEXP '.*2.*'
Regex should work

Related

Create A List From a Category Section in mysql

I was wondering if mysql has a way to look at a column and only retrieve the results when it finds a unique column once. For example
if the table looks like this:
id name category
1 test Health
2 carl Health
3 bob Oscar
4 joe Technology
As you can see their are two rows that could have the same category. Is their a way to retrieve the result where the array will one only return the category once?
What I am trying to do is get all the categories in the database so I can loop through them later in the code and use them. For example if I wanted to created a menu, I would want the menu to list all the categories in the menu.
I know I can run
SELECT categories FROM dbname
but this returns duplicate rows where I only need the cateogry to return once. Is there a way to do this on the mysql side?
I assume I can just use php's array_unique();
but I feel like this adds more overhead, is this not something MYSQL can do on the backend?
group by worked perfectly #Fred-ii- please submit this as answer so I can get that approved for you. – DEVPROCB
As requested by the OP:
You can use GROUP BY col_of_choice in order to avoid duplicates be shown in the queried results.
Reference:
https://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html
By using database normalization, you would create another table with an unique id and the category name and by that link those two together, like
select * from mytable1
on mytable1.cat = mytable2.id
group by mytable1.cat
You can ofcourse also use group by without multiple tables, but for the structure, I recommend doing it.
You can use select distinct:
SELECT DISTINCT categories
FROM dbname ;
For various reasons, it is a good idea to have a separate reference table with one row per category. This helps in many ways:
Ensures that the category names are consistent ("Technology" versus "tech" for instance).
Gives a nice list of categories that are available.
Ensures that a category sticks around, even if no names currently reference it.
Allows for additional information about categories, such as the first time it appears, or a longer description.
This is recommended. However, if you still want to leave the category in place as it is, I would recommend an index on dbname(categories). The query should take advantage of the index.
SELECT id, name from dbname GROUP BY categoryname
Hope this will help.
You can even use distinct category.

How to make a MYSQL query to include rows once of a column based on another?

Seems to be a simple question for someone who knows well SQL, but not for me.
Anyhow, here is a sample table:
Primary (and only) key is on id. So basically the scenario is as fallows. User may add images. Newly added images are inserted with comune_number value 0 avoiding duplicates (on file name = image via PHP). Images inserted can be assigned to a category from another table. The same image can be assigned to many categories, for each is inserted a new row with the category id (comune_number). Relation between the two tables is on comune_number.
I would like to show the images, with a checkbox checked for which is assigned already.
My question is simple. How to include all images once, but where the same image is already assigned, include that comune_number instead of 0. I don't care about the order. The result I would like to achieve is something like this:
I'm aware of GROUP BY, so if I try
mysql_query("SELECT * FROM banner WHERE `comune_number` = 0");
or
mysql_query("SELECT * FROM banner GROUP BY `image`");
I end up with the same (not wanted) result.
Most likely I have to combine two queries in one, but I can't figure out which and how.
Note1: I have tried many combinations in phpMyAdmin, based on my (little) knowledge and on what I found with Google (including Stackoverflow), but none of them resulted as shown.
Note2: MySQL version 5.1
Either MYSQL only or combined with PHP solutions are welcome.
EDIT
I need to keep the comune_number. So when I show the images, I need to know the id.
My queries must rely on comune_number, so when I need comune_number = 10, the result should be as on second image above.
EDIT2
It seems I wasn't made myself clear. So what I want, when user is watching category of id 10, show him all the images once, and mark the ones which were assigned to that category.
Another example is here. So if user is watching category (comune_number) of id=9, show every picture once, and mark the two assigned to it.
Based on your SQLFiddle and all the comments here is the updated query:
SELECT r.*
FROM (SELECT b.*
FROM banner b
WHERE b.comune_number = 9
UNION ALL
SELECT b2.*
FROM banner b2
WHERE b2.comune_number = 0
GROUP BY b2.image) r
GROUP BY r.image;
Live DEMO.
select * from
(SELECT * FROM banner order by
FIELD(comune_number,10,0))
abc group by `image`;
fiddle
Updated:
Query with filter condition:
select * from
(SELECT * FROM banner
where comune_number in (10,0) order by
FIELD(comune_number,10,0))
abc group by `image`;
an important tip. When you use GROUP BY all the field you put in your field list, must be in GRUOP BY clause or must be into an aggragate function. MySql has a strange behaviour, don't sign the error but if you try in another DBMS your query:
SELECT * FROM banner GROUP BY image
You have an error.
MySql applies for fields not present in group by an implicit limit 1.
Solution about your issue:
SELECT * FROM banner b1
WHERE b1.comune_number <= 'YOUR_CATEGORY'
AND NOT EXISTS
(SELECT 'X' FROM banner b2
where b2.image = b1.image
and b2.comune_number > b1.comune_number
AND b2.comune_number <= 'YOUR_CATEGORY')
EDIT
I've changed query, now I put a condition about input category. Where you find YOUR_CATEGORY put the value of category you see (i.e. 9).
I am not sure whether this is the exactly you need, but I think it can be helpful.Try this:
Select if(comune_number = 10, comune_number,0), id, image from table
You may change comune_number as per your convenience. Further nesting in IF condition is also possible.

PHP MYSQL - Search comma separated list with a comma separated list

Dear Stackoverflowers,
I have a mysql query which checks if some sub categories are part of a categoryID to show all products from subcategories in the main category.
For example:
Category
Subcategory 1
Subcategory 2
Subcategory 3
For example products are added to subcats but are ALL beeing shown in the head category.
This works fine and i do this with WHERE cID in (' . $subids . ')
But now comes it, the cID used to hold just one value but since it has to be possible to add products to multiple categories i now save the multiple selected ids as comma separated in the cID field.
So im searching for a way to basicly find a match from a comma seperated list within a comma separated list because cID has now become comma separated ID's and FIND_IN_SET does not work with this.
I hope someone can shine some light, thank you all!
Have a read of these:
Many-to-many data model
Junction table
Implementing this, as opposed to comma-separated values, should probably save you and your coworkers a lot of headache and simplify your queries, effectively eliminating the need of complex queries. It should be faster, too.
Add full-text search index on this column in the database and then use following sql query
Ref - http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Storing a CSV in a single field is not a good idea. Searching on that requires use of LIKE clause.
where CID LIKE '$cid1,' or CID LIKE ',$cid1,' or CID LIKE ',$cid1' or
CID LIKE '$cid2,' or CID LIKE ',$cid2,' or CID LIKE ',$cid2' or
.... so on
Also FIND_IN_SET would work too.
where FIND_IN_SET( $cid1, CID ) OR FIND_IN_SET($cid2, CID) .. so on
i now save the multiple selected ids as comma separated in the cID field. That's a very bad approach ,why would you store a CSV in a single field ,you shud change your design ,make a seperate table where each value will have a new row and will be mapped to a FK.
What you really need to do,is work on your DB design,read on Normalization and other related topics,I have so added some links,
MSDN Link on Many to Many
Databae Normalization

How to show content for different or all categories?

I have a page called "categories.php". I use it to show different content for different categories.
Example:
mysite.com/categories.php?cat=dance (shows dancing content)
mysite.com/categories.php?cat=sing (show singing content)
Etc...
The database has two different tables:
Categories
categories_id
categories_title
Categories_content
cat_content_id
categories_id
categories_text
categories_image
So far so good. But now the problem I'm facing. Let's say I want to show a content on all the categories. Usually I'll have to add the same content for all the categories one by one. But I think there should be a way to add it only once and show it on all the pages.
I forgot to mention that I use a form with a dropdown menu where the categories are list for which I would like to add the content.
Any ideas how to do this? Do I have to use multiple SQL queries to achieve this?
Maybe I'm just making it hard for myself and there is an easy solution for this.
Thanks in advance.
mw
If you create a new category called "all" or something, you can implement this in the query.
So instead of:
SELECT * FROM Categories JOIN [...] WHERE categories_title = '{$_GET['cat']}'
Use:
SELECT * FROM Categories JOIN [...] WHERE categories_title = '{$_GET['cat']}' OR categories_title = 'all'
Then on a category listing, filter out "all".
There are many ways of doing this, mine might not be the best but it's the best off the top of my head.
You should just be able to use SQL without a where clause. It should return all id's regardless of categories_id.
Select cat_content_id from categories_content;

Selecting rows from MySQL

I'm trying to create a web index. Every advertiser in my database will be able to appear on a few categories, so I've added a categorys column, and in that column I'll store the categories separated by "," so it will look like:
1,3,5
The problem is that I have no idea how I'm supposed to select all of the advertisers in a certain category, like: mysql_query("SELECT * FROM advertisers WHERE category = ??");
If categories is another database table, you shouldn't use a plain-text field like that. Create a "pivot table" for the purpose, something like advertisers_categories that links the two tables together. With setup, you could do a query like:
SELECT A.* FROM advertisers AS A
JOIN advertisers_categories AS AC ON AC.advertiser_id = A.id
WHERE AC.category_id = 12;
The schema of advertisers_categories would look something like this:
# advertisers_categories
# --> id INT
# --> advertiser_id INT
# --> category_id INT
You should design your database in another way. Take a look at Atomicity.
Short: You should not store your value in the form of 1,3,5.
I won't give you an answer because if you starting you use it this way now, you going to run into much more severe problems later. No offense :)
It's not possible having comma-separated values to do this strictly in an SQL query. You could return every row and have a PHP script which goes through each row, using explode($row,',') and then if(in_array($exploded_row,'CATEGORY')) to check for the existence of the category.
The more common solution is to restructure your database. You're thinking too two-dimensionally. You're looking for the Many to Many Data Model
advertisers
-----------
id
name
etc.
categories
----------
id
name
etc.
ad_cat
------
advertiser_id
category_id
So ad_cat will have at least one (usually more) entry per advertiser and at least one (usually more) entry per category, and every entry in ad_cat will link one advertiser to one category.
The SQL query then involves grabbing every line from ad_cat with the desired category_id(s) and searching for an advertiser whose id is in the resulting query's output.
Your implementation as-is will make it difficult and taxing on your server's resources to do what you want.
I'd recommend creating a table that relates advertisers to categories and then querying on that table given a category id value to obtain the advertisers that are in that category.
That is a very wrong way to define categories, because your array of values cannot be normalized.
Instead, define another table called CATEGORIES, and use a JOIN-table to match CATEGORIES with ADVERTIZERS.
Only then you will be able to properly select it.
Hope this helps!

Categories