Mysql Join with WHERE min(value) - php

I have this problem
I have 2 Tables
1. product_detail
-id
-name
-thumb
2. product_sale
-id
-pid
-fid
-price
-package
.
SELECT *
FROM product_sale
WHERE MIN(product_sale.price)
JOIN product_detail
ON product_detail.id = product_sale.pid
ORIGINAL SELECT SORRY POSTED WRONG
SELECT * FROM product_detail INNER JOIN product_sale ON product_detail.id = pid
I Have 1 Product in product_detail Example Product1
I Have Many rows in product_sale for Product1 but different product_sale.fid and product_sale.price
What i need to do ist make a select that display Product1 With Lovest Price in product_sale
1 Product1 1.50 1pz
2 Product2 2.50 3pz
3 Product3 3.00 1pz
Now i Get
1 Product1 1.50 1pz
2 Product1 1.65 1pz
3 Product1 1.70 1pz
4 Product3 3.00 1pz
Please helpme what select i need to do ??Thank You All

Barring subqueries, you can't JOIN after a WHERE, and I am pretty sure you can't use MIN in a WHERE either. However, you can WHERE a subquery that contains a MIN.
SELECT *
FROM product_sale AS ps INNER JOIN product_detail AS pd ON ps.pid = pd.id
WHERE (ps.pid, ps.price) IN (
SELECT pid, MIN(price)
FROM product_sale
GROUP BY pid
);
Note that if the product is sold at the lowest price multiple times, you will get multiple rows for it. I am not clear on what the #pz values are supposed to be, but perhaps the * in my answer should be pd.id, pd.name, COUNT(1) AS pz and GROUP BY pd.id, pd.name placed before the ;
Edit: The below should get the "last sale" asked about in the comments below this answer.
SELECT *
FROM product_sale AS ps3
INNER JOIN product_detail AS pd ON ps3.pid = pd.id
WHERE ps3.fid IN (
SELECT MAX(ps2.fid) AS lastFidsForPidsAtLowestPrices
FROM product_sale AS ps2
WHERE (ps2.pid, ps2.price) IN (
SELECT ps1.pid, ps1.MIN(price) AS lowestPriceForPid
FROM product_sale AS ps1
GROUP BY ps1.pid
)
GROUP BY ps2.pid
)
;

Seems to be a straight forward join with a group by and a min..
SELECT PD.name, min(price) as LowestSoldPrice, PD.Thumb, PS.Package
FROM product_Detail PD
LEFT JOIN product_Sale PS
on PD.ID = PS.PID
GROUP BY PD.name, PD.Thumb, PS.Package

I don't understand your query at all. I was surprised it produced anything but an error. This is what I would do.
select pd.id productid,
min(pd.name) name, -- min just so I do not have a complex group by
min(ps.price) minprice
from product_detail pd
join product_sale ps
on pd.id=ps.pid
group by pd.id
This will give you one row per product ID with the name of the product and the min price.

SELECT ps.*, pd.*
FROM product_sale ps
LEFT JOIN product_sale t
ON ps.pid = t.pid AND ps.price>t.price
LEFT JOIN product_detail pd
ON pd.id = product_sale.pid
WHERE t.pid IS NULL
But as many people here I wonder if you really need GROUP BY. What is accepted behavior if you have 2 or more sales with the same minimum price? Should all records be returned? or just one? which one then?

Related

php - mysql join three tables and grouping

I have three tables:
products:
id name
1 juice
2 chips
3 water
orders:
id product_id order_id
1 1 special1
2 3 special1
3 2 special1
4 1 special2
5 2 special2
final_orders:
id order_id date
1 special1 25-3-2017
2 special2 25-3-2017
I want to select all products names in every order using order_id to show:
ID: Special1
Date: 25-3-2017
Products List:
juice
water
chips
ID: Special2
Date: 25-3-2017
Products List:
juice
chips
I use this:
$sql = "select * from products,orders where products.id = orders.product_id";
but it doesn't work and show me duplicated results.
thank you.
You need to join with final_orders as well:
SELECT *
FROM final_orders AS f
JOIN orders AS o ON f.order_id = o.order_id
JOIN products AS p ON p.id = o.product_id
ORDER BY f.order_id
To prevent duplication in the output, your loop that prints the output should only show the information from final_orders when it changes. See How can i list has same id data with while loop in PHP?
If you want to see one final order per record in your result set, then you will have to aggregate the products which appear in each order. One option then is the following query which aggregates order products into CSV using MySQL's GROUP_CONCAT():
SELECT t1.order_id,
t1.date,
t2.products
FROM final_orders t1
INNER JOIN
(
SELECT a.order_id, GROUP_CONCAT(b.name) AS products
FROM orders a
INNER JOIN products b
ON a.product_id = b.id
GROUP BY a.order_id
) t2
ON t1.order_id = t2.order_id
Demo here:
Rextester

