MYSQL - INSERT INTO using WHERE condition of Table 1 - mysql

after reading all the "INSERT INTO" posts as well as the documentation, I am still unsure whether what I want is feasible or not.
I want to change the UPDATE below into an INSERT INTO, because I have many 100-thousands of them (speed issues):
UPDATE city c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
WHERE
p17t = 30 AND p17l = '30';
or
UPDATE city c
SET
c.g1h = '0',
c.g1q = '0',
c.g1k = '0',
c.g1w = '0',
c.g1s = '0'
WHERE
p1t = 1
AND p1l = '1';
However, my best solutions do not work:
INSERT INTO city (g17h, g17q, g17k, g17w, g17s)
SELECT
'3196504',
'2593487',
'0',
'0',
'0'
FROM valuestoretab
WHERE
p17t = 30
AND p17l = '30';
This is of course because my WHERE condition can only be satisfied in the first table (city) but not in the second one which is just a table of values, whereas the city table is a data set where each id has particular values for p17t, p17l and so on.
For clarification:
The first table (city) looks like
cityid1, ownerid1, islandid1, p17t, p17l
cityid2, ownerid2, islandid2, p17t, p17l
with different values for each row for p17t and p17l.
So, my questions would be:
1. Is it at all possible to write a INSERT-Query with a WHERE condition for the table that is being inserted into?
2. If no, do I have to stick to my UPDATE or is there another (fast!) solution?
Thanks to the community!
litotes

To give a quick answer insert with a select statement is possible
Insert INTO MyTable (Val1, Val2)
Select
SomeValue,
AnotherValue
From MyOtherTable
Where Date = Getdate()
On the other hand, you can also update many records like in the following example:
Update t1
Set
t1.Val1 = t2.SomeValue,
t1.Val2 = t2.AnotherValue
From MyTable t1
Inner join MyOtherTable t2 ON t1.PK = t2.FK
where t2.Date = getdate()
EDIT:
When i read the following query, I presume p17t and p17l are from the valuestoretab.
UPDATE city c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
WHERE
p17t = 30 AND p17l = '30';
==> changed this into:
UPDATE c
SET
c.g17h = '3196504',
c.g17q = '2593487',
c.g17k = '0',
c.g17w = '0',
c.g17s = '0'
FROM City c, ValueStoreTab v
WHERE
c.SomeCol = v.SomeCol -- Here, your relation must exist!
AND v.p17t = 30 AND v.p17l = '30';

Related

Update and append to all items in a specific column

