mysql - right joining two tables as one to many relation - php

I know that this question already asked many times here but after all I could't found my answer that what I want.
My Question is:
I have two tables and the structure of these tables is as:
table1:
item_id, store,title,available,shipping
table2:
item_id, review_rate,user_id,review_title
These tables should be join as one to many relation.
For example if the data in these tables is as:
table1:
item_id store title available shipping
-------------------------------------------------------
11 glasses ..........................
12 dresses ..........................
.
.
.
table2:
item_id review_rate user_id review_title
--------------------------------------------------
11 3 10023 good item
11 5 10024 nice item
12 1 10024 nice one
.
.
.
then the result should be as after joining:
afterJoin:
item_id store title available shipping rate people_reviewed
-----------------------------------------------------------------------
11 .................................... 4 2
12 .................................... 1 1
The query I tried to join is as:
CREATE OR REPLACE VIEW afterJoin AS
SELECT i.*,round(AVG(r.review_rate)) as rate,count(r.user_id) as people_reviewed
FROM table1 i
RIGHT JOIN table2 r ON i.item_id = r.item_id
but this return only one row.

Your query is missing a GROUP BY clause. Without it your database is aggregating all of the records together.
SELECT i.*, round(AVG(r.review_rate)) as rate, count(r.user_id) as people_reviewed
FROM table1 i
RIGHT JOIN table2 r ON i.item_id = r.item_id
GROUP BY i.item_id
The GROUP BY instructs the db to aggregate for each item_id.

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!

MySQL: Select several rows based on several keys from two different tables

I have these two tables - user_schedules and user_schedule_meta, shown below:
------------------------------------
| id | scheduler_id | status |
------------------------------------
1 3 pending
2 5 active
3 6 active
and
----------------------------------------------
| id | user_schedule_id | meta_key |meta_value
----------------------------------------------
1 3 course-id 135
2 3 session-id 15
3 3 schedule-id 120
I want to write a query to enable me select, for example, from both tables where EVERYONE of the below 5 conditions are met:
user_schedule_id = 3
scheduler_id = 6
session_id = 15
course-id = 135
schedule-id = 120
This is what I have so far, but it is not working:
SELECT user_schedule_meta.`id` FROM user_schedule_meta, user_schedules
WHERE user_schedules.`scheduler_id` = 6
AND user_schedules.id = user_schedule_meta.`user_schedule_id`
AND (
(user_schedule_meta.`meta_key` = 'course-id' AND user_schedule_meta.`meta_value` = 135)
OR (user_schedule_meta.`meta_key` = 'session-id' AND user_schedule_meta.`meta_value` = 15)
OR (user_schedule_meta.`meta_key` = 'daily-schedule-id' AND user_schedule_meta.`meta_value` = 120)
)
GROUP BY user_schedule_meta.`id`
Any suggestions what I am not doing right?
This is a typical key-value store lookup problem. These are trickier than they look in SQL, in that they require multiple JOIN operations.
You need a virtual table with one row per user_schedules.id value, then you can filter it. So
SELECT u.id, u.scheduler_id
FROM user_schedules u
JOIN user_schedule_meta a ON u.id=a.user_schedule_id AND a.meta_key='course-id'
JOIN user_schedule_meta b ON u.id=b.user_schedule_id AND b.meta_key='session-id'
JOIN user_schedule_meta c ON u.id=c.user_schedule_id AND c.meta_key='daily-schedule-id'
WHERE a.meta_value = 135 -- value associated with course-id
AND b.meta_value=15 -- value associated with session-id
AND c.meta_value=120 -- value associated with daily-schedule-id
Notice also that you can list your table with associated attributes like this. This trick of joining the key/value table multiple times is a kind of pivot operation. I use LEFT JOIN because it will allow the result set to show rows where an attribute is missing.
SELECT u.id, u.scheduler_id, u.status,
a.meta_value AS course_id,
b.meta_value AS session_id,
c.meta_value AS daily_schedule_id
FROM user_schedules u
LEFT JOIN user_schedule_meta a ON u.id=a.user_schedule_id AND a.meta_key='course-id'
LEFT JOIN user_schedule_meta b ON u.id=b.user_schedule_id AND b.meta_key='session-id'
LEFT JOIN user_schedule_meta c ON u.id=c.user_schedule_id AND c.meta_key='daily-schedule-id'
try this is code
select * from user_schedule_meta where user_schedule_id=3 and
(meta_key='session-id' AND meta_value=15
or meta_key='daily-schedule-id' AND meta_value=120
or meta_key='course-id' AND meta_value=135
)

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 from three tables

I have three tables where table_2 is the middle(connected) between table_1 and table_3
tables
table_id
...
...
table_rest
rest_id
table_id
...
rest
rest_id
...
...
And the query to select I use
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
WHERE rest_id = '$rest_id'
What I need now is to join in this query another table reserv
id
...
status
To check if status is 0, 1,or 2 to not show me anything if there is no status this mean there is no record to show me. In other words this is resserved system where I show on screen few tables. If status is 0,1,2 thats mean the table is taken. If nothing is found for status this mean that there is no record for table and can be shown to user.
EDIT: Sample scenario
tables
table_id
1
2
3
4
5
rest
rest_id
1
2
table_rest
table_id | rest_id
1 2
2 2
3 2
4 2
5 2
So the query that is above will generate 5 tables for rest_id=2 and none for rest_id=1
So now I have another table
reserv
id | status
1 0
2 1
3 2
So in this table reserv currently are saved 3 tables. The idea is to show me other two whit id=4 and id=5 because they are not in table reserv and don't have any status.
Hope is a little bit more clear now.
You have to point from table reserv to which table is beign booked, let's call it reserv.table_id
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
left join reserv
on reserv.table_id = m.id
WHERE rest_id = '$rest_id'
and reserv.status is null (*note)
*note use 'is' or 'is not' depending of your needs, as far as I read, first seems that you want !=, later that what you want is =
It's better if you provide sample data or sqlfiddle. Based on what I realize: Is this what you want:
select tables.table_id, rest.rest_id
from tables
left join table_rest on table_rest.table_id = tables.table_id
left join rest on rest.rest_id = table_rest.rest_id
where rest.rest_id = '$rest_id'
and tables.table_id not in (select id from reserv)

Fetch data from mapping table if the condition matches in multiple rows

product_id property_id
1 2
1 5
2 2
3 5
I have a mapping table as above. I want to get only product with id =1 if product_id in (2,5). i.e. I want to fetch data if the table contains both 2,5 not the data if it is with property_id only 2 or 5
select group_concat(distinct product_id) product_ids from table where property_id in (2,5)
UPDATE:
The property_id in can be property_id in(2,5,....). I get output from form as 2,5,.... and so on. Its not just for the single case. I just want the output if the condition in property_id in matches the whole series.
This how it could be done
select
product_id from
table_name
where property_id in (2,5)
group by product_id
having count(*) = 2
All you need to change having count(*) = 2 to the number of items inside IN() , right now its 2 and if you are looking at 3 property id then it will be 3 and so on.
select distinct a.product_id
from table a, table b
where a.product_id = b.product_id
and a.property_id = 2
and b.property_id = 5

Categories