How to get avg rating per product using codeigniter query? - php

I have rating table which have rating for every product given by user, I am retrieving all rating records, but at the same time I want to get avg rating based on per product but I am unable to get ouptput
Query :
$this->db->select('ratings.*');
$this->db->select('select AVG(ratings) as avg_rating from ratings group by product_id');
$this->db->from('ratings');
$this->db->join('users','users.id=ratings.user_id');
$this->db->get()->result();
Rating table
id user_id product_id rating
1 4 1 4
2 5 2 4
3 6 1 2
4 7 4 4
Expected output:
id user_id product_id rating avg rating
1 4 1 4 3
2 5 2 4 4
3 6 1 2 3
4 7 4 4 4

get data from table ratings, using a left join with select for the average.
the join() function of Codeigniter allows you to to write a select part instead of the table name, but you need to place it into parenthesis:
$this->db->select('t1.*, t2.avg_rating, t3.*');
$this->db->from('ratings t1');
$this->db->join('
(select product_id, avg(rating) as avg_rating
from ratings
group by product_id) t2','t2.product_id=t1.product_id','left'
);
$this->db->join('users t3','t3.id=t1.user_id','left');
$this->group_by('t1.userid')
$this->db->get()->result();
generates:
SELECT t1.*, t2.avg_rating, t3.*
FROM ratings t1
left join
(select product_id, avg(rating) as avg_rating from ratings group by product_id) t2
on t2.product_id=t1.product_id
left join users t3
on t1.user_id = t3.id
group by t1.user_id
and outputs as you expect.

When Queries get complicated i like to use query instead of query builder. You could do this:
$this->db->query('select r.*,(select round(sum(r2.rating)/count(*),0) from ratings r2 where r2.product_id = r.product_id ) as 'avg rating' from ratings r')->result();

Related

Count in Joins in SQL

i have two tables (post.id is primary key which become seconday key in like.post_id )
table "post"
id user_id image
1 10 abc.jpg
2 20 xyz.jpg
3 10 ajb.jpg
Table "Like"
id user_id post_id likes
1 10 1 1
2 20 2 1
3 10 1 1
4 10 1 1
3 10 3 1
now i want whenever i pass user_id then i wan to get all post of users with number of likes of posts
i tried with following code but not worked,
SELECT selfie_info.id,selfie_info.user_id,selfie_info.image, (SELECT COUNT(m.likes)FROM post_likes m WHERE m.user_id='10') as total_likes FROM selfie_info where user_id='10'
how can i do this ? i want result like following (if i pass user_id=10 )
user_id post_id likes
10 1 3
10 3 1
SELECT p.user_id, p.id AS post_id, COUNT(l.id) AS total_likes
FROM post p
LEFT JOIN likes l ON l.post_id =p.id
WHERE p.user_id=10 GROUP BY p.id;
You can use aggregation:
select pl.post_id, count(*) as numlikes,
si.*
from selfie_info si join
post_likes pl
on si.user_id = pl.user_id
where si.user_id = 10
group by si.user_id, si.post_id
You can use si.* in the select, even though this is a group by query because you are aggregating by the primary key/unique id in the table.
You have all necessary data in table "like"
You can use one select from "like" table.
select user_id, post_id, sum(likes) as likes from like where user_id = 10;
You need to count or sum likes?
Depends on you needs You can sum(likes) or count(*) likes

Select records from two tables if atleast 4 records in second table

I have 2 tables and i want to fetch data based on below condition:
Table1 has multiple product records.
Table2 contains various Size option for products and can not have more or less than 4 rows.
Now, i want to fetch those products which do not have entry or do not have exact 4 entries.
Table Structure is as below:
Table1
id name color price instock
----------------------------------
1 rice white 1200 1
2 shoe brown 2500 1
3 belt red 5200 1
Table2
id size pid
-----------------
1 5 1
2 10 1
3 4 1
4 15 1
5 7 2
Now Query shall fetch product with ID 2 and 3 as they have records less than 4 and no record resp.
I was using below query to fetch products which have no records in Table2
SELECT p.* FROM `Table1` p LEFT JOIN `Table2` t ON p.id = t.pid WHERE
t.pid IS NULL
SELECT p.id, p.name, p.color, p.price, p.instock, count(t.*)
FROM `Table1` p
LEFT JOIN `Table2` t
ON p.id = t.pid
GROUP BY p.id, p.name, p.color, p.price, p.instock
HAVING count(t.*) < 4

