Merge tables into One WITH same generated number in both new tables - mysql

I found some options to run a mysql query to migrate/split one table into 2 new tables, but one of the fields I would like to create on the new table has to be the same as in the other new table:
So from the "From_payments" table, I would like to create 2 new tables called: "To_paymenttransaction" and "To_paymentinfo". A lof of the field are predefined and some are from the old table. The only problem is that the predefined field "paymentinfoid" has to be the same is both new tables.
**To_paymenttransaction** --- < --- **From_payments**
paymenttransactionid ------- < --- (Generate next available number in this column)
paymentinfoid -------------- < --- (Generate next available number in this column)
transactionid --------------- < --- txn_id
state ---------------------- < --- (Set all to "1")
amount -------------------- < --- mc_gross
currency ------------------- < --- mc_currency
dateline -------------------- < --- payment_date
paymentapiid --------------- < --- (Set all to "1")
request -------------------- < --- (Set all to "NULL")
reversed ------------------- < --- (Set all to "0")
**To_paymentinfo** -----------<
paymentinfoid -------------- < --- (Same generated number that goes to the paymentinfoif field in To_paymenttransaction table )
hash ----------------------- < --- (Set all to "Imported")
subscriptionid --------------- < --- (Set all to "1")
subscriptionsubid ------------ < --- ("2" IF above field mc_gross is 4, "1" IF above field mc_gross is 6, "0" IF above field mc_gross is 10)
userid ---------------------- < --- userid
completed ------------------ < --- (Set all to "0")
Any ideas?
All help is greatly appreciated.

Maybe generate the paymentinfoid on the original table before you split it. Then you can copy that single entry into each of the new tables.

Related

Case statements for multiple fields when only certain cases exist for each field

