MySQL Problem with inserting a row with certain conditions - mysql

I have a problem inserting a row in a MySQL table when the table is completely empty.
I use this query :
INSERT IGNORE INTO test (id, amount)
SELECT 6, 50 FROM test WHERE NOT EXISTS
(SELECT 1 FROM test WHERE amount >= 50 AND id = 6) LIMIT 1
It works fine when there is at least one entry in the table, whatever the data in the columns are. It doesn't work if the table is completely empty.
Basically, I want to insert a row if a row with the same ID and an amount equals or higher doesn't exists.
I tried with a COUNT also, still the same problem. Is there another way of doing this?

I think the only thing wrong with this is on line two, remove FROM test.. You can't select 6, 50 from test.. 6 and 50 are not columns in test, and test has no records. Try it like this:
INSERT IGNORE INTO test (id, amount)
SELECT * from (select 6, 50) as a
WHERE NOT EXISTS (SELECT 1 FROM test
WHERE amount >= 50 AND id = 6)

Related

How to 'Select Specific data, copy only certain columns and insert it into a different table?'

Currently, I find it time consuming to copy specific columns and values from Table 1 and paste the values onto Table 2 manually.
I have two tables ( In the same database ) like this:
How can I save time by doing the following? -
Grab specific ID from Table 1, in this case 1 and 2.
and copy just the Pcode & Desc values onto Table 2?
This is the end result I want to achieve (screenshot below)
The ID will be new, because its a new record. So technically I am updating Table 2 with new values that I have copied from Table 1
Every column is varchar type column expect the Id's
Also, I am using MySql Workbench.
This should do the trick;
INSERT INTO table2 (PCode, Desc)
SELECT Pcode, Desc
FROM table1
WHERE table1.id = 1 or table1.id = 2

MySql - Add new row for every userId in the table

Below is the table i am trying to write a query for to add new rows for every user.
My question is how do i add a new row for every user? Which means for userId 2 I add AccId 4 and similarly for 7 and 8. Since there is no concept of for loop in sql, do i make use of while? If so, how to loop through the userIds since the IDs are not in equal increments?
something like this maybe:
Insert Into mytable (UserID, AccID)
Select UserID, max(accId)+1
From MyTable
Group By UserID
You can re-run it every time, you will create the next value.
Untested on a MySql server:
INSERT INTO MyTable ( ID, AccId )
SELECT MyValues.ID, MyValues.Espr1
FROM (SELECT MyTable.ID, Max([AccId]+1) AS Espr1
FROM MyTable
GROUP BY MyTable.ID) AS MyValues;
Basically we prefetch Id a AccId grouping the values of Id and grabbing the Max of AccId.
Then we add these rows to the main table. Repeating the query we will add the value 5 (AccId) and so on, always adding 1

Insert record with a max of a sub query?

I have an insert statement and I want to add a value to it that increments another record for every insert. I got a column called revision and I want to add 1 to it for each new row. So...
Row 1 = revision = 1
Row 2 = revision = 2
But only if the ID matches so it would be something like
SELECT MAX(revision)+1 FROM versions WHERE id=13
Which would get 6 for example
Then I want to add that to my insert statement
INSERT INTO
versions
(id, date_added, revision)
VALUES
(13, NOW(), STUFF FROM OTHER QUERY)
But I can't seem to figure out how to do a subquery inside an insert. If I do one it complains that the tables are the same.
Try something like this maybe
INSERT INTO
versions
(date_added, revision)
(SELECT NOW(),MAX(revision)+1 FROM versions WHERE id=13)

Limiting table rows