join multiple relation tables

i have a table food
food_id food_name
1 chappathi
and another table category
category_id category_name
1 non-veg
2 nutrition
and a relation table food_category
food_id category_id
1 1
1 2
where the food_id is the foriegn key of food_id in food table, category_id is the foriegn_key of category_id in the category table, there will be case no categories for a food
i have tried
$sql= "SELECT * FROM food f
LEFT JOIN food_category fc
ON f.food_id=fc.food_id
LEFT JOIN category c
ON fc.category_id=c.category_id"
it gives me more than one food items, what i want is
item name: chappathi
categories: non-veg, nutrition
------------------------------
second row of result set if there is any
Try this:
SELECT f.food_name AS item_name, GROUP_CONCAT(c.category_name SEPARATOR ', ') AS categories
FROM food f
LEFT JOIN food_category fc ON f.food_id=fc.food_id
LEFT JOIN category c ON fc.category_id=c.category_id
GROUP BY f.id
Hope it will help you.
Agreed with #strawberry. Look at group_concat.
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
The query should be written as below to fetch the food name and its categories list.
SELECT f.food_name as ItemName,
STUFF(
(SELECT DISTINCT ',' + c.category_name
FROM food
LEFT JOIN food_category fc on fc.food_id= food.food_id
LEFT JOIN category c ON fc.category_id =c.category_id
FOR XML PATH ('')), 1, 1, '') AS Categories
FROM food f
group by f.food_id, f.food_name
Please check it out.
What you need is group_concat:
SELECT f.food_name, group_concat(c.category_name) AS Cat
FROM food AS f
LEFT JOIN food_category AS fc ON f.food_id = fc.food_id
LEFT JOIN category AS c ON c.category_id = fc.category_id
GROUP BY f.food_id

I cant select data from database with inner join using mysql

I cant select data from database .
My table structrure is given below
customer table
id name
10 geetha
customer country table
id cust_id country
1 10 6
2 10 16
I got the result like these way
customer name country
geetha 6
geetha 16
But i want to get the one customer data only one time ie with out repeating.
customer name country
geetha 6
my query is
SELECT customer.name,customer.id,customer_country.country_id, customer_country.cust_id
FROM customer
INNER JOIN customer_country on customer.id = customer_country.cust_id
If you have duplicates in the customer_country table, then you need to choose one of them. Here is one method using max():
select c.name, max(cc.country_id)
from customer c inner join
customer_country cc
on c.id = cc.cust_id
group by c.name;
If you want all of them in a list, use group_concat():
select c.name, group_concat(cc.country_id) as countries
from customer c inner join
customer_country cc
on c.id = cc.cust_id
group by c.name;
For first record only, apply to the end: limit 1
SELECT customer.name,customer.id,customer_country.country_id,
customer_country.cust_id from customer
inner join customer_country on customer.id= customer_country.cust_id limit 1
try this i add distinct before customer_country.cust_id
SELECT customer.name,customer.id,customer_country.country_id, distinct customer_country.cust_id
FROM customer
INNER JOIN customer_country on customer.id = customer_country.cust_id

Getting count from inner join table

