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
Related
I have a table named Records that shows products. I also have a table named Categories that shows the categories for each individual product (if one exists).
The Categories table is structured liked:
id category_id
-- -----------
1 1
1 3
3 1
3 2
5 4
The query I run to pull record ID and category ID(s) is:
SELECT
Records.id,
(SELECT
GROUP_CONCAT(C.category_id)
FROM `Categories` C
WHERE Records.id = C.id) AS 'CategoryName'
FROM
Records
The output will return:
id CategoryName
-- ------------
1 1,3
2 NULL
3 1,2
4 4
5 NULL
I have an area of my website where users can filter records by category. Let's say user wants to filter for category = 1 or 2. I was thinking I just tack on a WHERE FIND_IN_SET(1,CategoryName) OR FIND_IN_SET(2,CategoryName) but this does not work because of the MySQL execution order and CategoryName column does not exist yet.
What is the best way to filter for category_id? The input for categories will be comma separated but I can use PHP to explode() the string to separate them.
You can rewrite the query with a LEFT join of Records to Categories:
SELECT r.id,
GROUP_CONCAT(c.category_id) AS CategoryName
FROM Records r LEFT JOIN Categories c
ON c.id = r.id
GROUP BY r.id
and if you want to use the same query for filtering all you have to do is add at the end a HAVING clause:
HAVING FIND_IN_SET(1, CategoryName) OR FIND_IN_SET(2, CategoryName)
Or, you can filter first and then aggregate:
SELECT r.id,
GROUP_CONCAT(c.category_id) AS CategoryName
FROM Records r INNER JOIN Categories c
ON c.id = r.id
WHERE c.category_id IN (1, 2)
GROUP BY r.id
Okay I have a table 3 Tables (Orders, Order_details, Products)
Orders
id | order_date
1 | March-01-13
2 | March-02-13
3 | April-01-13
4 | May-01-13
5 | June-01-13
and so on.....
Order_Details
id | order_id | product_id | total_price
1 1 1 100 /*mouse*/
2 1 3 200 /*monitor*/
3 2 2 50 /*keyboar*/
4 2 3 200 /*monitor*/
and so on....
Products
id | title
1 mouse
2 keyboard
3 monitor
and so on...
And here is my SQL Query that giving unexpected output
SELECT title, SUM(total_price) as total_price, orders.order_date as date
FROM products
LEFT JOIN order_details
ON order_details.product_id=products.id
LEFT JOIN orders
ON orders.id=order_details.order_id
WHERE title='monitor' /*this is just a try, prod_id should be the one*/
GROUP BY MONTH(date)
ORDER BY total_price DESC LIMIT 10
What I want to get is the total_price of product_id in all months
Expected Output
title | total_price | date
monitor 400 March
When using a GROUP BY, all of the fields in the SELECT list need to either be aggregated, or be part of the GROUP BY. So try adding the 'title' to the group by, and adding the MONTH function to the order_date in the SELECT list as follows:
SELECT title, SUM(total_price) as total_price, MONTH(orders.order_date) as date
FROM products
LEFT JOIN order_details ON order_details.product_id=products.id
LEFT JOIN orders ON orders.id=order_details.order_id
WHERE title='monitor'
GROUP BY title, date
ORDER BY total_price DESC LIMIT 10
This will get the total_price for each product for each month.
Do you want something like this?
SELECT p.title, SUM(total_price) as total_price
FROM products p LEFT JOIN
order_details od
ON od.product_id = p.id LEFT JOIN
orders o
ON o.id = od.order_id
GROUP BY p.title
ORDER BY total_price DESC
LIMIT 10;
I don't see why your sample output would have a month in it.
here's my data structure:
category_main
id name
---------------------
1 catmain1
2 catmain2
category_sub
id name id_catmain
---------------------
1 catsub1 1
2 catsub2 1
3 catsub3 2
images
id name catsub
---------------------
1 image1 1
2 image2 1
3 image3 2
4 image4 3
desired output:
id_catmain catmain images_total
--------------------------------------------------
1 catmain1 3
2 catmain2 1
the problem is getting the total amount of images per main category ..
i tried something like (as a view)
select categories.*, group_concat(id) as all_cat from categories group by id_catmain
then querying that view using FIND_IN_SET .. but i think there must be a better way using one query only. any ideas?
thanks
Something along these lines should work I think:
SELECT c.id, c.name, COUNT(*) AS images_total FROM images i
JOIN category_sub cs ON cs.id = i.catsub
JOIN category_main c ON c.id = cs.id_catmain
GROUP BY c.id
What you are basically doing there is tying all the image table's rows to the subcategories they represent, then tying the main categories to the same row through the subcategory id. Then you can simply count all the rows, grouping the amount of counted rows by all the different main category ids.
You can solve this in many ways. One of these would be to use a subquery:
SELECT c.id AS id_catmain, c.name AS catmain,
(SELECT COUNT(i.id) AS totalImages
FROM images i
INNER JOIN category_sub s ON i.catsub = s.id
WHERE s.id_catmain = c.id) as totalImages
FROM category_main c
ORDER BY c.name ASC;
Sample here: http://sqlfiddle.com/#!9/d78e2/5
This is not better than Bun's answer, it's just to say there are other ways of doing this.
First table: Product
id | Name | Price | Discount
-------------------------------
1 xyz 200
2 xyz 250
3 yz 100 50
Second table : buy
id | userid | Product_id Card_details
------------------------------------------
1 1 1 55555
2 1 2 88888
3 3 1 77777
Now i have $user_id in my php variable. If user id is 3 i want following output:
id Name Price Discount user_id Product_id Card_details
3 yz 100 50 3 1 77777
How can i achieve this.
Use JOIN or where
SELECT * FROM Product p JOIN buy b
ON p.id = b.Product_id
WHERE b.userid ='3'
SELECT * FROM Product JOIN buy ON Product.id = buy.id WHERE buy.userid = $user_id;
Try the following query
$query = "SELECT Product.id, Product.Name, Product.Price, Product.Discount,
buy.userid , buy.Product_id, buy.Card_details
FROM Product
JOIN buy ON Product.id = buy.Product_id
WHERE buy.userid = 3";
First in your Product table xyz is to time you have to use unique name for your product for better understanding.
Now in Product table id is your product id. Check your Buys tables productid there is no entry for product id 3. When you want to buy product 3 for user id 3 then buy table productid entry should be three for userid 3.
Now check the below query it will definitely work for you.
SELECT * FROM Product
INNER JOIN buy ON Product.id = buy.Product_id
WHERE buy.userid = '3';
It means you want to get product buy by userid 3.
Try This
DECLARE #USER_ID INT=3 --I/P of USER_ID
SELECT P.ID,
P.NAME,
P.PRICE,
P.Discount,
B.user_id,
B.PRODUCT_ID,
B.CARD_DETAILS
FROM #PRODUCT P
JOIN #BUY B
ON P.ID = B.ID
WHERE B.USER_ID = #USER_ID
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;