Mysql - if value doesn't exists use another table - php

what I'm trying to do is run a query to display all products
customers may have discounts for(when they log in) or it just uses the standardTermsPricing:
tables are:
product want to display all
manufacturer, productRange, webcode, description, supplierCode, priceExVat etc
standardTermsPricing (this doesn't contain any userid)
supplier , supplierCode , Amount
supplierdiscounts
supplier(supplierCode) , user , Amount
productdiscounts
user ,product (webcode) , Amount ``
I know user y127 is working at some level but if I try one z999 this isn't in table supplierdiscounts or productDiscounts so no results.
my current select statement doesn't really work it gets some results but not what I want... any ideas??
end result I'm using a PHP mysqli_query to loop results to display to customer and export a CSV file - but that's another issue!!
many thanks, Ian
SELECT
p.name,
p.manufacturer,
p.productRange,
p.webcode,
p.description,
p.supplierCode,
p.priceExVat,
stp.amount 'standard discount amount',
sd.amount 'supplier discount amount',
pd.amount 'product discount amount',
sd.user
FROM
products p
JOIN standardTermsPricing stp ON p.supplierCode = stp.supplierCode
JOIN supplierdiscounts sd ON p.supplierCode = sd.supplier
JOIN productDiscounts pd ON p.webcode = pd.product
WHERE sd.user = 'Y127'

JOIN is the same as an INNER JOIN so only matching combinations are returned. If you want all rows, also when there are no matching rows in the discounts tables, you need for example a LEFT JOIN:
...
FROM
products p
INNER JOIN standardTermsPricing stp
ON p.supplierCode = stp.supplierCode
LEFT JOIN supplierdiscounts sd
ON p.supplierCode = sd.supplier
LEFT JOIN productDiscounts pd
ON p.webcode = pd.product
WHERE sd.user = 'Y127'

fixed it, many thanks - we had some duplicate products in the db.
SELECT
p.name,
p.manufacturer,
p.productRange,
p.webcode,
p.description,
p.supplierCode,
p.priceExVat,
sd.amount sdamount,
pd.amount pdamount,
stp.amount stpamount
FROM products p
INNER JOIN standardTermsPricing stp ON p.supplierCode = stp.supplierCode
LEFT JOIN supplierdiscounts sd ON p.supplierCode = sd.supplier AND sd.user = 'C456'
LEFT JOIN productDiscounts pd ON p.webcode = pd.product AND sd.user = 'C456'
WHERE sd.user = 'C456'
UNION
SELECT
p.name,
p.manufacturer,
p.productRange,
p.webcode,
p.description,
p.supplierCode,
p.priceExVat,
NULL,
NULL,
stp.amount stpamount
FROM products p
INNER JOIN standardTermsPricing stp ON p.supplierCode = stp.supplierCode

Related

Improve this query with use of union

This query gives an error if subquery return more than 1 row. I separated the queries and use mysqli_multi_query(), but both queries data is displayed in two tables.
So I decided to make the one query.
SELECT DISTINCT category ,
(SELECT COUNT(products.name)
FROM products
where category_id=categories.id
) AS total_products,
(
SELECT SUM(quantity) FROM productstock a
LEFT JOIN products b ON a.product_id=b.id
LEFT JOIN categories c ON b.category_id=c.id
where c.deleted=0
GROUP BY category_id
) AS available_stock,
SUM(product_qty*orignalCost) AS SaleWise_cost,
SUM(product_qty*saleprice) AS SaleWise_price,
SUM(product_qty*saleprice) AS total_sale ,
SUM((product_qty*saleprice)-(product_qty*orignalCost)) AS profit
FROM categories
INNER JOIN products ON categories.id = products.category_id
INNER JOIN sales ON sales.product_id = products.id
INNER JOIN productstock ON productstock.product_id = products.id
WHERE categories.deleted=0
GROUP BY category_id
As available stock is corelated subquery so joining condition must be added in where clause inside subquery. please check this pseudocode
(
SELECT SUM(quantity) FROM productstock a
LEFT JOIN products b ON a.product_id=b.id
LEFT JOIN categories c ON b.category_id=c.id
where c.deleted=0 AND b.category_id = categories.id
) AS available_stock
Another way
(SELECT SUM(quantity)
FROM products b
INNER JOIN productstock a
ON b.id = a.product_id
AND b.id = products.id
AND b.category_id = categories.id) AS available_stock

MySQL join with specific WHERE clause

I have a simple database
With this query I get all users and number of products they have bought:
SELECT
c.id,
cd.name,
cd.surname,
COUNT(p.name) as bought
FROM shopping s
JOIN client c ON s.client_id = c.id
JOIN client_details cd ON c.id = cd.client_id
JOIN product p ON s.product_id = p.id
GROUP BY c.id;
It's pretty good, but I have to select all users and number of specific products bought. With this query I get it only if the user have bought at least one product:
SELECT
c.id,
cd.name,
cd.surname,
COUNT(p.name) as bought
FROM shopping s
JOIN client c ON s.client_id = c.id
JOIN client_details cd ON c.id = cd.client_id
JOIN product p ON s.product_id = p.id
WHERE p.name = 'sugar'
GROUP BY c.id;
I want to get the list with all users, and if specific user didn' buy specific product, there should be 0 on output.
Use condition aggregation:
SELECT c.id, cd.name, cd.surname,
MAX(p.name = 'sugar') as SugarFlag
FROM shopping s JOIN
client c
ON s.client_id = c.id JOIN
client_details cd
ON c.id = cd.client_id JOIN
product p
ON s.product_id = p.id
GROUP BY c.id;

Combine two MySql into one query

I have two sql queries that I need to combine into one query for better efficiency, just not sure how to do it. Basically I need to query my Supplier, then for each supplier check to see if the Listing table has more than one record that matches based upon "supplier id", if it does then I need to return the supplier name and id. Here are my two queries:
Query 1:
SELECT s.name, s.id
FROM Supplier s
Query 2:
SELECT l.asin,
l.id,
COUNT(*) c
FROM Listing l
LEFT JOIN Product p
ON p.id = l.product_id
LEFT JOIN Supplier s
ON p.supplier_id = s.id
WHERE (l.matchValidated IS NULL OR l.matchValidated = 0)
AND s.id = SUPPLIER_ID_GOES_HERE
GROUP BY l.asin HAVING c > 1);
You already have supplier joined in the second query so you just need to add the supplier name and id to your SELECT and GROUP BY.
SELECT l.asin,
l.id,
s.name AS supplier_name,
s.id AS supplier_id,
COUNT(*) c
FROM Listing l
LEFT JOIN Product p
ON p.id = l.product_id
LEFT JOIN Supplier s
ON p.supplier_id = s.id
WHERE (l.matchValidated IS NULL OR l.matchValidated = 0)
GROUP BY l.asin, l.id, s.name, s.id
HAVING c > 1;