I have tables as described below:
subscription_plans (Table for storing all plans)
id plan days_limit added_on status rate
------------------------------------------------
1 PlanA 15 1398249706 1 150.00
2 PlanB 15 1398249706 1 150.00
subscribed_videos (Table for storing details of video in each plans)
id plan_id videoid
----------------------
1 1 1
2 2 2
subscription_groups (Table for storing groups where a plan can be part of another plan. ie, Plan A be a plan with 2 other individual plans, Plan B and C )
id plan_id assosiated_plan_id added_on
----------------------------------------------
1 1 2 1398249706
usersubscription (Table for storing user subscribed plans)
id user_id plan_id subscribed_on
---------------------------------------
1 1 1 1398771106
Now, my problem is that how can I get the count of videos for each plans. If Plan A contains both Plan B and C (subscription_groups table), then the count should return the total video count for each individual plans in that particular plan. Now I have done with a query which will return plan details along with count of videos for a plan but I am not able to join it with subscription_groups. How can I accomplish this in a single query.
$data['planquery']=$this->db->query("select
us.plan_id,us.subscribed_on,sp.plan,sp.days_limit,sp.rate,count(sv.videoid) from
usersubscription as us INNER JOIN
subscription_plans as sp ON us.plan_id=sp.id INNER JOIN subscribed_videos as sv ON sp.id=sv.plan_id where sp.status=1 and us.user_id=1");
Expected Result:
plan_id subscribed_on plan days_limit rate count
-------------------------------------------------------
1 1398771106 PlanA 15 150.00 2
Can anyone help me to find a solution for this?
Thanks in advance.
You can do so
SELECT
us.plan_id,
us.subscribed_on,
sp.plan,
sp.days_limit,
sp.rate,
COUNT(sv.videoid)
FROM
usersubscription AS us
RIGHT JOIN subscription_plans AS sp
ON us.plan_id = sp.id
INNER JOIN subscribed_videos AS sv
ON sp.id = sv.plan_id
INNER JOIN subscription_groups g
ON(g.plan_id =sv .plan_id OR sv.plan_id= g.assosiated_plan_id)
WHERE sp.status = 1
AND (us.user_id = 1 OR us.user_id IS NULL )
Demo
Since user has only plan associated but the associated plan can also has another plan linked so the last condition will check the user id but for is null to for the second linked plan user id will be null due to right join on subscription_plans
Edit
SELECT
u.plan_id,
u.subscribed_on,
p.plan,
p.days_limit,
p.rate
,COUNT(DISTINCT v.`videoid`)
FROM `usersubscription` u
JOIN `subscription_groups` g
ON (u.`plan_id` = g.`plan_id`)
RIGHT JOIN `subscription_plans` p
ON(u.`plan_id` = p.`id` OR g.`assosiated_plan_id` = p.`id`)
INNER JOIN `subscribed_videos` v ON(v.`plan_id`=g.`assosiated_plan_id` OR u.`plan_id`= v.`plan_id`)
WHERE u.`id`=1 AND p.`status` = 1
Demo 1 Demo2
For video ids you can use group_concat
SELECT
u.plan_id,
u.subscribed_on,
p.plan,
p.days_limit,
p.rate
,COUNT(DISTINCT v.`videoid`) `video_count` ,
GROUP_CONCAT(DISTINCT v.`videoid`) `video_ids`
FROM `usersubscription` u
JOIN `subscription_groups` g
ON (u.`plan_id` = g.`plan_id`)
RIGHT JOIN `subscription_plans` p
ON(u.`plan_id` = p.`id` OR g.`assosiated_plan_id` = p.`id`)
INNER JOIN `subscribed_videos` v ON(v.`plan_id`=g.`assosiated_plan_id` OR u.`plan_id`= v.`plan_id`)
WHERE u.`id`=1 AND p.`status` = 1
Demo 1a Demo 2a

Returning average rating from a database (SQL)

I'm trying to create a rating system, where the user can rate pictures/videos/audio etc. I have two tables at the moment
Table: products
Cols: product_id[PK] | name | category | type | link
This is the products table and contains information about the products. If you're confused by products, think of the "product" as the image/video/audio, I named it like this simply for allowing me to understand it easier. The second table is the ratings
Table: product_ratings
Cols: rating_id[PK] | rating | product_id | timestamp
This table stores information about the rating the user has given.
I want a page where it will display the highest rating (on average) for all "products". So far, I've looked through SA, and found the follow piece of code:
SELECT
p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
WHERE p.product_id = 1
This just returns the average rating for a specific product_id, How would I go about getting ALL the product_ids and their average rating, and how would I find the highest one via PHP?
I've tried:
WHERE p.product_id < 1 AND p.product_id < 30
But this just returns product_id of 2, with it's name and average_rating, which I don't understand.
Guidance/links to material are welcome
SELECT
p.product_id,
p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
GROUP BY p.product_id
ORDER BY rating_average DESC
LIMIT 1
Just try:
SELECT
p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
also this is meaningless expression:
WHERE p.product_id < 1 AND p.product_id < 30
because it is completely equivalent to
WHERE p.product_id < 1
and i doubt that you have ids below zero
Your query is close. Just remove the WHERE clause that filters everything.
SELECT p.product_id, p.name,
AVG(pr.rating) AS rating_average
FROM products p
INNER JOIN product_ratings pr
ON pr.product_id = p.product_id
ORDER BY rating_average DESC
This will return you the averages for each product, sorted with the highest average rating at the top of the resultset.

Categories