Updating multiple rows with a value calculated from another column - sql

I have a table with a row that looks like this:
(2009123148498429, '...', '...')
The first part, id, is a timestamp followed by a random number. (needed to work with other parts in the system) The data already exists in the table.
I want to create a column, timestamp, and extract just the date (20091231) and update all the rows with the timestamp.
How can I do this for all the rows with SQL? (i.e. update them all with some sort of a function?)
What kind of default value should I assign the column to make sure that future inserts correctly extract the date?
UPDATE - Please read the comments by bobince in the first answered question by Jonathan Sampson on how we got to the answer. This is the final query that worked:
UPDATE table SET rdate=substring(convert(rid,char(20)),1,8);
The problem was that I was using substring as substring( str, 0, 8 ) whereas it should be substring( str, 1, 8 ). I guess we're all used to 0 as the beginning position! More info here on substring
Related to: multiple updates in mysql

SELECT SUBSTRING(colDate,0,8) as 'date'
FROM someTable
Or am I mistaken?
UPDATE someTable
SET newDateField = SUBSTRING(colDate,0,8)
Would likely work too. Untested.

Use a sub-select in your update (untested, and I've been using Firebird for too long, so someone check me here).
UPDATE MyTable AS TUpdate
SET MyNewField = (SELECT SUBSTRING(TSub.MyDateColumn,0,8)
FROM MyTable AS TSub
WHERE TSub.MyID = TUpdate.MyID);
As for future inserts correctly extracting the date, you're going to have to create a trigger on insert to extract the date for that record.

Need to use a subselect.
UPDATE someTable set timestamp = (SELECT SUBSTRING(colData, 0, 8) FROM someOriginalTable);
EDIT lc got me by a few seconds!

UPDATE tbl
SET
newDateField = SUBSTRING(CAST(sourceCol AS varchar), 0, 8)

Related

SQL delete objects having and id range

I want to create a function in sql server that take as input an id range and delete all the object in that range (included the start and the end).
Let's have for example:
delete_objects_with_id(id_start,id_end)
It will delete all the objects with the id in the range id_start and id_end.
The problem is that the id are of this form: id_start=2017-0001 id_end=2017-0050 is there a sql server function that iterate on a list given a range?
first_issue content id
2011-01-01 test 2011-0001
2012-10-01 test 2012-0001
2012-11-01 test 2012-0002
2012-11-01 test 2012-0003
No, there's no builtin SQL Server function that will iterate on a list given a range.
If the id values are always nine characters, in the format four numeric digits, a dash and four more digits, then a comparison to character strings would get you the id values.
That is, you could write a query (SQL SELECT statement) to return the id values in that range,
SELECT t.id
FROM myobjects t
WHERE t.id >= '2017-0001'
AND t.id <= '2017-0050'
ORDER BY t.id
and with that query, you could define a cursor loop, and loop through (iterate) through those id values returned.
If the id values aren't in a canonical format, then the range operation isn't necessarily going to work. You'd need a mechanism to convert the id values into values that are canonical, so you can do a range.
But I'm not getting why you would need (or want) to iterate, if by "objects" you are referring to "rows" in a table. If you can write a SELECT statement that returns those rows, you could write a DELETE statement using the same predicates, and delete the rows in one fell swoop.
DELETE
FROM myobjects
WHERE id >= '2017-0001'
AND id <= '2017-0050'
It's not at all clear what you are attempting to achieve, why you would need to "iterate". But a cursor loop is one way to do that.
Again, to answer the question you asked: No. There is no "sql server function that iterate on a list given a range"
There is a simple workaround, Just remove - character and cast id as BIGINT
(This will work assuming that the first part of the id is year value and the second part is an id for each year)
DELETE FROM TABLE_1
WHERE CAST(REPLACE(id,'-','') as BIGINT) >= CAST(REPLACE(id_start,'-','') as BIGINT)
AND CAST(REPLACE(id,'-','') as BIGINT) <= CAST(REPLACE(id_end,'-','') as BIGINT)
Or use BETWEEN
DELETE FROM TABLE_1
WHERE CAST(REPLACE(id,'-','') as BIGINT) BETWEEN CAST(REPLACE(id_start,'-','') as BIGINT)
AND CAST(REPLACE(id_end,'-','') as BIGINT)

How to update a part of the column data using replace function in SQL?

I am trying to update a table coulmn, the table has thousands of records.
Currently I am updating the table by running the following query manually for some of the records.
UPDATE MyTable
SET column = REPLACE(column, 'ABC', 'ABC9')
WHERE where column like ‘ABC%’
Now I am trying to generate a generic query to update the table by adding a letter '9' after the alphabets. Thanks for your help
Use PATINDEX and STUFF
Patindex - Helps you to identify the first occurrence of numeric character in the string
Stuff - Helps you to insert 9 before the first occurrence of numeric character in the string
UPDATE MyTable
SET column = stuff(column,patindex('%[0-9]%',column),0,'9')

UPDATE column with VARCHAR(2) 4000 byte value

I want to update a table with complex entries in a column and just a clause in the column without effecting other values.
Want to update #Rule number=0# to #Rule number=1# but without affecting other values in the column. Is this possible?
Are you looking for replace()? If dynamic_attributes is a string:
update t
set dynamic_attributes = replace(dynamic_attributes,
'#Rule number=0#',
'#Rule number=1#'
)
where dynamic_attributes like '%#Rule number=0#%';
Note: Strings may not be the best way to store such a list. You should consider a table with one row per customer_id and dynamic attribute.
Here it is:
UPDATE A
SET A.dynamic_attributes = REPLACE(A.dynamic_attributes,'#Rule number=0#','#Rule number=1#')
FROM yourtable AS A
WHERE A.dynamic_attributes LIKE '%#Rule number=0#%'

How to store part of a field value in another column in SQL

So I'm trying to get a part of a value from a column and insert that part into another column - new column. BOTH columns are in the same table. So what i want should look something like this:
id newColumn oldColumn
1 12 123 some text
2 24 246 some text
....
I know how to get 12 and 24 using SUBSTR, but how do i enter the data for each row in the table. Should i be using self-join or something else?
First you have to add new col using following command:-
ALTER TABLE TAB_NAME
ADD COLUMN COL_NAME(VARCHAR(10));
After that execute this command:-
UPDAET TAB_NAME
SET COL_NAME = SUBSTRING(OLDCOLUMN, 1, 2);
I think this might help you.
No need to join, it's just a plain UPDATE:
update tablename set newColumn = substring(oldColumn from 1 for 2)
substring is ANSI SQL, some dbms have substr and other versions.
The question is why you are doing this? What do you expect to find in newColumn if someone later updates oldColumn to another value? Maybe you should have a view instead, where newColumn always has up to date values?
Please get into the habit of ALWAYS specifying the DB engine you are using... It helps us to help you - we can provide more relevant answers.
You might want to consider using a calculated column as opposed to storing the information again.
In SQL Server you could do something like this
ALTER TABLE YourTable
ADD new_column as SUBSTRING(old_column, 1, 2);
This way you don't need to insert or update this column it is always consistent with the original column. and you just use it in your select statement in the usual way.
select new_column from YourTable

PostgreSQL select value and increment at once

I'm looking for a possible solution to the following. I have data stored in a table to keep track of a special increment number the customer wants in the DB. This is a special number they use internally.
What I would like to do is automatically increment this number in the table when I select it. So I don't have the problem of another transaction, from someone else using the system, using the same ID number.
So I want to select the current number and increment it by one at once so I don't have duplicates. How would I go about doing this if it is even possible?
UPDATE the_table
SET the_column = the_column + 1
WHERE qualifier = X
RETURNING the_column;
This ought to do the trick, with the caveat that it will return the new id rather than the old one:
UPDATE foo
SET id=nextval('foo_sequence')
WHERE ...
RETURNING *