Show null results when left join don't find match

I have problem with join left. It work fine but i don't see null results. It connects three tables - categories, product_categories and order_products.
Query made by stack user look's like:
SELECT
categories.name,categories.id,
SUM((orders_products.product_price_gross + orders_products.option_price)*(1 - (orders_products.rebate/100)) * orders_products.product_qty) as suma
FROM orders_products
LEFT JOIN product_categories
ON product_categories.product_id = orders_products.product_id
LEFT JOIN categories
ON product_categories.category_id = categories.id
GROUP BY categories.name, categories.id
ORDER BY suma DESC
I'm not sure how upgrade this query - I need to see what never been sold to show on shop statistics.
I hope You could help me.
Kind regards
Mark
You want to see products that has not been sold? Your main table is the transaction table orders_products. So any product not "ordered" will not show. Interchange product_categories and orders_products to achieve what you want. This will list all categories and null out the "suma" if JOIN statement cannot find the product_id listed in the "order_products" table
SELECT
categories.name,
categories.id,
SUM((orders_products.product_price_gross + orders_products.option_price)*(1 - (orders_products.rebate/100)) * orders_products.product_qty) AS suma
FROM product_categories
LEFT JOIN orders_products
ON product_categories.product_id = orders_products.product_id
LEFT JOIN categories
ON product_categories.category_id = categories.id
GROUP BY categories.name, categories.id
ORDER BY suma DESC

Query Returns Duplicate Products Based On Category

I have a mysql query that joins 5 different tables to return specific properties of products. It should return each product only one time. But since the product may have multiple categories it's returning the products once for each category.
Here's the select:
SELECT DISTINCT
pd.name AS pname,
p.price AS price,
cd.name AS cname,
pd.description AS pdescription,
pd.language_id AS language_id,
pd.product_id AS product_id,
p.model AS model,
p.sku AS sku,
p.upc AS upc,
m.name AS brand
FROM {$this->prefix}product_description pd
LEFT JOIN {$this->prefix}product_to_category pc
ON (pd.product_id = pc.product_id)
INNER JOIN {$this->prefix}product p
ON (pd.product_id = p.product_id)
LEFT JOIN {$this->prefix}category_description cd
ON (cd.category_id = pc.category_id
AND cd.language_id = pd.language_id)
LEFT JOIN {$this->prefix}manufacturer m
ON (m.manufacturer_id = p.manufacturer_id)
If a given product, say product_id 32 is assigned to more than one category, it will return product_id 32 once for each category, the only difference being the result cname being the category name.
If someone could help rework the select to only include each product once, no matter the category I would appreciate the help.
It would also be helpful to have the category returned to be the MAX() category_id for the product, but not a huge deal if that's too much to ask.
Thank you.
If you use GROUP BY, you can get each product once irrespective of the category:
SELECT DISTINCT
pd.name AS pname,
p.price AS price,
cd.name AS cname,
pd.description AS pdescription,
pd.language_id AS language_id,
pd.product_id AS product_id,
p.model AS model,
p.sku AS sku,
p.upc AS upc,
m.name AS brand
FROM {$this->prefix}product_description pd
LEFT JOIN {$this->prefix}product_to_category pc
ON (pd.product_id = pc.product_id)
INNER JOIN {$this->prefix}product p
ON (pd.product_id = p.product_id)
LEFT JOIN {$this->prefix}category_description cd
ON (cd.category_id = pc.category_id AND cd.language_id = pd.language_id)
LEFT JOIN {$this->prefix}manufacturer m
ON (m.manufacturer_id = p.manufacturer_id)
GROUP BY product_id;
For getting the MAX() category, you can try and apply this MAX function on the column that you want. I guess in this case it would be MAX(cd.name) AS cname.
For more info on GROUP BY you can go through the following manual page:
https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
most likely it is because you are using an INNER JOIN between product_to_category and product
inherently an inner join will make as many connections as possible, where a left join will limit the yielded results to the elements in the first (left) table.

Categories