I can't seem to find an answer to my problem, but I got a database where I would like to change the row in a column to affect all the other rows in the same column, is this possible?
(I can't post an image because of reputation?! - but my column is called Active and there's 2 rows right now - the first one has the value 'ja' and the second one is NULL)
'ja' and NULL are the only two values I will be using, so when the second row is set to 'ja', I would like the first row to change to NULL. But as I can see it might not be possible, but if anyone knows more than me, I would be very happy!
It's Mysql database I use sql queries and php.
I'd keep things simple and run two queries.
One to set everything back to null
The second to set the active record to 'ja'
I'm guessing that there's probably a foreign key in the table too so that would be part of the update statement too.
As a matter of "style" I'd prefer to see an active column having a 1/0 or y/n type of value rather than using null all the time.
That is a complicated database design. The first thing that comes to mind is a trigger updating all other rows whenever a row gets 'ja'. However this will fail, because you cannot update the same table you are already updating.
It is generally a bad idea to design a table such that all rows must contain value y when one row contains value x. I would solve this with by removing the "active" column altogether and replace it with a one row table containing a column active_id. So there is always just one id active and the others are implicitely inactive.
If you want to stick with your database design, a possible update statement would be:
update mytable
set active = case when id = 123 then 'ja' else null end;
However the dbms doesn't guarantee that there will always be exactly one record with 'ja'. It's up to you to be careful about it.
PS: I agree with Sarah King on the NULL issue. NULL means "I don't know", but you know very well that the records are not active. So this should be a non-nullable column with values "ja" and "nein" or whatever you prefer. In MySQL you would rather use a BOOLEAN column.
Related
I am creating my first (!) database, and I have run into an issue that I cannot seem to locate the answer for.
I have put an "added on" field in a table (among other things ofc), and since I'm the one adding it, I want to put the same date in the entire column. The idea is that if there is a new item added at a later date, it will have that date, but the data initially populated should all have the same date.
How? Please don't tell me one row at a time....
Just add the column to the table and then run an update query
update yourtable set nameofyournewfield = 'yourdate'
This will update all rows currently in the db, while the new rows will gettheir value (or have the default value you provided)
Another possibility in addition to #Nicola's answer is to use the DEFAULT argument in add column.
You can set default property of that column to any date and it will replicate that for all rows as long as you don't specify any value for that column while inserting and when you want to insert a different value just specify it in the insert statement.
Let's say I have a MySQL table and a table has a row with id and it has auto_incremented. Let's say via MySQL query and PHP, I add a row. The first row has id of 1. Then I manually add a second row (via phpmyadmin) with the id of 2. If I do a third MySQL insert via PHP... what would the id be for the third row... 2 or 3?
Question is... does auto_increment take into account manual inputs?
does auto_increment take into account manual inputs?
Yes it does. But I hope you do not really type in the ID manually, right? :-) Just leave this field alone when inserting (manually or programatically), MySQL will take care of it for you.
MySQL does accept manual inputs, and it WILL try to set the value you offer. If the value does not exist, it gets inserted, else you get a duplicate key error.
Put a value when you want to decide a value yourself (for example,
you deleted a line, and now want the exact same line in the table).
Put NULL or leave the column out of the insert to let the database
use the auto-increment.
Just a hint: when your application is choosing the values to put for an autoincrement value, you are probably doing something wrong.
If I have an insert statement with a bunch of values where the first value is an id that's also the primary key to my database, how can I check if everything else in those values is not completely the same and to update the fields that are different? (second part not necessary for an answer, but it'd be nice. If it's too convoluted to do the second part I can just delete the record first and then insert the full line of updated values)
I'm guessing that it has something to do with SELECT FROM TABLE1 * WHERE id=1 and then somehow do an inequality statement with the INSERT INTO TABLE1 VALUES ('1','A'... etc.) but I'm not sure how to write that.
Edit: I think I asked the question wrong so I'll try again:
I have a database that has first column id that is a primary key and then a lot of other columns, too long to type out by hand. I have a script that will get data and I will not know if this data is a duplicate or not e.g.
id value
1 dog
2 cat
if the new info coming in is "1, dog" then I need a signal (say boolean) that tells me true, if the new info is "1, monkey" then I need a signal that tells me false on the match and then update every single field. The question is how do I generate the boolean value that tells me whether the new values with the same id is completely identical to the one in the db? (It has to check every single filed of long list of fields that will take forever to type out, any type of output would be good as long as I can tell one means it's different and one means it's the same)
A side question is how do I update the row after that since I don't want to type out every single field, my temporary solution is to delete the row with the out of date primary id and then insert the new data in but if there is a fast way to update all columns in a row that'd be great.
MySQL can do "on duplicate key update" as part of the insert statement:
INSERT INTO table (id, ...) VALUES ($id, ...)
ON DUPLICATE KEY UPDATE somefield=VALUES(somefield), ...=VALUES(...)
Simple and effective. You only specify the fields you want changed if there is a primary key duplication, and any other fields in the previously-existing record are left alone.
I want to update only one field in a mysql table.
I have an "ad_id" which is unique.
The field "mod_date" is a TIMESTAMPS field, which is the one I need to update.
UPDATE main_table
SET main_table.mod_date = NOW()
WHERE classified.ad_id = $ad_id";
I haven't tested this yet because I am afraid it might update all rows.
So I have two questions:
Is there anyway to prevent MySql to update more than 1 row?
Is this sql code correct for updating one row only?
Thanks
If ad_id is unique, it will only update one row (if $ad_id is valid, zero otherwise).
If your worried about an update like this, rewrite it as a select to confirm which rows it will operate on before running it.
Your query doesn't look like it would work as such because it checks for field ad_id in table classified which hasn't been defined in the statement. If this is just a partial query and you're joining the classified table somewhere in the query there's not enough info here to tell how many rows will be modified.
You can add LIMIT 1 to the end of the query to make it update only the first row the query finds, but if you're not sure what the query does the first row might not be the one you want to modify.
As a side note I do have to say that if you're afraid to try and see what the query does, it means that either you don't have a backup of the database or you're working directly with a production database, and both of those options sound pretty scary.
What's the relation between main_table and classified?
For example...
UPDATE header h
INNER JOIN detail d ON d.id_header = h.id_header
SET h.name = 'New name'
WHERE d.id_detail = 10
will update name in the header table for specific id_detail.
In your case if ad_id is unique then you can be sure that MySQL will update only one row.
I'm trying to keep the database tables for a project I'm working on nice and normalized, but I've run into a problem. I'm trying to figure out how I can insert a row into a table and then find out what the value of the auto_incremented id column was set to so that I can insert additional data into another table. I know there are functions such as mysql_insert_id which "get the ID generated from the previous INSERT operation". However, if I'm not mistaken mysql_insert_id just returns the ID of the very last operation. So, if the site has enough traffic this wouldn't necessarily return the ID of the query you want since another query could have been run between when you inserted the row and look for the ID. Is this understanding of mysql_insert_id correct? Any suggestions on how to do this are greatly appreciated. Thanks.
LAST_INSERT_ID() has session scope.
It will return the identity value inserted in the current session.
If you don't insert any rows between INSERT and LAST_INSERT_ID, then it will work all right.
Note though that for multiple value inserts, it will return the identity of the first row inserted, not the last one:
INSERT
INTO mytable (identity_column)
VALUES (NULL)
SELECT LAST_INSERT_ID()
--
1
INSERT
INTO mytable (identity_column)
VALUES (NULL), (NULL)
/* This inserts rows 2 and 3 */
SELECT LAST_INSERT_ID()
--
2
/* But this returns 2, not 3 */
You could:
A. Assume that won't be a problem and use mysql_insert_id
or
B. Include a timestamp in the row and retrieve the last inserted ID before inserting into another table.
The general solution to this is to do one of two things:
Create a procedural query that does the insert and then retrieves the last inserted id (using, ie. LAST_INSERT_ID()) and returns it as output from the query.
Do the insert, do another insert where the id value is something like (select myid from table where somecolumnval='val')
2b. Or make the select explicit and standalone, and then do the other inserts using that value.
The disadvantage to the first is that you have to write a proc for each of these cases. The disadvantage to the second is that some db engines don't accept that, and it clutters your code, and can be slow if you have to do a where on multiple columns.
This assumes that there may be inserts between your calls that you have no control over. If you have explicit control, one of the other solutions above is probably better.