How do I append a character to all items `purchase_id' here is a manual example of what I want...
SELECT *
FROM `loadable_link`
WHERE `product_sku` = '2101-R'
ORDER BY `customer_id` DESC
Then select from purchased_id and append a '0' to all purchased ID's
UPDATE `loadable_link` SET `purchased_id` = '11165690'
WHERE `loadable_link`.`purchased_id` = 1116569;
You can update the table according to the condition in the original select statement.
If purchase_id is a number, you can multiply it by 10:
UPDATE `loadable_link`
SET `purchase_id` = `purchase_id` * 10
WHERE `product_sku` = '2101-R'
If purchase_id is a string, you can concatenate a 0 to it:
UPDATE `loadable_link`
SET `purchase_id` = CONCAT(`purchase_id`, '0')
WHERE `product_sku` = '2101-R'
UPDATE `loadable_link`
SET `purchased_id` = CONCAT(`purchased_id`, "0")
WHERE `product_sku` = "2101-R";
This can be achieved in one UPDATE query, take the original value of each row and CONCAT() to append a 0 to the end of the existing purchase_id.

How do I set a column to the number that was generated by MySQL for a previously set row?

So, I created an INSERT statement on MySQL that added a certain row to a table. The invoice_id was set to DEFAULT. Now, I need to find out what that auto-generated id was to continue. How do I go about that?
I've tried using DEFAULT and AUTO to see if they would do the trick. They did not.
INSERT into ap.terms
VALUES (terms_id = 6, terms_description = 'Net due 120 days', terms_due_days = 120);
UPDATE ap.terms
SET terms_description = 'Net due 125 days', terms_due_days = 125
WHERE terms_id = 6;
DELETE FROM ap.terms
WHERE terms_id = 6;
INSERT into ap.invoices
VALUES (AUTO_INCREMENT, 32, 'AX-014-027', '2014-08-01', '434.58', '0.00', '0.00', 2, '2014-08-31', NULL);
INSERT into ap.invoice_line_items
VALUES (invoice_sequence = 1, account_number = 160, line_item_amount = '180.23', line_item_description = 'Hard drive'), (invoice_sequence = 2, account_number = 527, line_item_amount = '254.35', line_item_description = 'Exchange Server update')
SET invoice_id = last_insert_id(1,1);
UPDATE ap.invoices
SET credit_total = invoice_total*0.1, invoice_total = (payment_total + credit_total)
WHERE invoice_number = 'AX-014-027';
UPDATE ap.vendors
SET default_account_number = 403
WHERE vendor_id = 44;
UPDATE ap.invoices
SET terms_id = 2
WHERE default_terms_id = 2;
DELETE FROM ap.invoice_line_items
WHERE invoice_id = last_insert_id(1,1);
DELETE FROM ap.invoices
WHERE invoice_id = last_insert_id(1,1);
So, line 16, where it says "SET invoice_id = last_insert_id(1,1)" is where my Error is. How do I fix it?
Error code 1062, you have an error in your sql syntax. Check the manual that corresponds.
Your table structure is incorrect. Your primary key should be set to auto increment, default none. You should use LAST_INSERT_ID() to retrieve the last row ID inserted into the database.

UPDATE multiple rows with different values in one query in MySQL

I am trying to understand how to UPDATE multiple rows with different values and I just don't get it. The solution is everywhere but to me it looks difficult to understand.
For instance, three updates into 1 query:
UPDATE table_users
SET cod_user = '622057'
, date = '12082014'
WHERE user_rol = 'student'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '2913659'
, date = '12082014'
WHERE user_rol = 'assistant'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '6160230'
, date = '12082014'
WHERE user_rol = 'admin'
AND cod_office = '17389551';
I read an example, but I really don't understand how to make the query. i.e:
UPDATE table_to_update
SET cod_user= IF(cod_office = '17389551','622057','2913659','6160230')
,date = IF(cod_office = '17389551','12082014')
WHERE ?? IN (??) ;
I'm not entirely clear how to do the query if there are multiple condition in the WHERE and in the IF condition..any ideas?
You can do it this way:
UPDATE table_users
SET cod_user = (case when user_role = 'student' then '622057'
when user_role = 'assistant' then '2913659'
when user_role = 'admin' then '6160230'
end),
date = '12082014'
WHERE user_role in ('student', 'assistant', 'admin') AND
cod_office = '17389551';
I don't understand your date format. Dates should be stored in the database using native date and time types.
MySQL allows a more readable way to combine multiple updates into a single query. This seems to better fit the scenario you describe, is much easier to read, and avoids those difficult-to-untangle multiple conditions.
INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
cod_user=VALUES(cod_user), date=VALUES(date)
This assumes that the user_rol, cod_office combination is a primary key. If only one of these is the primary key, then add the other field to the UPDATE list.
If neither of them is a primary key (that seems unlikely) then this approach will always create new records - probably not what is wanted.
However, this approach makes prepared statements easier to build and more concise.
UPDATE table_name
SET cod_user =
CASE
WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END, date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
You can use a CASE statement to handle multiple if/then scenarios:
UPDATE table_to_update
SET cod_user= CASE WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END
,date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
To Extend on #Trevedhek answer,
In case the update has to be done with non-unique keys, 4 queries will be need
NOTE: This is not transaction-safe
This can be done using a temp table.
Step 1: Create a temp table keys and the columns you want to update
CREATE TEMPORARY TABLE temp_table_users
(
cod_user varchar(50)
, date varchar(50)
, user_rol varchar(50)
, cod_office varchar(50)
) ENGINE=MEMORY
Step 2: Insert the values into the temp table
Step 3: Update the original table
UPDATE table_users t1
JOIN temp_table_users tt1 using(user_rol,cod_office)
SET
t1.cod_office = tt1.cod_office
t1.date = tt1.date
Step 4: Drop the temp table
In php, you use multi_query method of mysqli instance.
$sql = "SELECT COUNT(*) AS _num FROM test;
INSERT INTO test(id) VALUES (1);
SELECT COUNT(*) AS _num FROM test; ";
$mysqli->multi_query($sql);
comparing result to transaction, insert, case methods in update 30,000 raw.
Transaction: 5.5194580554962
Insert: 0.20669293403625
Case: 16.474853992462
Multi: 0.0412278175354
As you can see, multiple statements query is more efficient than the highest answer.
Just in case if you get error message like this:
PHP Warning: Error while sending SET_OPTION packet
You may need to increase the max_allowed_packet in mysql config file.
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3
Here col4 & col1 are in Table1. col2 & col3 are in Table2 I Am trying to update each col1 where col4 = col3 different value for each row
I did it this way:
<update id="updateSettings" parameterType="PushSettings">
<foreach collection="settings" item="setting">
UPDATE push_setting SET status = #{setting.status}
WHERE type = #{setting.type} AND user_id = #{userId};
</foreach>
</update>
where PushSettings is
public class PushSettings {
private List<PushSetting> settings;
private String userId;
}
it works fine

MySQL query Find and Replace in Specific Columns in a Table?

I need to set all values in certain columns...to 1 (where they are now NULL)
Can anyone help out with a little assist on this SQL query/command syntax?
I need to replace several columns where the SchoolID is 184 with a 1, something like this?
SELECT * FROM tblMembers WHERE SchoolID SET column = '1';
You need to use an UPDATE statement:
UPDATE tblMembers
SET column = '1'
WHERE SchoolID = '184'
You can set multiple columns at the same time:
UPDATE tblMembers
SET column = '1', column2 = 'somethingelse', column3 = 'somethingelse'
WHERE SchoolID = '184'

MySQL AND keyword issue

I have a query which is behaving strange...
Firstly, here is a query to get all PMs whether or not they've been read or deleted for the user ID 1:
SELECT * FROM `pms` WHERE `toid` = '1'
This returns 3 rows as expected. Next, let's see if I can get only unread messages for this user:
SELECT * FROM `pms` WHERE `toid` = '1' AND `read` = '0'
This returns 2 rows as expected. Let's see if I can get any read and unread messages which have been binned:
SELECT * FROM `pms` WHERE `toid` = '1' AND `binned` = '0'
This returns 2 rows as expected.
The query which I need to run is getting all unread and not binned messages for a specified user id. To do this, I am doing this:
SELECT * FROM `pms` WHERE `toid` = '1' AND `read` = '0' AND `binned` = '0'
However, it should be returning 1 row as I know in the database there is a message with toid as 1, read as 0 and binned as 0 but for some reason this query above is returning 0 rows...
Why is this?
UPDATE
Here is a screenshot of my table structure as seen in Sequel Pro:
Here is a screenshot of the data inside the table as seen in Sequel Pro:
As you can see there is definitely 1 record with toid as 1, read as 0 and binned as 0.
UPDATE 2
The reason these are ENUM is because I'm wishing to store a boolean value in MySQL. I do this by enforcing the column to be either a '1' or a '0' and making it default to '0' as well. If anyone has a better way of storing boolean values in MySQL then I'd love to learn.
Secondly, here is my PHP function inside of my User.class.php file which is getting the unread count using this SQL. This function is returning 0 when it should be returning 1. The $this->getUserId() is returning 1 as that is the current user I am using:
public function getUnreadCount()
{
global $database;
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND 'binned' = '0'";
$query = $database->query($sql);
$count = $database->count($query);
return $count;
}
Thanks for the help so far but I still cannot work out why this isn't working. I'm using the read in the query adding backticks to prevent MySQL from using it as a keyword.
I bet its something really obvious I'm missing...
James, I think the problem might have to do with how the table was populated.
Since the "read" and "binned" columns' datatypes are ENUMs, you probably have to either set the correct default value ('0' or '1') or always provide a valid value when inserting a row into this table. In other words, you can't omit a value for either the "read" or "binned" columns when inserting a "pms"-row.
In other words, if your "pms" table is set up as follows, without defaults:
create table pms (
toid int,
`read` ENUM('0','1') ,
binned ENUM('0','1')
);
then you have to insert fully specified row-values like so:
insert into pms (toid, `read`, binned) values
(1, '0', '0'),
(1, '0', '1'),
(1, '1', '0'),
(1, '1', '1')
;
and avoid inserting sparse data like this:
insert into pms (toid) values (1);
insert into pms (toid, binned) values (1, '1');
insert into pms (toid, `read`) values (1, '1');
insert into pms (toid, `read`, binned) values (1, '1', '1');
Providing the correct default enum-value for those columns would also solve this issue:
create table pms (
toid int,
`read` ENUM('0','1') default '0',
binned ENUM('0','1') default '0'
);
I've set up a sqlfiddle to illustrate.
if your columns are integers try doing this
SELECT * FROM `pms` WHERE `toid` = 1 AND `read` = 0 AND `binned` = 0
EDIT:
it should be your columns to be integers like that in this demo.
SQLFIDDLE DEMO
or to be enum with values as strings like here
SELECT * FROM `pms`
WHERE `toid` = 1 AND `read` = '0' AND `binned` = '0'
sqllfiddle demo
Try to test if you have set your variables correctly. I suggest by testing if you get the right results when querying for just one variable.:
SELECT * FROM `pms` WHERE `toid` = '1'; -- 3;
SELECT * FROM `pms` WHERE `read` = '0'; -- 4;
SELECT * FROM `pms` WHERE `binned` = '0'; -- 4;
Classic mistakes would be that you have used integer values instead of string (ENUM) values or have substituted the zero for an null.
SQL FIDDLE DEMO
Wow haha I've just found why its not been returning the rows.
I'd mistakenly used single quotes instead of backticks in my PHP implementation of the SQL query...
So my query was actually:
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND 'binned' = '0'";
When it should've been:
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND `binned` = '0'";`
As you can see, near the end of the query for binned I had mistakenly used single quotes.
Can you believe it was that simple?
Just out of interest, how do you think I should be storing boolean values in MySQL?