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)
Related
i had query like this
CREATE TRIGGER `tambah_riwayatobat` AFTER INSERT ON `obat`
FOR EACH ROW insert into riwayat_obat(nama, keterangan, distributor,tanggal)
(select new.nama, 'Masuk', d.nama ,now()
From distributor d
join obat ON new.id_distributor = d.id_distributor)
i try to insert data with trigger and one of part data i fetch with constraint, but why the data be duplicate entry ?
Output :
example, if i try to insert data obat 1st time, data on tambah_riwayatobat insert 1 too
if i try to insert data obat 2nd time, data on tambah_riwayatobat insert 2 times with same data
if i try to insert data obat 3rd time, data on tambah_riwayatobat insert 3 times with same data
I'm not certain exactly what's happening, but it's a result of the join in your trigger code. You’re joining obat to distributor, but your join condition makes no mention of obat so you're getting some sort of cross-product where on the second and subsequent INSERT your SELECT subquery is selecting more than one row.
You shouldn't (and don't need to) use the join, since all the data you need from obat is already in the pseudorecord NEW. The following code should work much better:
CREATE TRIGGER `tambah_riwayatobat`
AFTER INSERT ON `obat`
FOR EACH ROW
INSERT INTO riwayat_obat
(nama, keterangan, distributor, tanggal)
(SELECT NEW.nama, 'Masuk', d.nama, now()
FROM distributor d
WHERE new.id_distributor = d.id_distributor
LIMIT 1);
The LIMIT clause will ensure that the SELECT selects only one row, so the INSERT inserts only one row; if distributor.id_distributor is a primary key the LIMIT clause is unnecessary.
For my time management system I'd like to add a new daily row into my table containing a value depending on the day of the week which is located in another table.
The values that I want to read are located in the colums s0 - s6 (for each day of the week).
Edit: Right now I'm at this point. New line is being added, but with "s2" instead of the value of that cell :(
INSERT INTO `table_write` (datum, soll)
SELECT CURRENT_DATE(), CONCAT('s',DAYOFWEEK(CURRENT_DATE())-1)
FROM `table_read` WHERE id = 51901
btw: The -1 is just to get weekdays being shown 0-6 instead of 1-7. It works fine, it's just not letting me read from the table I want to read from :(]
I've never done anything with Events in MySQL, so I'm grateful for every answer.
Change your INSERT statement like below. Remove the VALUES clause all together cause you are using INSERT .. SELECT construct here.
INSERT INTO `table_to_write` (datum, soll)
SELECT NOW(), #soll
FROM `table_to_read`
WHERE id = 51901; //This where make no sense in this case though
(OR)
INSERT INTO `table_to_write` (datum, soll)
SELECT NOW(), CONCAT('s', DAYOFWEEK(now()))
FROM `table_to_read`
WHERE id = 51901;
I'm need to get the ID of the last record inserted into my table.
INSERT INTO mytable (Column1, Column2) VALUE ('Test', 'Bob');
SELECT/SET LAST_INSERT_ID() as NewID;
Response.Write rst("NewID") '(for example)
Can it run in one statement, or do I need to run the SELECT LAST_INSERT_ID after the INSERT SQL has ran.
I am using MYSQL and ASP
You need to run it after every statment as it will always returns one id of most recent inserted record.
To achieve your goal,
You need to do is, whenever any record inserted to table, get the last id and store it in to any string/table every time and return it from your sproc. This way you get all inserted id at once.
I think that you need to run 2 procedure, first insert and then select order by id desc
Maybe this seems like the opposite of what people would normally like to do, but I'd like to duplicate rows in my mysql table.
So, for example, I have a table with 1 row that has project_id, and one row with file_name. Each project has very many files associated with it. I would like to duplicate all rows that exist for one project in to another project. I could write some python script that would do this but I suspect there would be a way to do it from within mysql.
Any ideas? Thanks.
For example, if I have a project that looks like this...
file_id, file_name, project_id
-------, ---------, ----------
1, file1.png, 1
2, file2.png, 1
3, file3.png, 1
...and up to around 100 rows.
What should I type in to get a project that looks like this...
file_id, file_name, project_id
-------, ---------, ----------
1, file1.png, 1
2, file2.png, 1
3, file3.png, 1
4, file1.png, 2
5, file2.png, 2
6, file3.png, 2
In MySQL, you can combine an insert statement with a select statement, such that the values inserted in the new row by the insert statement are the ones selected by the select statement. See INSERT..SELECT for details.
It sounds like what you need is to INSERT from a SELECT. The basic idea for doing this can be found from the link below.
mysql -> insert into tbl (select from another table) and some default values
Side note: If you duplicate the rows completely then you will probably have issues with database keys. If you don't, then your database has design issues.
Try this:
INSERT INTO table_name (file_name, project_id)
SELECT file_name, project_id + 1 FROM table_name;
This selects everything currently in the table named table_name and reinserts the records into table_name with an incremented project_id. It assumes the file_id field is auto incremented.
I think it can be resolve this way, in case you have a main table that holding the entire project id list, project_table in my example, and assuming that file_id in the file_table is set to auto_increment :
INSERT INTO file_table ( file_name, project_id)
VALUES (SELECT file_name, project_table.project_id
FROM project_table
INNER JOIN file_table ON project_id = 1
WHERE project_table.id != 1)
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