How to reduce query time of the sql statement,mysql - mysql

Here is the sql(mysql):
Table product and product_sale_app
it will pass in two parameters,appkey is the attribute of table product_sale_app;category is the attribute of table product.I need get effect_date,product_id,name from table product and use the above conditions.
SELECT effect_date,
product_id,
name
FROM product
WHERE product_id IN
(SELECT product_id
FROM product_sale_app
WHERE appkey =88888
AND product_id IN
(SELECT product_id
FROM product
WHERE category =1 ) )

Instead of sub queries, JOIN the tables using product_id and then put conditions inside the WHERE clause.
Try the following:
SELECT p.effect_date,
p.product_id,
p.name
FROM product AS p
JOIN product_sale_app AS psa ON psa.product_id = p.product_id
WHERE p.category = 1 AND psa.appkey = 88888

Related

Sql query using joins to find sum of quantity

Here,in billtran table the productid=1 is repeated twice
I want to find the sum(billtran.quantity) of each productid separately
select Query1:
select name,billtran.quantity from product inner join billtran on product.id=billtran.productid where product.id in(select id from product)
Per comment:
select name, SUM(billtran.quantity) from product inner join billtran on product.id=billtran.productid where product.id in(select id from product)
GROUP BY NAME
My additions in caps
Note: where product.id in(select id from product) is an entirely useless where clause and should be removed. Queries don't have to have a where clause and don't need one that says a table id should be in all the ids in that table (always true)
I would hence have written this one as:
SELECT
p.name,
SUM(b.quantity) as sumof_quantity
FROM
product p
INNER JOIN billtran b ON p.id=b.productid
GROUP BY
p.name
Very simple query. Pls check below:
select product.name,sum(billtran.quantity) from product inner join billtran on product.id=billtran.productid group by billtran.productid
First of all you have to get the sum of the quantity according to the product_id
SELECT product.name, SUM(billtran.quantity) AS value_sum
FROM billtran inner join product on product.id= billtran.product_id where product.id in(select id from product )
GROUP BY product_id;
This will be the result:
name quantity
abc 6
xyz 1
pqt 3
You can get the same result by grouping the product.name as well:
SELECT product.name, SUM(billtran.quantity) AS value_sum
FROM billtran inner join product on product.id=billtran.product_id where product.id in(select id from product)
GROUP BY product.name;

Get cheapest price for a product

I have two tables: products and prices
products
id (PK)
name
prices
id (PK)
product_id (FK > products)
price
originalPrice
Each product might have multiple prices. What I want to achieve is a query that returns me all products on-sale with its cheapest price.
on-sale = price < originalPrice
if a product is not on-sale, it should not be included in the results
if a product has multiple prices that qualify for on-sale, only return the cheapest price.
The resulting table should have these columns
products.id
products.name
prices.id
prices.price
prices.originalPrice
With my attempts I'm ending up with this issue: #1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'tbl.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by. Please note that I cannot change the config.
MySQL version: 5.7.22
I have uploaded a SQL export with sample data here: https://www.dropbox.com/s/6ucdv6592dum6n6/stackoverflow_export.sql?dl=0
select pro.name, MIN(pri.price) from products pro
inner join price pri on pri.product_id = pro.id
where pri.price < pri.originalPrice
group by pro.name
heres a shot without any data :p may need a little tweaking
Try this:
SELECT *
FROM `products` pro
JOIN price pri on pri.productId = pro.id
WHERE pri.price < pri.originalPrice
AND pri.price =
(
SELECT min(p.price)
FROM price p
WHERE p.productId = pro.id AND p.price < p.originalPrice
)
Hope this works for you
SELECT *,MIN(price) FROM (
SELECT name, products.id,price
FROM products
INNER JOIN productItems
ON products.id = productItems.productId
WHERE price < originalPrice
ORDER BY (price-originalPrice)
) as tbl GROUP BY id;
OR
SELECT *,MIN(diff) FROM (
SELECT name, products.id,price,(price-originalPrice) as "diff"
FROM products
INNER JOIN productItems
ON products.id = productItems.productId
WHERE price < originalPrice
ORDER BY products.id,(price-originalPrice)
) as tbl GROUP BY id;
This works with that dropbox link you gave: http://sqlfiddle.com/#!9/a6306d/3
select pro.name, MIN(pri.price) from products pro
inner join price pri on pri.productId = pro.id
where pri.price < pri.originalPrice
group by pro.name

