SQL: How select rows and minus from another table - mysql

how construct sql query to select rows from table "Product" and minus sum(pc) from another table "Order".
Here is schema.
Thanks!

Group your orders by the product to get the sum of the pc-column for the products.
Then join the sum onto your product table, subtract the sum of the orders from your pc-column in the product table.
SELECT
product.id_product,
(product.pc - ifnull(orders.amount, 0))
FROM
product
LEFT JOIN (
SELECT
id_product,
SUM(pc) AS amount
FROM
`Order`
GROUP BY
id_product
) AS orders ON orders.id_product = product.id_product

Related

Creating a percentage column on a table made from an inner join

I have two tables Orders and RMA. I wrote this command to return an inner join between the two tables. OrderID is the primary key of Orders and foreign key of RMA.
SELECT Orders.SKU, COUNT(*) AS Frequency
FROM Orders
INNER JOIN RMA ON Orders.OrderID = RMA.OrderID
GROUP BY Orders.SKU
ORDER BY COUNT(*) DESC;
This select statement returns a table with one column containing SKU values and one column containing the number of times each SKU value appears in the data. My goal is to create a third column that includes a percent that represents the frequency of each SKU value.
(disclaimer: I'm new to mysql, so if there's more information needed for this question, I am happy to provide it. Thanks!)
You must divide COUNT(*) with the total number of rows in RMA:
SELECT Orders.SKU,
COUNT(*) AS Frequency,
COUNT(*) / (SELECT COUNT(*) FROM RMA) AS percent
FROM Orders INNER JOIN RMA
ON Orders.OrderID = RMA.OrderID
GROUP BY Orders.SKU
ORDER BY Frequency DESC;

How to match up dates on 2 different tables and join to an ID table?

I have a table full of product ids and their attributes. I want to join sales data and receipt data from 2 different tables and a different row for each id and date combo. So I want the output to look like this:
I tried joining the product id table and sales table to the receipt table but I'm not sure how to get the dates from the sales and receipts table to match up. Not sure of how to approach this. Thanks!
Calculate the counts for each table and combine them usung UNION ALL
select
product_id
,sales_date
-- combine the counts from both tables
,sum(sales_count)
,sum(receipt_count)
from
(
-- get the counts for the sales table
select
product_id
,sales_date
,count(*) as sales_count
-- UNION needs the same number of columns in both Select -> adding a dummy column
-- 1st Select determines the datatype
,cast(0 as int) as receipt_count
from sales
group by product_id, sales_date
UNION ALL
-- get the counts for the receipts table
select
product_id
,receipt_date
,0
,count(*)
from receipts
group by product_id, receipt_date
) as dt
group by product_id, receipt_date
select p.product_id, s.sales_date, s.sales_count, r.receipt_count
from
products p,
(select count(*) sales_count, sales_date, product_id from sales group by 2,3) s
(select count(*) receipt_count, receipt_date, product_id from receipts group by 2,3) r
where
p.product_id = s.product_id
and p.product_id = r.product_id
and s.sales_date=r.receipt_date
;

Get the max column value for each unique ID

I have two tables, a customers and orders table.
The customers table contains a unique ID for each customer. It contains 1141 entries.
The orders table contains many entries with a customerID and a date.
I am trying to query my database and return a list of customers and the max(date) from the orders list.
SELECT *
FROM customers
INNER JOIN
(
SELECT CustomerID, max(date) as date
FROM orders
GROUP BY CustomerID
) Sub1
ON customers.id = Sub1.CustomerID
INNER JOIN orders
ON orders.CustomerID = Sub1.CustomerID
AND orders.date = Sub1.Date
However this query is returning 1726 rows instead of 1141 rows. Where is this getting extra from?
I think it's beacause ORDERS table contains same customerID multiple times, so when you join the table with CUSTOMERS, each CUSTOMER.id matches multiple rows of ORDERS.
The problem is that there are ties.
For a given customer, some place more than one order per day. So there's a possibility that occasionally some may have placed more than one order on the date that is their max date.
To fix this, you need to use MAX() or some column that is always unique in the Orders table (or at least unique within a given date). This is easy if you can depend on an auto-increment primary key in the Orders table:
SELECT *
FROM customers
INNER JOIN
(
SELECT CustomerID, max(orderid) as orderid as date
FROM orders
GROUP BY CustomerID
) Sub1
ON customers.id = Sub1.CustomerID
INNER JOIN orders
ON orders.CustomerID = Sub1.CustomerID
AND orders.orderid = Sub1.orderid
This assumes that orderid increases in lock-step with increasing dates. That is, you'll never have an order with a greater auto-inc id but an earlier date. That might happen if you allow data to be entered out of chronological order, e.g. back-dating orders.
;with cte as
(
select CustomerID, orderdate
, rn = row_number() over (partition by customerID order by orderdate desc)
from orders
)
select c.*, cte.orderdate
from customer c
join cte on cte.customerID = c.customerid
where rn =1 -- This will limit to latest orderdate

SQL summery queries

I am having trouble getting the correct answer. My results are returning the same amount for all fields.
Please keep in mind that I am a newbie to SQL
Write a SELECT statement that returns one row for each customer that has orders with these columns:
The email_address column from the Customers table
The sum of the item price in the Order_Items table multiplied by the quantity in the Order_Items table
The sum of the discount amount column in the Order_Items table multiplied by the quantity in the Order_Items table
Sort the result set in descending sequence by the item price total for each customer. 
This is my code
SELECT email_address,
SUM(item_price * quantity) AS item_price_total
SUM(discount_amount * quantity) AS discount_amount_total
FROM customers c JOIN order_items oi
GROUP BY email_address
Order BY item_price_total
You need a join condition to relate the two tables. Otherwise, you just get a full cross-product.
SELECT email_address,
SUM(item_price * quantity) AS item_price_total
SUM(discount_amount * quantity) AS discount_amount_total
FROM customers c JOIN order_items oi ON c.id = oi.customer_id
#^^^^^^^^^^^^^^^^^^^^^^^^
GROUP BY email_address
Order BY item_price_total
I'm just guessing the names of the columns that relate the two tables, you should replace them with the actual columns.

MySQL Join to show all rows

I have two MySQL tables with the following structure:
TABLE `orders`
order_id
order_date
product_id
TABLE `products`
product_id
product_name
product_price
product_type
I want to show all rows from table orders and if there is a product_id in TABLE products show all data of that product. If there isn't, show all data from orders table only.
I tried this:
SELECT * FROM orders AS o RIGHT JOIN products AS p ON o.product_id=p.product_id
But if we have a row with a product_id inside orders table that doesn't exist in products table, then the row from orders is not showed. I want the row from orders id to show no matter if there is a product_id inside products table. If there is JOIN it, if it isnt show just the data from table orders.
Any suggestions?
You should be doing a LEFT JOIN
With a left join, all rows from ORDERS will be returned. The columns from the products table will be null if the criteria for the join is not met.
SELECT o.*,p.*
FROM orders AS o
LEFT JOIN products AS p
ON o.product_id=p.product_id`
See the MySQL manual join syntax