Recursive SELECT query in Mysql? - php

I got two following tables
category:(one to many-----question)
id name parentId
1 test1 0
2 test2 1
3 test3 1
4 test4 3 .....
like a tree
test1
test2
test3
test4
question:
id title category_id
1 question1 1
2 .... 1
3 .... 2
my question is : if i search category id = 1 ,there will be print total questions:
count(question.id)
3
How to build Select query to do that? is that possible?
Thank you for your valuable help.

This will return count of questions for your selected category, here in example category_id = 1:
mysqli_query('SELECT COUNT(id) FROM question WHERE category_id = 1');
Updated:
so, if you want to count it also for subcategories, the simpliest way will be to have "path" in your category table, where will be all IDs (self ID and ID-s of all parents), and you can separate it with ~ (its important to have ~ also at the beginning and end of path; path can be VARCHAR(255), but if you want have really deep tree, you can use TEXT.
id name parentId path
1 test1 0 ~1~
2 test2 1 ~1~2~
3 test3 1 ~1~3~
4 test4 3 ~1~3~4~
Hope, its clear enough, how you will update your table category to have there also column path.
And the select then will be:
mysqli_query('
SELECT COUNT(id)
FROM question
WHERE category_id IN (
SELECT id
FROM category
WHERE path LIKE "%~'.$category_id.'~%"
)
');
$category_id will be ID of category, for which you want to count questions (also for subcategories).

This is a very simple query:
SELECT COUNT(*) FROM question WHERE category_id='1';
But you probably want a join query like this:
SELECT COUNT(*) FROM question INNER JOIN category
ON (question.category_id = category.id) WHERE category.name='test1';
That will give you the option of searching for category names.
(BTW, did you google this?)
Edit: took me a cup of coffee, but indeed a LEFT JOIN does not make sense if the WHERE is on the joined table. INNER JOIN does.

Try like this,
SELECT COUNT(id) FROM question WHERE category_id IN (SELECT id FROM question WHERE category_id='1')

Related

Projecting mySQL database, how to deal with multiple categories

I need a help with projecting my database. The purpose of this database will be to show offers in different categories. There are 1-6 categories to each item. There are around 80 categories types, so I decided to make three tables as below:
table1:
ID Item_id
1 1
2 2
3 3
4 4
5 5
table2:
ID Item_id Category
1 1 cat55
2 1 cat56
3 1 cat57
4 1 cat58
5 2 cat42
6 2 cat43
7 2 cat44
8 2 cat45
9 3 cat42
etc.
table3:
Category_id category_name
cat55 apples
cat56 oranges
cat57 bananas
cat58 pineapples
Am I doing this right? I've got a problem to make proper sql query to show my categories in php, because when I use this query:
SELECT table1.*, table2.*, table3.*
FROM table1
INNER JOIN table2
ON table1.item_id = table2.item_id
INNER JOIN table3
ON table2.category=table3.category_id
It only gives me the first category name, when I need all of them and show them like this:
Item 1: apples, oranges, bananas, pineapples
Item 2: cat42, cat43, cat44, cat45
Item 3: cat42
What am I doing wrong? Is it wrong query or I need to change the database structure to like this
table 1 and 3 unchanged
table 2:
ID Item_id c1 c2 c3 c4 c5 c6
1 1 cat55 cat56 cat57 cat58 null null
2 2 cat42 cat43 cat44 cat45 null null
3 3 cat42 null null null null null
I'm using foreach loop, so I can do only one query, I know that more queries are possible, but I need to make it as simple as possible.
If you want to fetch all names in single row for each item, following query will work:
SELECT table1.Item_Id,Group_Concat(t3.category_name separator ',') as Category_Name
FROM table1
INNER JOIN table2
ON table1.item_id = table2.item_id
INNER JOIN table3
ON table2.category=table3.category_id
Group by table1.Item_Id;
I don't find any problem in your DB Structure.
Hope it helps!

how to loop through multiple categories in sigle row using php and mysql

i have a database name category
parent_cat cat_id title
0 1 fruit
0 2 vehicle
0 3 goods
1 4 sour
1 5 sweet
1 6 mixed
2 7 sedan
2 8 hatchback
2 9 car
and i store a object in database table name product
obj_name parent_cat sub_id
mango 1 4,5,
maruti 2 7,8,9
bmw 2 7,9
i want to join the two table to show the data so i need to pass the parameter in URL ie. ?obj=vehicle i got by doing sql query
SELECT category.cat_id,category.title,product.parent_cat,product.obj_name
FROM category, product
WHERE category.cat_id=product.parent_cat
AND category.title='$title' --is a difined get variable
if title=fruit i got "mango" if title=vehicle i got maruti and bmw
i want to know if title=sedan or title=car then how can i get maruti and bmw
through loop any solution
You might want to use a LEFT JOIN query, if you have comma separated values for title use IN()
SELECT a.cat_id, a.title, b.parent_cat, b.obj_name
FROM product b
LEFT JOIN category a
ON a.cat_id = b.parent_cat
WHERE a.title IN($title);
Try this:
SELECT category.cat_id, category.title, product.obj_name, product.parent_cat, product.sub_id FROM category
LEFT JOIN product ON category.cat_id = product.parent_cat OR category.cat_id LIKE '%product.sub_id%'
WHERE category.title LIKE '%$title%'
Use LIKE instead of = when you're not sure of the exact data you're comparing or looking for.
[UPDATE]
SELECT category.cat_id, category.title, product.obj_name, product.parent_cat, product.sub_id FROM product
LEFT JOIN category ON (product.parent_cat = category.cat_id OR product.sub_id LIKE '%category.cat_id%') AND category.title LIKE '%$title%'
I'm joining the table in wrong direction, sorry for that.

How can i use sql count in these multiple tables?

I am still a php/mysql newbie and I am working on mysql table relationship concept and i am having an issue with using mysql count in multiple table. Here is my db structure.
**product table**
id product_name product_img groupeid
1 Sneaker Mark sneaker_adi.png 1
2 bag Eric bageric.png 2
3 Sneaker Etoi sneakeretoi.jpg 1
**groupe table**
group_id group_name
1 men
2 women
**category table**
catid catname
1 sneaker-shoes
2 bag-woman
**productcategory table**
prod_id cat_ID
1 1
2 2
3 1
What i want to do is to determine the number of sneaker-shoes using mysql.
We can see that the number of sneaker-shoes in the db is 2.
But how can i use **count()** in these multiple tables.
I tried like this;
$sql = "SELECT COUNT(*) product.id,product_name,catname FROM product INNER JOIN productcategory ON product.id = prod_id INNER JOIN category ON catid = cat_ID WHERE catname='sneaker-shoes'";
i got error like:
Fatal error: Call to a member function execute() on a non-object in C:\wamp\www\kbashopping\Homme\index.php on line 32
Hope i exposed the issue clearly, any help and assistance will be appreciate
Thanks
If you are looking only for the count, mention only the count phrase in the Select clause.
Change :
SELECT COUNT(*) product.id,product_name,catname FROM
to :
SELECT COUNT(product.id) FROM
SELECT count (pc.cat_ID) FROM productcategory pc inner join category c on c.catid = pc.cat_ID where c.catname = 'sneaker shoes';
This will build a temporary table in mysql that joins category and product category but only including results where the catname is sneaker shoes. Then it selects a column to run the count operation on, and returns the result of count.

select query records if multiple type is matched

I have some mysql tables like below,
1)videos
id name
1 test1
2 test2
2)tags
id name
1 theme1=test1
2 theme1=test2
3 theme2=test1
4 theme2=test2
5 age=senior
6 age=children
3)tags_to_items
vid tagid
1 1
1 5
Here in table tags_to_item you see videos.id=1 has 2 tags
1)theme1=test1 AND 2)age=senior. It means video.id=1 has 2 tags.
Now here is one conflict,
what i am doing now is, i am searching for theme's only. It means if i search where theme1=theme1 then it need to also search theme1 in theme2 and vice versa. like this
WHERE tagid=1 OR tagid=2
This is functioning proper, but now i want to search if video have multiple tag with AND condition like this
WHERE tagid=5 AND tagid IN (1,2)
It should return video.id=1
So, probably it need to search where video 1 contains tag tag age=senior AND theme1=theme1 OR theme2=theme1. But its not working, anyone have idea how can i do like this?
I think i got the answer.
I need to do join like this,
INNER JOIN tags_to_items t2 ON (v.id = t2.tagid AND t2.tagid = 5)
INNER JOIN tags_to_items t3 ON (v.id = t3.tagid AND t3.tagid in ('27' ,'69','84' ,'99' ))