We have an inventory feature where we generate Bills. There is an Edit Bill API call. We have implemented it as PATCH call.
A Bill with id = 1 has 2 LineItems :
| Stock Id | Qty | Rate |
| 10 | 2 | 10 |
| 11 | 3 | 20 |
Now lets say I want to change the quantity for stock Id : 10 to 5 and I want to change the rate for stock Id : 11 to 40
We have represented it as PATCH Call :
bill : {
id : 1
lineItems : [
{
stockId : 10,
qty : 5,
},
{
stockId : 11,
rate : 40
}
]
}
In the backend we run following query :
UPDATE `billlineitem`
SET `rate` = ( CASE
WHEN stockid = 11 THEN '40'
ELSE rate
END ),
`qty` = ( CASE
WHEN stockid = 10 THEN 5
ELSE qty
END ),
`updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE `bill_id` = '1'
AND `stockid` IN ( 10, 11 )
Is it ok, in the above case when there is no change for an attribute then the else clause will take the value from the database for that attribute. The above update statement is run in a transaction.
Is this a correct approach? Will this do an update for every attribute for every stock Id. Is there a better approach?
We are using MySQL DB.
What you've written should work, but it will get very complex if you have to update different columns for many different stock IDs. It would probably be simpler, and maybe better performance, to do a separate query for each ID.
BEGIN TRANSACTION;
UPDATE billlineitem
SET rate = '40', `updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE stockid = 10;
UPDATE billlineitem
SET qty = 5, `updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE stockid = 11;
COMMIT;

Binary search in a MySQL table with deleted rows PHP

I have a large MySQL table with sorted data. When I need to find a starting point, I perform a binary search to find the lower bound ID (auto increment). The only problem is once some data is deleted, I need to look at the first existing row with a lower ID if the ID given by the algorithm doesn't exist. How should I modify this code to achieve that?
$l = 1;
$h = $max; //SELECT MAX(id)
while ($h - $l > 1){
$m = ($h + $l) / 2;
$q = mysqli_query($db, "SELECT col FROM tab WHERE id=". floor($m));
$result = array();
while($result[] = mysqli_fetch_row($q)){;}
if ($result[0][0] < $val) $l = $m;
else $h = $m;
}
echo round($m);
For example I want to find which rows have the value of col greater than 12345 and the table has max ID 10000. I start by looking at row 5000, where the col = 9000, then 7500 (col = 13000), then 6250 has been deleted, so I start looking for the 1st existing row with ID < 6250 and I find that 6245 has col = 10500. Now I'm looking between IDs 6873 and 7500 etc.
The right way to do this
So you have a table like this:
| ID | col |
---------------
| 1 | 15 |
| 3 | 155 |
| 18 | 9231|
| 190 |14343|
| 500 |16888|
You can get find 14343 with the following query:
SELECT ID, col FROM the_table WHERE col>12345 LIMIT 1;
To make it faster, you'd need to add an index (index word is worth googling)
ALTER TABLE `the_table` ADD INDEX `col` (`col`);
After that mysql will create a tree structure internally and will be doing binary searches on it for you.
This will be working much faster as you'll avoid multiple network roundtrips + other per request expenses (query parsing, optimization, all the locks & mutexes, ...)
Answer to your question
I need to look at the first existing row with a lower ID
E.g. you'd like to get first row with an ID < than 300, you do this (limit is what makes the query return only 1 result):
SELECT col FROM the_table WHERE ID < 300 LIMIT 1;

Change FROM part of a query depending on column value

I have a table named tasks with a columns named task_type, task_group and keyid. Then there is another table named task_groups with two columns: keyid and name.
If a task has a task_type equal to 2 then I know that task_group contains the keyid value for the entry in table task_groups that contains the name of the task. If task_type is any other value then task_group is -1. So what i want is to write a query that returns the task type always AND the name of the task_group but only if task_type is 2, all of this for a given task.
For this I use a script with the following logic (3 is a tasks.keyid example):
SELECT task_type,task_group AS tgid FROM tasks WHERE keyid = 3;
if (task_type == 2)
SELECT name FROM task_group WHERE keyid = tgid
Is there a way to write one query to do this?
EDIT: Adding some sample data
Table task:
+++ keyid +++ task_group +++ task_type
+++ 25 +++ -2 +++ 0
+++ 26 +++ -2 +++ 1
+++ 27 +++ 132 +++ 2
+++++++++++++++++++++++++++++++++++++++
Table task_groups:
+++ keyid +++ name
+++ 132 +++ a task group
+++++++++++++++++++++++++++++++++++++++
Expected output when replacing the value 3 in the above code would be
(tasks.keyid = 25) task_type = 0, task_group_name = ""
(tasks.keyid = 26) task_type = 1, task_group_name = ""
(tasks.keyid = 27) task_type = 2, task_group_name = "a task group"
I hope this is good enough.
Try this:
SELECT
t.task_type, t.task_group AS tgid,
IF (t.task_type = 2, g.name, '') AS group_name
FROM tasks t
LEFT JOIN task_group g ON t.task_group = g.keyid
WHERE t.keyid = 3
;
this query should return group name if type = 2 or empty string otherwise.

extract string from string in mysql query

I have this query:-
select col_str,
getVal,another_str,resultVal_str from tablename
Getting results like this:
col_str getVal another_str
'11,12,33,54,1,44' '12' '9,5,4,8,7'
'11,12,33,54,1,44,10,12,11,12,12' '44' '9,5,4,8,7,6,3,5,2,4,2'
'11,12,33,54,1,44' '999' '9,5,4,8,7,4'
'11,12,33' '0' '9,5,4'
----- ---- -----
----- ---- -----
----- ---- -----
The columns col_str,getVal,another_str came from table and the column resultVal_str want to calculate based on remaining three column,
Logic for resultVal_str -
See first record getVal having value 12 and col_str having 12 at location number 2 then see the location number two in another_str is 5, so the resultVal_str is 5 and so on. See below:
col_str getVal another_str resultVal_str
'11,12,33,54,1,44' '12' '9,5,4,8,7' 5
'11,12,33,54,1,44,10,12,11,12,12' '44' '9,5,4,8,7,6,3,5,2,4,2' 6
'11,12,33,54,1,44' '999' '9,5,4,8,7,4' 0
'11,12,33' '0' '9,5,4' 0
----- ---- ----- ---
----- ---- ----- ---
----- ---- ----- ---
How can i add the next column resultVal_str with getting result like above ?
first you need to fin the position of getVal in col_str using FIND_IN_SET function.
once you get the position you can find the resultVal from same location in another_str using SUBSTRING_INDEX function as:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(another_str,
",", (FIND_IN_SET(getVal, col_str))),
",", - 1) AS resultVal_str
FROM tablename;
test:
SET #getVal = '12', #col_str = '11,12,33,54,1,44', #another_str = '9,5,4,8,7';
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(#another_str, ",", (FIND_IN_SET(#getVal, #col_str))), ",", - 1) AS resultVal_str;

how to select a particular set of rows in a table in the program without the user needing to select them using the mouse?

I am using JTable. Suppose I have a table which contains the following information -
**col1 col2 col3 col4**
row1 --- value1 --- ---
row2 --- value2 --- ---
row3 --- value3 --- ---
row4 --- value3 --- ---
row5 --- value1 --- ---
row6 --- value1 --- ---
row7 --- value2 --- ---
row8 --- value1 --- ---
I need to copy the rows which have the value of col2 as "value1" into another table.
For selecting the rows by hand (mouse click) there is a function called - getSelectedRows() where the work will be over in seconds i.e.
int [] rows = inputTable.getSelectedRows(); // "rows" is getting the array of indexes of the rows in the table
but now I need to do the same thing without mouse selection. i.e. int [] rows should get the rows indexes without using the above method but I can use any other methods without mouse selection that is...
List<String> searchedRows = new ArrayList<String>();
for (int rowIndex=0; rowIndex < rowCount; rowIndex++) {
String value = (String)table.getValueAt(rowIndex,varColNumber);
if ("value1".equals(value)) {
searchedRows.add(rowIndex);
}
}
// here in the List searchedRows you have the rows numbers where the column is equals to the string "value1".
Hope it helps..