Retrive data from 2 tables with multiple conditions

I have a question, So I have 2 tables :
order:
id supplier_id status
1 2 3
2 4 5
3 2 7
gift_2_order:
order_id gift_id order_price
1 2 4
2 1 5
3 2 6
1 6 1
2 4 9
So I want to get all orders, how many times is repeated in table : gift_2_order and the total price. For this example I want to get :
order number_repetitions total_price
1 2 5
2 2 14
3 1 6
I tried :
SELECT
ord.estimation_date,
ord.order_date,
ord.supplier_id,
ord.status,
count.(g2o.order_id),
sum.(g2o.order_price)
FROM `order` ord
INNER JOIN gift_2_order g2o on ord.id = g2o.order_id
Can you help me please? Thank's in advance.
you have to group by ord.id and remove . from count and sum
SELECT
ord.id,
count(g2o.order_id),
sum(g2o.order_price)
FROM `order` ord
INNER JOIN gift_2_order g2o on ord.id = g2o.order_id
group by ord.id order by ord.id
Try:
SELECT
ord.order_id,
count(g2o.order_id) as number_repetitions ,
sum(g2o.order_price) as total_price
FROM `order` ord
INNER JOIN gift_2_order g2o on ord.id = g2o.order_id
group by ord.order_id
By the way "order" is no very good table name.
SELECT
t1.supplier_id,
t1.status,
count(t2.order_id) as total_orders,
sum(t2.order_price) as total_amount
FROM `order` t1
join gift_2_order t2 where t1.id = t2.order_id group by t2.order_id
You don't have the need of doing a JOIN. Without a JOIN the query will be more performant...
This SQL fiddle will do the thrick for you:
SELECT
order_id,
count(order_id),
sum(order_price)
FROM gift_2_order
GROUP BY order_id
ORDER BY order_id
If you do not need to join tables, don't do it.

Sql request into 2 tables to get percentage of each rows

I have 2 SQL tables like this:
___Rooms:
ROO_Id ROO_Number
1 101
2 201
___Bookings:
BOO_Id BOO_RoomNumber
1 1
2 1
3 2
I want to echo a table with all rooms I have with percentage for each.
BOO_RoomNumber percentage count
101 66% 2
201 33% 1
Thanks.
Here is the answer:
UPDATED
select r.ROO_Number BOO_RoomNumber, ((ifnull(cnt_book,0)*100)/(select count(*) from Bookings)) percentage, ifnull(cnt_book,0) `count`
from Rooms r left join (select BOO_RoomNumber, count(*) cnt_book
from Bookings
group by BOO_RoomNumber) cnt on r.ROO_Id=cnt.BOO_RoomNumber
Working SQLFiddle
Try to use this:
SELECT r.id as BOO_RoomNumber, ((booked/(select count(id) from BOOKINGS))*100) as percentage, booked as `count`
FROM ROOMS as r
LEFT JOIN
(
SELECT count(id) as booked, roomId
FROM BOOKINGS
GROUP BY roomId
) as b on b.roomId=r.id

Select unique product id and order by stock id desc

I'm trying to get unique product from stock...
stock table:
id - product - quantity
1 2 0
2 3 5
3 2 19
4 4 3
5 2 8
result
id - product - quantity
5 2 8
4 4 3
2 3 5
it's working with
SELECT max(id) as id,
product
FROM stock
GROUP by product
ORDER by id DESC
but I can't get last quantity of product
with this query I get:
id - product - quantity
1 2 0
2 3 5
4 4 3
I need latest quantity of the product.
You can wrap your existing query in a subquery and join that on the table itself so you can get the other columns of the same row.
SELECT a.*
FROM stock a
INNER JOIN
(
SELECT product, MAX(ID) id
FROM stock
GROUP BY product
) b ON a.product = b.product
AND a.ID = b.ID
ORDER BY a.id DESC
Assuming your definition of "latest" is max(id), I think the easiest way is:
SELECT s.id, s.product, s.quantity
FROM stock s
WHERE NOT EXISTS (SELECT 1 FROM stock s2 WHERE s2.product = s.product and s2.id > s.id);
Basically give me the stock rows where there is no row for the same product with a greater id.
You can do it with a left join of the table with itself that filters only rows without one with higher id and same product, avoiding subquery and group by, which can be very expensive on large tables:
select p1.id, p1.product, p1.quantity from stock as p1
left join test as p2 on p1.product = p2.product and p2.id> p1.id
where p2.id is null
order by p1.id desc;

Categories