I'm having some trouble selecting a distinct order id from my orderItems table.
My orderItems table contains:
orderId | itemId | orderedQuantity | inStockQuantity | backorderQuantity | isBackorderOfId | id.
orderedQuantity is the total ordered amount, inStockQuantity is the quantity available at the time of purchase and backorderQuantity is the rest. isBackorderOfId correlates to the id column when an order item is a backorder of another order item.
My query is trying to select a distinct orderId of entries where the backorderQuantity < a SUM(inStockQuantity) where isBackorderOfId = id. This would result in a list if distinct order ids which have remaining backorders to be shipped.
Test data:
orderId | itemId | orderedQuantity | inStockQuantity | backorderQuantity | isBackorderOfId | id
1 | 114 | 10 | 6 | 4 | 0 | 23
1 | 255 | 4 | 3 | 1 | 0 | 24
2 | 114 | 3 | 3 | 0 | 23 | 25
Query:
SELECT items1.* FROM orderItems items1
LEFT JOIN orderItems items2 ON items2.isBackorderOfId = items1.id
WHERE items1.backorderQuantity > '0'
GROUP BY items2.isBackorderOfId
HAVING SUM(items2.inStockQuantity) < items1.backorderQuantity
OR SUM(items2.inStockQuantity) IS NULL`
This results in both the first and second row which has the same orderId. I can't use SELECT DISTINCT because of the use of aggregate functions.
Any help would be appreciated.
SELECT items1.orderId
FROM orderItems items1
LEFT JOIN
orderItems items2
ON items2.isBackorderOfId = items1.id
GROUP BY
items1.orderId
HAVING COALESCE(SUM(items2.inStockQuantity), 0) < SUM(items1.backorderQuantity)
Related
I have a table like so (I'm not sure how to format tables)
Category / Products / Purchases
1 | A | 12
1 | B | 13
1 | C | 11
2 | A | 1
2 | B | 2
2 | C | 3
Expected output:
1 | B | 13
2 | C | 3
However I keep on getting
1 | A | 13
2 | A | 3
ie. It just selects the first occurrence of the second column.
Here is my code:
SELECT Category, Products, MAX(Purchases) FROM myTable GROUP BY Category;
Use filtering in the where clause:
select t.*
from t
where t.purchases = (select max(t2.purchases) from t t2 where t2.category = t.category);
With NOT EXISTS:
select m.* from myTable m
where not exists (
select 1 from myTable
where category = m.category and purchases > m.purchases
)
See the demo.
Results:
| Category | Products | Purchases |
| -------- | -------- | --------- |
| 1 | B | 13 |
| 2 | C | 3 |
You can use row_number() to identify max purchase for each group or replace rownumber() to rank() if there are ties of max purchases for each group
Select Category, Products,
Purchases from (Select Category,
Products,
Purchases,
row_number() over (partition by
category, products order by
purchases desc) rn from table) t
where t.rn=1
)
I have the following tables:
purchase_tbl
id | productId | purchaseQuantity
---+-----------+-----------------
1 | 1 | 30
2 | 2 | 30
3 | 1 | 10
4 | 2 | 10
sale_tbl
id | productId | saleQuantity
---+-----------+-------------
1 | 1 | 10
2 | 2 | 10
3 | 1 | 10
4 | 2 | 10
5 | 1 | 10
6 | 2 | 10
I need to get the output as this one:
productId | totalPurchasedQuantity| totalSaleQuantity
----------+-----------------------+------------------
1 | 40 | 30
2 | 40 | 30
I'm using this query and how to get the desired result?
SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM purchase_tbl
JOIN sale_tbl
ON purchase_tbl.productId = sale_tbl.productId
GROUP BY purchase_tbl.productId
Current output
productId | totalPurchaseQuantity | totalSaleQuantity
----------+-----------------------+------------------
1 | 120 | 60
2 | 120 | 60
You better group then in separate query, as table have multiple records for each product, which getting cross product.
SELECT purchase.productId, totalPurchaseQuantity, totalSaleQuantity
FROM
(SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
FROM purchase_tbl
GROUP BY purchase_tbl.productId) purchase
INNER JOIN
(SELECT sale_tbl.productId
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM sale_tbl
GROUP BY sale_tbl.productId
) sale ON sale.productId= purchase.productId;
To obtain your expected result you have to do the aggregation on the individual table before joining them. Your query with be like:
SELECT A.productId, A.totalpurchaseQuantity, B.totalsaleQuantity
FROM
(SELECT productId, SUM(purchaseQuantity)
totalpurchaseQuantity FROM purchase_tbl
GROUP BY productId) A JOIN
(SELECT productId, SUM(saleQuantity)
totalsaleQuantity FROM sale_tbl
GROUP BY productId) B ON
A.productId=B.productId;
I have a table (Table1) with the columns order_item_id customer_id and order_id in which I want to count the number of orders per customer. Unfortunately an order with more than one article has the same order_id
|order_item_id|order_id|customer_id|
| 2 | 30 | 1 |
| 3 | 30 | 1 |
| 4 | 42 | 1 |
| 5 | 33 | 2 |
| 11 | 32 | 3 |
| 12 | 33 | 2 |
| 13 | 33 | 2 |
| 19 | 69 | 3 |
Expected Outcome:
|numberOfOrders|customer_id|
| 2 | 1 |
| 1 | 2 |
| 2 | 3 |
I tried this (and many more):
CREATE TABLE X AS
SELECT
customer_id,
COUNT(order_id) AS `numberOfOrders`
FROM Table1 T1
GROUP BY customer_id;
The problem is, that with this solution it counts every article not the number of orders: so the number of orders for customer 1 is 3 (not 2), for customer 2 is 3 (not 1)....
How can I solve this for a big database with Mysql query?
Try the following solution to SELECT your data as expected:
SELECT COUNT(DISTINCT order_id) AS numberOfOrders, customer_id
FROM table1
GROUP BY customer_id
Demo: http://sqlfiddle.com/#!9/ee8f62/1/0
An option could be to do GROUP twice. First GROUP for the number of items per order, wrapped by a second GROUP for the number of orders per customer:
/* second group */
SELECT customer_id
, count(*) AS number_of_orders
FROM (
/* first group */
SELECT order_id
, customer_id
, count(*) AS order_item_count
FROM Table1
GROUP BY order_id, customer_id
) a
GROUP BY customer_id
I have the following table:
+---------+--------------+----------+
| item_id | location_id | price |
+---------+--------------+----------+
| 1 | 1 | 100 |
| 1 | 1 | 250 |
| 1 | 2 | 50 |
| 2 | 1 | 250 |
| 2 | 1 | 1000 |
| 3 | 1 | 1000 |
| 3 | 2 | 100 |
+---------+--------------+----------+
I can reduce this down to the minimum values using this query
SELECT
item_id, location_id, MIN(price) AS Price
from
table
GROUP BY item_id , location_id
This gets me
+---------+--------------+----------+
| item_id | location_id | price |
+---------+--------------+----------+
| 1 | 1 | 100 |
| 1 | 2 | 50 |
| 2 | 1 | 250 |
| 3 | 1 | 1000 |
| 3 | 2 | 100 |
+---------+--------------+----------+
I want to reduce this further. I am using the rows with a location_id of 1 as a reference row. For each row that has an item_id matching the reference row's item_id but a different location id. I want to compare that row's price with the reference row's price. If the price is lower than the reference row's price, I want to filter that row out.
My final result should include the reference row for each item id and any rows that met the criteria of the price being lower than the reference row price.
I have a hunch that I can use the HAVING clause to do this but I am having trouble compiling the statement. How should I construct the HAVING statement?
Thanks in advance
Nah, having can't help you like this, having is for things like you need filter min() result for something
e.g:
select id,min(price) from table where date = '2016-3-18' group by id having min(price) = 50
it will show you the records that min(price)=50
let's back to your case, there are lots of way to do that,
1. left join
select a.item_id,a.location_id,a.price
from table a
left join table b
on a.location_id = b.location_id and a.price > b.price
where b.price is null
2. exists
select a.item_id,a.location_id,a.price
from table a
where exists(
select 1 from
(select location_id,min(price)as price from table group by location_id)b
where a.location_id = b.location_id and a.price = b.price
)
normally i ll recommand you use exists
I have a table containing inventory
ID | Product ID | In_Transit | Quantity | Cumulative Quantity
=====+================+==============+==============+====================
1 | 1 | 0 | 1000 | 1000
2 | 1 | 0 | 1 | 1001
3 | 1 | 1 | 54 | 1055
4 | 1 | 1 | 1 | 1056
So the total inventory for product id 1 is '1056' I get this using a SELECT MAX(ID) subquery join with the table to get its cumulative quantity which is 1056.
I would like to get the Inventory total (subtracting all the amounts in transit)
So 1056 - 54 - 1 = 1001
How would I get this in one query so i get
Product ID | Total Inventory | Inventory on Hand (Excluding in Transit |
===========+=================+=========================================
1 | 1056 | 1001
Also i need to use the cumulative inventory to get the total as opposed to 'SUM', except for summing those in transit because (those not in transit) have a large number of records and they take ages to SUM. I can use it to sum those in transit because there are far fewer records
SELECT
a.product_id
, a.cumulative as total_inventory
, a.cumulative - COALESCE(b.quantity,0) AS inventory_on_hand
FROM table1 a
JOIN
( SELECT MAX(id) AS max_id
FROM table1
GROUP BY product_id
) m ON (m.max_id = a.id)
LEFT JOIN
( SELECT product_id, SUM(quantity)
FROM table1
WHERE in_transit = 1
GROUP BY product_id
) b ON (a.product_id = b.product_id)