How to update and insert data in one query - php

I have to update as well as insert data in MySQL in a single query. I have two tables: one is paytransactionfailure and second is walletbalance in which I have to first get data from paytransactionfailure table and and update the status of this table and insert data in walletbalance table. Is this possible in a one query.
My first table name:
paytransactionfailure
...........................................................
id fromid toid amount refund_status user_register
...........................................................
1 5 6 20 0 1
walletbalance
...............................................
id user_id balance transaction_type
...............................................
1 5 100 credit
I want this if SELECT * from paytransactionfailure WHERE refund_status='0' and user_register='1' and fromid='5' query exists then I have to update refund_status=1 in paytransactionfailure table and at the same time I want to insert data in walletbalance table for fromid user like this
want this output
...............................................
id user_id balance transaction_type
...............................................
1 5 100 credit
2 5 20 credit
for this I have used below query but I have get success in updating record but I don't get success in inserting record in walletbalance.
Is this possible or I am going in a wrong direction?
UPDATE paytransactionfailure
SET `refund_status` =1
WHERE EXISTS (SELECT * from paytransaction WHERE refund_status='0' and `user_register`='1')

What you are looking for is INSERT ... ON DUPLICATE KEY UPDATE (to insert new rows or update one that exists), or REPLACE (to insert new rows and overwrite data of any that already exist).
In both cases, the statements rely on UNIQUE keys in the table, which your walletbalance table is missing, and the statements can only be performed on the same table.
You might want to look into using stored procedures to carry out these operations - or redesign the process entirely, because IMO the schema in question just wasn't designed for what you are trying to do with it.

Related

MySQL PHP insert new row where rowNum column values always remain chronological by date and time

I am trying to create a SQL query (or multiple queries and logic in PHP) to insert new rows into MySQL db table (say table name is student) where the rowNum column values always remain chronological dependent on a separate date/time column. This means that if the row I'm inserting has the greatest/max/latest date/time it should be inserted normally and the rowNum value will just increment by one. I already have that implemented. The issue is that when the row I'm inserting has a date/time value that falls between two existing rows. Then the rowNum value for the row I'm inserting needs to be set to be the same as the rowNum value for the second of the two rows that I'm trying to insert "between" (Note: I understand the table is unordered list/set; however, the rowNum needs to adjust as in it is being insert "between"). Then, the rest of the rows after (chronologically speaking) this newly inserted row need to have their rowNum value incremented by one. Please see below example for further clarification:
id is autoincrement id column and primary key. rowNum is a "reference" id that is not necessarily unique, but does increment for each new insertion. If you go through each rowNum value, they should always be in chronological order based on date/time column. dateTime is not a default datetime timestamp, instead it is a varchar field in the format shown below.
Table: student
id
rowNum
dateTime
1
4
09-17-2021 14:00
2
5
09-17-2021 16:32
3
6
09-18-2021 19:11
4
7
09-22-2021 13:01
Then, when insert a new row with dateTime: 09-17-2021 15:21 the table should be as follows:
Table: student
id
rowNum
dateTime
1
4
09-17-2021 14:00
5
5
09-17-2021 15:21
2
5
09-17-2021 16:32
3
6
09-18-2021 19:11
4
7
09-22-2021 13:01
Then, the rowNum values after the inserted row should increment as follows:
Table: student
id
rowNum
dateTime
1
4
09-17-2021 14:00
5
5
09-17-2021 15:21
2
6
09-17-2021 16:32
3
7
09-18-2021 19:11
4
8
09-22-2021 13:01
Lastly, I understand this is a strange thing to do. I've made this concern clear and suggested this should be done a different way; but, due to unique constraints I have to do it this way where the rowNum values are chronological.
INSERT cannot modify other rows than the row(s) it inserts. You also cannot use a trigger, because a trigger cannot update the same table (it could cause infinite loops).
So you must do an UPDATE statement after you finish your INSERT. Best if you do this in a transaction.
But actually it's easier to do the UPDATE first:
START TRANSACTION;
UPDATE student SET rowNum=rowNum+1 WHERE rowNum >= 5;
INSERT INTO student SET rowNum=5, dateTime='09-17-2021 15:21';
COMMIT;
It's better to do the UPDATE first because if you INSERT the new row first, then it'll get included in the condition of the UPDATE.
This still has a problem, if more than one client is inserting a row concurrently. It could cause lock conflicts or deadlocks. You might need to use LOCK TABLES first to prevent this. But that will block your opportunity to do concurrent inserts. In other words, every transaction that does an INSERT will need to wait for others to commit.
You should also consider:
What happens to the rowNum values if a row is deleted?
What happens to the rowNum values if a dateTime is updated?
What prevents a client from updating a rowNum value directly, and throwing off the unbroken sequence?

Mysql Query : auto-increment manipulation and update on the foreign table

My tables are :
orders(orderID,orderDesc)
orderscoding(orderscodingID,orderID,codeA)
I have around 230 records for both tables.
I want to alter the (orderID) auto-increment from
1,2,3,4,5 ..... to 100001,10002,10003,10004,10005
and reflect it on the related table , is this possible?
So basically this will not work, as it is for new insert (but I want to modify existing records):
ALTER TABLE orders AUTO_INCREMENT=100001;
If you want to update existing orderIDs, you can do like this
UPDATE orders SET orderID = orderID + 10000
All existing orderID will be incremented by 10000 with this query. So, 1 will become 10001, 2 will be 10002 and so on...
Do the same for orderscoding table to keep it synced with orders table (do the same if any more tables are synced to orderID.)
UPDATE orderscoding SET orderID = orderID + 10000