Pull data from 3 tables

I have 3 tables as follows :
Table 1: Product
id_product [Primary Key],added_time.
Table 2: Category
id_category [Primary Key],Category_name.
Table 3: product_category
id_category,id_product [Both Foreign Keys]
I want to pull Data as
Category_name,No Of Products in this Category,Last time when product was added to Category(Latest product added_time).
You could use this SQL:
SELECT Category.Category_name,
Count(DISTINCT Product.id_product) AS num_products,
Max(Product.added_time) last_added_time
FROM Category
LEFT JOIN product_category
ON product_category.id_category = Category.id_category
LEFT JOIN Product
ON Product.id_product = product_category.id_product
GROUP BY Category.Category_name;
Note that by using LEFT JOIN you will be certain to list all categories even those for which no products exist. If you don't want those, replace both LEFT keywords with INNER.
Note also that in standard SQL you need to GROUP BY any columns you mention in the SELECT list, unless they are aggregated, like with MAX or COUNT.
SELECT C.`Category_name`,
(SUM(IF(P.`id_product`IS NULL,0,1))) AS No_of_Products,
MAX(P.`added_time`) AS Latest_time
FROM
Category C
LEFT JOIN
product_category P_C ON C.`id_category` = P_C.`id_category`
LEFT JOIN
Product P ON P.`id_product` = P_C.`id_product`
GROUP BY C.`id_category`
Hope this helps.

mysql check if field value exists in another table

TABLE PRODUCTS
ProductID | ProductCode | SampleRefNum
1 a1
2 b2
3 c2
TABLE STOCK LIST
StockListID | ProductCode | SampleRefNum | QTY
1 a1 10
2 b2 10
3 j100 25
I have to 2 tables. The products tables is the current products on the site.
Stock list table is a list uploaded from the POS system , with products and their quantities.
Products either have a ProductCode or SampleRefNum .
I am trying to generate a list off all items in the product table that do not have a matching ProductCode or SampleRefNum in the stock list table. in the following e.g the query should return ProductID 3 .
I'm trying to do this with a query , instead of looping and checking results in PHP.
Try JOIN these two tables and take products with ProductCode or SampleRefNum is null from STOCK_LIST
select t1.* from PRODUCTS as t1
left join STOCK_LIST as t2 on t1.ProductID = t2.StockListID
where (t2.ProductCode IS NULL or t2.SampleRefNum is NULL)
You can use left join for correct your result.
SELECT p.* FROM products AS p
LEFT JOIN stockList AS s
ON p.productID = s.stockListId
OR p.sampleRefNum = s.sampleRefNum;
Select productId from Products where productId NOT IN(Select p.productId From Products p
INNER JOIN Stocklist s ON ( p.ProductCode=s.ProductCode || p.SampleRefNum=s.SampleRefNum));
I guess that productId and Stocklist Id are not related to each other they are just primary keys of two different tables.
So try above query.
If my guess is wrong comment the same in detail.
select table1.id table2.id from table1,table2 where tpl1.id=tpl2.id
after that check num_rows of return data if total is 0 that mean no things
This is the correct answer. It was part right by #Ye Win and 웃웃웃웃웃
SELECT * FROM products AS p
LEFT JOIN stock_list AS s
ON p.ProductCode = s.ProductCode OR p.SampleRefNum = s.SampleRefNum
WHERE (s.ProductCode IS NULL AND p.ProductCode IS NOT NULL OR s.SampleRefNum IS NULL AND p.SampleRefNum IS NOT NULL)

Joining two tables for the result?

I have 2 tables in a database person and order tables.
PERSON table:
PERSON_ID | NAME
ORDER table:
ORDER_ID | ORDER_NO | PERSON_ID
I need to display all the orders + a name of corresponding person if it exists, if not just order details.
So far I got up to query:
SELECT ORDER_ID, ORDER_NO, order.PERSON_ID, NAME
FROM person, order
WHERE person.PERSON_ID = order.PERSON_ID AND
person.FIRST_NAME IS NOT NULL;
Which gives me orders only if the name is available whereas I need to display all the orders despite the fact if name is available or not.
Any suggestions?
Yes, you can use LEFT JOIN for that:
SELECT o.order_id, o.order_no, o.person_id, p.name
FROM `order` o
LEFT JOIN person p
ON p.person_id = o.person_id AND p.FIRST_NAME IS NOT NULL
With LEFT JOIN if the name is null it will still give you the orders.