Getting rows from a database then modify them with additional rows from database

Here's the table structure
id | name | parent_id
1 fruit 0
2 apple 1
3 banana 1
4 orange 1
5 vegetable 0
6 carrot 5
7 tomato 5
I need get every row where a parent_id is 0, but I also need to to set an array on each row which is equal to 0 with the name of all it's children.
So I would have something like:
id = 1, name = fruit, children = [apple, banana, orange]
I'm aware there are better table structures but I must use the table structure stated.
I've tried getting all rows from the db then looping through them, if parent_id = 0 then push that to an array, otherwise it's a child so find parent in array and add it to that.
But there must be a better way?
I thinks you should use:
SELECT pr.id, pr.name, (
SELECT GROUP_CONCAT(name) FROM test as ch WHERE ch.parent_id = pr.id GROUP BY ch.parent_id
) AS children
FROM test as pr
WHERE parent_id = 0
Without thinking about performance or beauty:
SELECT t.id, name, (
SELECT GROUP_CONCAT(name) FROM table WHERE parent_id = t.id GROUP BY parent_id
) AS children
FROM table t
WHERE parent_id = 0
Avoiding a sub query, just using a self join the following should do it:-
SELECT t1.id, t1.name, GROUP_CONCAT(CONCAT('name:', t2.name))
FROM test t1
LEFT OUTER JOIN test t2
ON t1.id = t2.parent_id
WHERE t1.parent_id = 0
GROUP BY t1.id, t1.name
SQL fiddle for it:-
http://www.sqlfiddle.com/#!2/d4479a/1
I had come across a similar issue, where I had to fetch all subordinates of a user in a recursive manner.
We wrote a function where we loop through each of the child records recursively until we reach the final subordinate. We keep on concatenating the subbordinates we find in each loop.
Hope through this you can think of a solution and resolve your problem.

Categories