How can I store only 10 rows in a MySQL table? The older rows should be deleted when a new row is added but only once the table has 10 rows.
Please help me
You could achieve this with an after insert trigger, delete the row where it is min date. e.g. DELETE FROM myTable WHERE myTimestamp = (SELECT MIN(myTimestamp) FROM myTable) but that could in theory delete multiple rows, depending on the granularity of your updates.
You could have an incrementing sequence, and always just delete the min of that sequence.
The question is why you'd want to do this though? It's a slightly unusual requirement.
A basic example (not validated/executed, I don't have mySQL on this particular machine) would look something like.
CREATE TRIGGER CycleOldPasswords AFTER INSERT ON UserPasswords FOR EACH ROW
set #mycount = SELECT COUNT(*) FROM UserPasswords up where up.UserId = NEW.UserId;
if myCount >= 10 THEN
DELETE FROM UserPasswords up where up.Timestamp = (SELECT min(upa Timestamp) FROM UserPasswords upa WHERE NEW.UserId = upa.UserId) AND NEW.UserId = up.UserId;
END
END;
You can retrieve the last inserted id when your first row is inserted, and store it in a variable. When 10 rows are inserted, delete the row having id < id of the first inserted record. Please try it.
first of all insert all values using your insert query
and then run this query
delete from table_name where (cond) order by id desc limit 10
must specify an id or time in one column

MySQL INSERT IF (custom if statements)

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.
My question is: can I do this in my query?
Now, why would I want to do that?
Let's assume we have the following 2 tables:
products: id, qty_on_hand
orders: id, product_id, qty
Now, let's say an order for 20 Voodoo Dolls (product id 2) comes in.
We first check if there's enough Quantity On Hand:
SELECT IF(
( SELECT SUM(qty) FROM orders WHERE product_id = 2 ) + 20
<=
( SELECT qty_on_hand FROM products WHERE id = 2)
, 'true', 'false');
Then, if it evaluates to true, we run an INSERT query.
So far so good.
However, there's a problem with concurrency.
If 2 orders come in at the exact same time, they might both read the quantity-on-hand before any one of them has entered the order.
They'll then both place the order, thus exceeding the qty_on_hand.
So, back to the root of the question:
Is it possible to run an INSERT statement conditionally, so that we can combine both these queries into one?
I searched around a lot, and the only type of conditional INSERT statement that I could find was ON DUPLICATE KEY, which obviously does not apply here.
INSERT INTO TABLE
SELECT value_for_column1, value_for_column2, ...
FROM wherever
WHERE your_special_condition
If no rows are returned from the select (because your special condition is false) no insert happens.
Using your schema from question (assuming your id column is auto_increment):
insert into orders (product_id, qty)
select 2, 20
where (SELECT qty_on_hand FROM products WHERE id = 2) > 20;
This will insert no rows if there's not enough stock on hand, otherwise it will create the order row.
Nice idea btw!
Try:
INSERT INTO orders(product_id, qty)
SELECT 2, 20 FROM products WHERE id = 2 AND qty_on_hand >= 20
If a product with id equal to 2 exists and the qty_on_hand is greater or equal to 20 for this product, then an insert will occur with the values product_id = 2, and qty = 20. Otherwise, no insert will occur.
Note: If your product ids are note unique, you might want to add a LIMIT clause at the end of the SELECT statement.
Not sure about concurrency, you'll need to read up on locking in mysql, but this will let you be sure that you only take 20 items if 20 items are available:
update products
set qty_on_hand = qty_on_hand - 20
where qty_on_hand >= 20
and id=2
You can then check how many rows were affected. If none were affected, you did not have enough stock. If 1 row was affected, you have effectively consumed the stock.
You're probably solving the problem the wrong way.
If you're afraid two read-operations will occur at the same time and thus one will work with stale data, the solution is to use locks or transactions.
Have the query do this:
lock table for read
read table
update table
release lock
I wanted to insert into a table using values so I found this solution to insert the values using the IF condition
DELIMITER $$
CREATE PROCEDURE insertIssue()
BEGIN
IF (1 NOT IN (select I.issue_number from issue as I where I.series_id = 1)) THEN
INSERT IGNORE INTO issue ( issue_number, month_published, year_published, series_id, mcs_issue_id) VALUES (1, 1, 1990, 1, 1);
END IF;
END$$
DELIMITER ;
If you later on want to call the procedure it's as simple as
CALL insertIssue()
You can find more information about PROCEDURES and if conditions in this site