I have this query, but it gives me duplicate values in row
select products.name, products.image, products.image_second,
products.description, products.min_order, size_categories.size_id,
products.id,
GROUP_CONCAT( product_prices.price order by FIND_IN_SET(sizes.id, size_categories.size_id)) as price,
GROUP_CONCAT( sizes.name order by FIND_IN_SET(sizes.id, size_categories.size_id) ) as sizes_name,
units.name as units_name
from `products`
inner join `subcategories` on `products`.`subcategories_id` = `subcategories`.`id`
inner join `size_categories` on `subcategories`.`categories_id` = `size_categories`.`categories_id`
inner join `sizes` on FIND_IN_SET(sizes.id, size_categories.size_id) > '0'
inner join `units` on `units`.`id` = `products`.`units_id`
inner join product_prices on product_prices.products_id = products.id
where `products`.`id` = '1'
group by `products`.`name`, `products`.`image`,
`products`.`image_second`,
`products`.`description`, `products`.`min_order`,
`size_categories`.`size_id`, `products`.`id`
The result is like this
------ size_id | id | price | sizes_name
------ 1,2 1 43,32,43,32 2m,2m,3m,3m
32 is the price of 2m, and 43 is the price of 3m.
I need it in a single row and also i need to maintain the order (it should be like 32,43 and not like 43,32)
like
------ size_id | id | price | sizes_name
------ 1,2 1 32,43 2m,3m
Please Help
You missed the condition:
...and product_prices.size_id = sizes.id
when you join product_prices.
With this condition you don't need DISTINCT inside GROUP_CONCAT() for this sample data, although it may be needed for your actual data:
select products.name, size_categories.size_id, products.id,
GROUP_CONCAT(product_prices.price order by FIND_IN_SET(sizes.id, size_categories.size_id)) as price,
GROUP_CONCAT(sizes.name order by FIND_IN_SET(sizes.id, size_categories.size_id)) as sizes_name
from products
inner join subcategories on products.subcategories_id = subcategories.id
inner join size_categories on subcategories.categories_id = size_categories.categories_id
inner join sizes on FIND_IN_SET(sizes.id, size_categories.size_id)
inner join product_prices on product_prices.products_id = products.id and product_prices.size_id = sizes.id
where products.id = '1'
group by products.name, size_categories.size_id, products.id;
See the demo.
Results:
> name | size_id | id | price | sizes_name
> :--- | :------ | -: | :---- | :---------
> PR1 | 1,2 | 1 | 32,43 | 2m,3m
Related
Please help me with the MYSQL query.
Entity Name: OrderItem
Attributes: orderId(PK), orderItemSeqId(PK), productId
Entity Name: ProductFacility
Attributes: facilityId(PK), productId(PK), inventoryCount (Integer)
**OrderId | orderItemSeqId | productId**
OID1 | 0001 | 10000
OID1 | 0002 | 10001
OID1 | 0003 | 10002
**FacilityId | ProductId | InventoryCount**
FC_1 | 10000 | 12
FC_1 | 10001 | 5
FC_1 | 10002 | 7
FC_2 | 10001 | 1
FC_2 | 10002 | 6
FC_3 | 10002 | 7
Here I want to fetch the facility (FC_1) which has all the products available for order.
I don't want the facility records which has partial products (like facility FC_3 has only one (10002) product from order OID1)
I only want the facilityId records which have all the products from the order (ex OID1)
IMPORTANT POINT: This SQL will be executed on millions of records.
Try this:
select *
from ProductFacility f1
where (select count(distinct InventoryCount) cnt_fac
from ProductFacility f2
where f2.FacilityId = f1.FacilityId
and InventoryCount > 0
group by FacilityId ) = (select count(distinct productId)
from OrderItem );
Here is a DEMO
This will get you the facilities you are looking for
with cte as
(
select OrderId, count(*) as c
from orderT a
group by OrderId
)
select FacilityId, b.OrderId, count(*) as c from Facility a
inner join orderT b on a.ProductId = b.ProductId
group by FacilityId, b.OrderId
having count(*) = (select c from cte c where c.OrderId = b.OrderId)
To get a list of which facilities can satisfy an order, you need to check which facility has InventoryCount > 0 for each product in the order, which you can do with this query:
SELECT O.OrderId, F.FacilityID
FROM (SELECT DISTINCT productId
FROM OrderItem) P
CROSS JOIN (SELECT DISTINCT OrderId
FROM OrderItem) O
CROSS JOIN (SELECT DISTINCT FacilityId
FROM ProductFacility) F
LEFT JOIN OrderItem OI ON OI.OrderId = O.OrderID AND OI.productId = P.productId
LEFT JOIN ProductFacility PF ON PF.FacilityId = F.FacilityId AND PF.productId = OI.productId AND PF.InventoryCount > 0
GROUP BY O.OrderId, F.FacilityID
HAVING COUNT(OI.ProductId) = COUNT(PF.ProductId)
I have added an additional order to my demo which requires products 10001 and 10002; for that the output is
OrderId FacilityID
OID1 FC_1
OID2 FC_1
OID2 FC_2
Demo on SQLFiddle
This should work:
select oc.orderId, ofc.facilityId
from
(
select orderId, count(*) productCount
from OrderItem
group by orderId) oc
inner join
(
select pf.facilityId, oi.orderId, count(*) productsAvailableCount
from ProductFacility pf
inner join OrderItem oi on oi.productId = pf.productId and pf.inventoryCount > 0
group by pf.facilityId, oi.orderId
) ofc on ofc.orderId = oc.orderId and oc.productCount = ofc.productsAvailableCount
Demo on DB Fiddle
I have 3 tables, products, productscategories and categories.
The productscategories is a many to many table with only id numbers of the other two tables.
The result without the group by looks like this:
id | Url | Category
-------------------------------------
1 | http://example.com/12 | hat
2 | http://example.com/12 | shoe
3 | http://example.com/13 | hat
4 | http://example.com/13 | jacket
5 | http://example.com/14 | hat
6 | http://example.com/14 | socks
Now I want to exclude every row with the same url if it contains any of the choosen categories, in this case jacket and shoe.
The unwanted result looks like this:
id | Url | Category
-------------------------------------
1 | http://example.com/12 | hat
3 | http://example.com/13 | hat
5 | http://example.com/14 | hat
Because url with id 13 includes jacket I don't want it there. Same goes for url with 14 which includes shoe.
This accur because I have multiple categories and multiple urls that are not aware of each other.
The sql for the above:
SELECT * FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
WHERE categories.slug NOT IN (
'shoe',
'jacket',
)
GROUP BY products.image_url
The wanted result:
id | Url | Category
-------------------------------------
5 | http://example.com/14 | hat
How can I make an sql query that makes url aware of the category, like above?
SELECT * FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
GROUP BY products.image_url
HAVING sum( categories.slug IN('shoe','jacket') )=0
categories.slug IN('shoe','jacket') - return 1 if category in set or 0 if not. sum() - return count of shoe/jacket in group. HAVING filter group with shoe/jacket in it.
Suggestion 1: WHERE NOT EXISTS
SELECT * FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
WHERE NOT EXISTS(
SELECT 1
FROM products p2
JOIN productscategories pc2 ON p2.id = pc2.product_id
JOIN categories c2 ON c2.id = pc2.category_id
WHERE c2.slug IN ('shoe','jacket')
AND p2.url = products.url
)
Suggestion 2: OUTER JOIN
SELECT * FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
LEFT OUTER JOIN products p2 ON products.url = p2.url
LEFT OUTER JOIN productscategories pc3 ON p2.id = pc2.product_id
LEFT OUTER JOIN categories c2 ON c2.id = pc2.category_id AND c2.slug IN ('shoe','jacket')
WHERE c2.id IS NULL
Try this:
SELECT * FROM (
SELECT * FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
) AS A
LEFT JOIN
(
SELECT Url FROM products
JOIN productscategories ON products.id = productscategories.product_id
JOIN categories ON categories.id = productscategories.category_id
WHERE Categories.slug IN ('jacket', 'shoe')
GROUP BY url
) B ON B.url = A.url
WHERE B.url IS NULL
I have tables
table_order
product_name
Below is the SQL I have to query table_order which works perfectly in outputting the product_id but I need it to show it's name and not number. I need to modify mySQL with a LEFTJOIN to somehow connect with table product_name but I keep getting an error. So instead of
99 = 15, 99 = 16
I need
99 = name1, 99 = name2
SELECT table_order.order_id, table_order.product_id
FROM table_order
WHERE table_order.order_id=99
ORDER BY table_order.order_product_id
table table_order
_________________________
order_id | product_id |
_________________________
99 | 15 |
99 | 16 |
_________________________
table product_name
___________________________
product_id | product_name |
___________________________
15 | name1 |
16 | name2 |
___________________________
Use
SELECT a.product_id, b.product_name
FROM table_order AS a LEFT JOIN product_name AS b ON a.product_id = b.product_id
WHERE a.order_id = '99'
ORDER BY a.product_id
You need to join the tables, as you say, on product_id.
SELECT table_order.order_id, product_name.product_name
FROM table_order
INNER JOIN product_name on table_order.product_id = product_name.product_id
WHERE table_order.order_id=99
ORDER BY table_order.product_id
Select t1.product_id,t2.product_name from table_order as t1
inner join(
select * from product_name
) as t2
on t1.product_id = t2.product_name
where t1.product_id = //some Number
See if that works.
If you need to output all the orders regardless of whether the product id of that table_order has a connection to product_table, you need to use LEFT JOIN.
SELECT o.order_id, p.product_name
FROM table_order o
LEFT JOIN product_name p ON o.product_id = p.product_id
ORDER BY o.product_id
However if you just need to get all the rows that exists in both tables, you can use an INNER JOIN
SELECT o.order_id, p.product_name
FROM table_order o
INNER JOIN product_name p ON o.product_id = p.product_id
ORDER BY o.product_id
I have a query like this
SELECT o.product_id,
p.name,
count(o.product_id) AS total_products_sold,
(SELECT count(o.id)
FROM ebay.`order` o) AS total_orders
FROM ebay.`order` o
INNER JOIN product p ON o.product_id = p.id
GROUP BY o.product_id
The total_orders is rerun when executed for each which not i want. I
Question:
I want the total_orders combines with every result set from the outer query.
I tried this but it only return 1 row
SELECT tps.product_id,
tps.name,
tps.total_products_sold,
count(oo.id) AS total_orders
FROM ebay.`order` oo
INNER JOIN
( SELECT o.id,
o.product_id,
p.name,
count(o.product_id) AS total_products_sold
FROM ebay.`order` o
INNER JOIN product p ON o.product_id = p.id
GROUP BY o.product_id ) AS tps ON oo.product_id = tps.product_id
Any better solution ?
Thanks.
You can use with rollup which will give you the total without changing the actual query
It wont give you the result in column of every row but you will get the result of total orders in the last row.
SELECT
o.product_id,
p.name,
count(distinct o.id) AS totalorder
FROM
ebay.`order` o
INNER JOIN
product p
ON
o.product_id = p.id
GROUP BY
o.product_id
WITH ROLLUP
For example
+-----------+------+------------+
| product_id| name | totalorder |
+-----------+------+------------+
| 2000 | A | 10 |
| 2001 | B | 20 |
| NULL | NULL | 30 | <--- Last row is having the Total order
+-----------+------+------------+
WITH ROLLUP
SELECT tps.product_id,
tps.name,
tps.total_products_sold,
s.total_orders
FROM ebay.`order` oo
INNER JOIN
(
SELECT o.id,
o.product_id,
p.name,
count(o.product_id) AS total_products_sold
FROM ebay.`order` o
INNER JOIN product p
ON o.product_id = p.id
GROUP BY o.product_id
) AS tps ON oo.product_id = tps.product_id
CROSS JOIN
(
SELECT count(id) total_orders
FROM ebay.`order`
) s
I am trying to achieve total number of topics, total number of posts, and last post for given section, please find db structures and query as following...
fcats
| id | title | section |
+----+--------+---------+
| 1 | test | gd |
+----+--------+---------+
ftopics
| id | title | cat_id |
+----+--------+---------+
| 1 | test1 | 1 |
+----+--------+---------+
fposts
| id | post | topic_id | posted_by
+----+-------+----------+---------+
| 1 | post | 1 | user |
+----+-------+----------+---------+
current query
SELECT id,
title ,
(SELECT count(id)
FROM ftopics
WHERE cat_id = id) AS total_topics
FROM fcats
WHERE section = "gd"
by using above query, i could only get total_topics for given section, but i am confused about how to get total number of posts, and last post for given section. please help, thanks.
SELECT A.id section_id,
IFNULL(COUNT(DISTINCT B.id),0) topics_count,
IFNULL(COUNT(C.id),0) post_count,
(SELECT post from fposts where id = MAX(C.id)) last_post
FROM fsections A LEFT JOIN ftopics B
ON A.id = B.cat_id
LEFT JOIN fposts C
ON C.topic_id = B.id
WHERE A.section = "gd"
GROUP BY A.id
Also include the null case if the section doesnot have any post
Maybe something like this:
SELECT
id,
title ,
(
SELECT
count(ftopics.id)
FROM
ftopics
WHERE
ftopics.cat_id = fcats.id
) AS total_topics,
(
SELECT
COUNT(distinct fposts.id)
FROM
ftopics
JOIN fposts
ON ftopics.id=fposts.topic_id
WHERE
ftopics.cat_id = fcats.id
),
(
select
fposts.id
from fposts
inner join ftopics on fposts.topic_id = ftopics.id
inner join fcats c2 on c2.id = ftopics.cat_id
where fcats.id = c2.id
order by fposts.id desc
limit 1
) as last_post_id
FROM fcats
WHERE section = "gd"
For first part of your answer you should use count distinct, and for second part a subquery:
SELECT c.id,
c.title ,
count( distinct t.cat_id) AS total_topics ,
count( distinct p.id) AS total_posts ,
(select p2.id
from ne_forum_posts p2
inner join ne_forum_topics t2 on p2.topic_id = t2.id
inner join ne_forum_sub_cats c2 on c2.id = t2.cat_id
where c2.id = c.id
order by p2.id desc
limit 1) as last_post_id
FROM ne_forum_sub_cats c LEFT OUTER JOIN
ne_forum_topics t on c.id = t.cat_id LEFT OUTER JOIN
ne_forum_posts p on p.topic_id = t.id
WHERE section = "gd"
all typos fixed and tested.