Given MySQL DB with duplicate rows based on criteria, list all the OLDER rows, for external processing (php)

Situation:
Old scripts added rows to a table without deleting existing rows.
Need to discover "duplicate" rows (based on matching two fields).
For each set of duplicate rows, sort by ids and return all but the newest one (highest id).
Each row has an associated external file, so can't simply delete the older rows - need to return a list of all the older rows, which will then be processed by a php script.
Example:
TABLE mytable:
ID A B Filename
1 10 abc aa.png
2 11 dddd bb.xml
3 10 abc cc.png
4 10 dddd dd.png
5 10 abc ee.xml
6 11 dddd ff.xml
Rows with IDs 1 & 3 & 5 are duplicates (both A and B match).
Similarly, 2 & 6 are duplicates. Return list (1, 2, 3) - these are the "older" rows that need to be processed.
Even better: return a set of records, containing 'ID' and 'Filename' for those rows.
My primary question is an SQL query that does this, though it would also be useful to me to see how to use the result of that query in php.
There are existing stackoverflow posts related to deleting duplicate rows, but the ones I found delete the rows directly. This won't work for me, as I need to have the external php script delete the corresponding external files:
Deleting Duplicate Rows from MySql Table
How to delete duplicate records in mysql database?
How to delete all the duplicate records in PHP/Mysql
IMPORTANT: The other posts which I quote don't bother to distinguish newer from older; they are about removing fully duplicate records, but that is not my situation. I have records which are partially duplicates; that is, several records match the specified criteria, but there is important information in other fields, hence I have to know which is newest (highest id) for each value of criteria; those are the ones to keep.
I would try this "make sure you test the code before to apply it on production data"
Assuming you have lots of data, I would create temporary table of the data that you want to keep so you can perform the operation fast.
-- Generate a list of the IDs to keep
CREATE TEMPORARY TABLE keepers (KEY(ID)) ENGINE = MEMORY
SELECT A, B MIN(ID) AS ID
FROM table
GROUP BY A, B;
-- Delete the records that you do not wish to keep
DELETE FROM table
WHERE NOT EXISTS (SELECT 1 FROM keepers WHERE ID = table.ID);
If the DELETE query does not work "return an error" about the sub query, you can try this instead of the DELETE query.
CREATE TEMPORARY TABLE deleteme (KEY(ID)) ENGINE = MEMORY
SELECT ID FROM table
WHERE NOT EXISTS (SELECT 1 FROM keepers WHERE ID = table.ID);
DELETE t.* FROM table AS t
INNER JOIN deleteme AS d ON d.ID = t.ID;
To get the data:
Select the records you want to keep (inner query) and join back on itself (outer query) keeping all records and using the dummyfield to find the to be deleted records.
CREATE TEMPORARY TABLE delete_these AS
SELECT *
FROM table a
LEFT JOIN (SELECT MAX(id) as non_deletion_id, 1 AS dummyfield,
FROM table a
GROUP BY your two fields) b ON non_deletion_id=a.id
WHERE dummyfield IS NULL;

In MYSQL/PHP how would I delete from ID 1 and insert data to ID 5

This is how my table is setup. I want to add in a new height and then delete that data at ID 1 (2.0). So it keeps leap frogging when inserting in new data. This is so I can keep up to only 5 records at a time.
Sorry, I'm very new to MYSQL/PHP.
Insert new data:
INSERT INTO table (height) VALUES (xxx);
Delete the pair (1,2.0):
DELETE FROM table WHERE id=1;
OR... all together like this:
UPDATE table SET height=xxx WHERE id=1;
for the delete, something like this might work better:
DELETE FROM table WHERE id NOT IN (SELECT ID FROM table ORDER BY ID DESC LIMIT 5)
essentially delete from the table where the id doesn't match the last 5 ids inserted. This also works when there are less than 5 entries in the database, nothing would get deleted.
To delete the first item do:
DELETE FROM table LIMIT 1

SQL query using replace a value in one table by randomly selecting a value in another table

I have a table with an value that I would like to be updated periodically with a cron job. However, I need to update the value by replacing it with a value from a different table. The issue is that I would like the replacement value to be chosen randomly.
For example, Table 1 has
ID Email
=================
1 bobatumail
Table 2 has:
ID Email
================
1 bobatumail
2 joeatumail
3 peteatumail
4 biffatumail
5 wilneratumail
6 wilsonatumail
I would like the query to replace bobatumail in Table 1 with any of the other values in Table 2 as long as it is random. It could even be the same value as in Table 1.
Any idea how to do this?
In MySQL you could use the REPLACE statement:
REPLACE INTO table1 (ID, Email)
SELECT 1, table2.Email FROM table2 ORDER BY RAND() LIMIT 1;
The "1" in the second line represents the id of the entry while the second part returns a random value out of table2. Yes, there are solutions using the UPDATE statement (JOIN and ANSI) but its always tricky and you usually have to turn off safe update mode.
http://dev.mysql.com/doc/refman/5.5/en/mysql-command-options.html#option_mysql_safe-updates
Please note that REPLACE first deletes the old entry and then reinserts the new one.
http://dev.mysql.com/doc/refman/5.5/en/replace.html

Categories