First, here's the concise summary of the question:
Is it possible to run an INSERT statement conditionally? Something akin to this:
IF(expression) INSERT...
Now, I know I can do this with a stored procedure.
Now, I want to do that
Let's assume we have the following 3 tables:
products: id, qty_on_hand
orders: id, product_id, qty
roomTable :id,product_id,room_number,booked_status
Now, let's say an order for 20 rooms (product id 2) comes in. We first check total qty of given product_id from orders table as total_qty and total_qty < qty_on_hand if it return true then insert order values and update 1 room after last booked_status='Y' room from roomTable with booked_status ='Y' and give the id of that room .
Problem is that I am not able to make the join query . what i done so far -
INSERT INTO orders(product_id, qty)
SELECT 2, 20 FROM products WHERE id = 2 AND qty_on_hand >= 20
For those of you who need more detail around how this technique works from Mt. Schneiders,
INSERT INTO orders(product_id, qty)
SELECT 2, 20
FROM products
WHERE id = 2 AND qty_on_hand >= 20 + (select sum(qty) from orders where product_id = 2)
What is going on here is that the result of the select statement is hard coded. In this case we are taking INSERT INTO orders(product_id, qty) VALUES(2, 20) and replacing VALUES(2,20) with SELECT 2, 20. The result of the SELECT is hard coded but only returns a value if the condition is met.
I found this article that explains this technique more in depth:
http://boulderapps.co/dont-insert-when-maximum-is-reached
Wouldn't it be something like this?
INSERT INTO orders(product_id, qty)
SELECT 2, 20
FROM products
WHERE id = 2 AND qty_on_hand >= 20 + (select sum(qty) from orders where product_id = 2)
So, it would not insert if the last orders quantity plus quantity from the order being inserted is less or equal whats in hand.
Related
Would like to get the SUM of two specific rows in a table in mysql.
create table people(
id int,
firstname varchar(50),
money int
);
id firstname money
1 david 100
2 jack 200
3 bob 300
Say I want the SUM of row 1(david) and row 3(bob) only. The total should be 400.
I used this query:
SELECT SUM(money)
FROM people
WHERE id = 1 AND 3;
but it turned out to be 100, and not 400 as I expected.
Here's your query. you can use case and in to get this.
select sum(case when id = 1 or id = 3 then money else 0 end) from people
or
select sum(money) from people where id in (1, 3)
The answer given by #Metal is the way to go:
SELECT SUM(money)
FROM people
WHERE id IN (1, 3);
I am mainly posting this to explain why your current query is giving you a sum of 100. The reason is that the WHERE condition:
WHERE id = 1 AND 3
will only ever be true when id = 1, i.e. for David's record. The value 3 is evaluating to true always. So, you simply sum David's record and get a total of 100.
You have to use OR to select both the rows.
SELECT SUM(money)
FROM people
WHERE id = 1 OR id = 3;
you can find like this:
SELECT SUM(money)
FROM people
WHERE id =1
union
SELECT SUM(money)
FROM people
WHERE id =3
You Have to use this way.
SELECT SUM(money) as Money
FROM people
WHERE id Between 1 and 3
I am trying to select max transaction_num from my table tbl_loan and group it by c_id to avoid duplicate of c_id.
here is my query
SELECT * FROM `tbl_loan` WHERE transaction_num IN (SELECT max(transaction_num) max_trans FROM tbl_loan GROUP BY c_id)
and my output is
still have duplicate c_id.
MySQL MAX with GROUP BY clause
To find the maximum value for every group, you use the MAX function with the GROUP BY clause in a SELECT statement.
You use the following query:
SELECT
*, MAX(transaction_num)
FROM
tbl_loan
GROUP BY c_id
ORDER BY MAX(transaction_num);
From the looks of it, and correct me if I'm wrong. The transaction number appears to be sequential per each C_ID whenever a new transaction happens. There is also the "I_ID" column which appears to be an auto-incrementing column which does not duplicate. It appears your transaction number is sequentially 1, 2, 3, etc per C_ID for simple counting purposes, so everyone starts with a 1, and those with more have 2nd and possibly 3rd and more...
So, if this is accurate and you want the most recent per C_ID, you really want the max "I_ID" per C_ID because multiple records will exist with a value of 2, 3, etc...
try this.
SELECT
TL.*
FROM
tbl_loan TL
JOIN ( SELECT C_ID, max(I_ID) maxI_ID
FROM tbl_loan
GROUP BY c_id) MaxPer
on TL.I_ID = MaxPer.MaxI_ID
So, from your data for C_ID = 55, you have I_ID = 61 (trans num = 1) and 62 (trans num = 2). So for ID = 55, you want the transaction I_ID = 62 which represents the second transaction.
For C_ID = 70, it has I_IDs of 77 & 78, of which will grab I_ID = 78.
The rest only have a single trans num and will get their only single entry id.
HTH
Think about it like this
Your query:
SELECT * FROM `tbl_loan` WHERE transaction_num IN (SELECT max(transaction_num) max_trans FROM tbl_loan GROUP BY c_id)
Lets say your subquery returns one transaction_num of 20. This 20 can be the same for multiple c_id's.
So your outer query is then running
SELECT * FROM `tbl_loan` WHERE transaction_num IN (20)
and returning all those results.
I'm new here. First post. I'd really appreciate some help.
I'm trying to calculate total sales for all products sold.
I have a Quantity column and a Price column.
I understand how to multiply these two columns, BUT I do not know how to add them all together in the same query.
Here is an example:
Quantity: 2, 3, 1 Price: 2, 4, 5
I could do Quantity * Price to get: 4, 12, 5
But then how would I add 4 + 12 + 5 to get the total? I need this step to be included in the same query.
EDIT: Both the Quantity and Price columns are in the same table.
SALES (Quantity, Price)
I am using Microsoft SQL-Server.
Example if you have one table:
SELECT dbo.orderid,
SUM(dbo.quantity * dbo.price) AS grand_total,
FROM ORDERITEM
If you have two tables instead of one, then:
SELECT oi.orderid,
SUM(oi.quantity * p.price) AS grand_total,
FROM ORDERITEM oi
JOIN PRODUCT p ON p.id = oi.productid
WHERE oi.orderid = #OrderId
GROUP BY oi.orderid
Adding all the rows (orderid numbers) up together to get a total, you would simply groupby and them select the sum value. Example below:
SELECT Orderid, SUM(quanity) AS Expr1, SUM(price) AS Expr2, SUM(quanity * price) AS Total
FROM dbo.mytable
GROUP BY pid
HAVING (pid = 2)
Or this in a SQL view showing the total QTY and Price:
SELECT Orderid, SUM(quanity) AS Quanity, SUM(price) AS Price, SUM(quanity * price) AS Total
FROM dbo.mytable
GROUP BY pid
I think I'm missing a simple step here but I can't seem to figure it out. I've read the other threads and they talk about grouping but I can't seem to put it all together right.
I have a simple table that holds inventory transactions. In each row, there is a quantity and a price. I want to get the sum of the quantity and the sum of the each price * each quantity.
Here's my query. If I remove the grouping, I get 1 result that is multiplied by the number of rows in the table. If I add the grouping, I get the correct result multiple times. Am I missing something here? I just feel like running a query to get 20k results when they all contain the same data would be pointless.
SELECT (SUM(i.quantity) - IFNULL(SUM(s.quantity), 0)) AS quantity,
SUM(i.unitprice * i.quantity) AS totalprice
FROM 02_01_transactions t
LEFT JOIN 02_01_transactions i
ON i.type = 1
AND i.active = 1
LEFT JOIN 02_01_transactions s
ON s.type = 2
AND s.active =1
GROUP BY t.id
Not sure there is a need for the joins (you are not joining on any common value) or the type = 2 rows if you are just subtracting them out. Is there a reason the following does not work?
-- Total quantity, total price of all type 1, active transactions.
SELECT SUM(quantity) AS quantity,
SUM(unitprice * quantity) AS totalprice
FROM 02_01_transactions
WHERE type = 1
AND active = 1
Here's my guess at what you were trying to accomplish:
select
sum(quantity * case type when 1 then 1 when 2 then -1 end) as quantity,
sum(unitprice * quantity) as totalprice
from 02_01_transactions
where type in (1, 2) and active = 1
I know I can do a count from mysql by doing this:
Select customer, Count (customer) Numbers from TblOrders group by customer
I want to count how many times each customer appears in the Order table.
After that I want to update Order table by swapping the customer id of the customer with the highest number of orders with another customer with id = 1.
Customer | Numbers
1 | 5
2 | 18
3 | 0
so here the highest was C2 so it'll swap C1 with C2 now after performing another count, I should get the table below.
Customer | Numbers
1 | 18
2 | 5
3 | 0
I also know the swapping can be done this way from a little research I've done.
Update TblOrders Set Customer = Case when 1 then 2
when 2 then 1
end
where TblOrders in (1, 2)
the problem with this statement is that it assumes I already know the two ID's that I'm swapping. but in case I don't know but I want the second one to be the ID with the highest number of orders...how do I go about it?
You want to issue an UPDATE request which affects all rows that belong to either one of the two customers in question. So the basic idea is this:
UPDATE TblOrders
SET customer = IF(customer == 'C1', #MaxCust, 'C1')
WHERE customer IN ('C1', #MaxCust)
If your customer IDs were integers, you could abbreviate this to
UPDATE TblOrders
SET customer = 1 + #MaxCust - customer
WHERE customer IN (1, #MaxCust)
This works because a + b - a = b and a + b - b = a, so a and b are exchanged.
My notation above was using a user variable #MaxCust to store the ID of the customer to be swapped. Depending on your environment, you might also use application code to enter the correct value into the query. Using a user variable, you could set it like this:
SELECT customer
FROM TblOrders GROUP BY customer
ORDER BY COUNT(*) DESC
LIMIT 1
INTO #MaxCust
after taking a look at # MvG's solutions, I came up with my own solution which is below.
SELECT customer FROM TblOrders GROUP BY customer ORDER BY COUNT(*) DESC LIMIT 1 INTO #MaxCust;
Update TblOrders Set Customer = Case
when 1 then #MaxCust
when #MaxCust then 1
end
where TblOrders in (1, #MaxCust );