Thread: using a correlated subquery in update

using a correlated subquery in update

From
Sean Davis
Date:
I have a table that has a column that has values like XM_29832.11 and I
want to do an update to take off the .11 part.  I can do this for a
single value using:

select substring('XM_29832.11' from '^([A-Z]*_[0-9*])');

However, how can I write an update to use the above as a subquery to
update the whole column at once?

Thanks,
Sean


Re: using a correlated subquery in update

From
Michael Fuhr
Date:
On Fri, Dec 03, 2004 at 08:18:27AM -0500, Sean Davis wrote:

> I have a table that has a column that has values like XM_29832.11 and I
> want to do an update to take off the .11 part.  I can do this for a
> single value using:
>
> select substring('XM_29832.11' from '^([A-Z]*_[0-9*])');

This query returns 'XM_2' -- is that what you want?  Your description
sounds like you'd want 'XM_29832'.  Or is the query wrong because
you typed it into the message instead of cutting and pasting it?

> However, how can I write an update to use the above as a subquery to
> update the whole column at once?

UPDATE foo SET value = substring(value FROM '^([A-Z]*_[0-9]*)');

I'd suggest making the update in a transaction so you can verify
that the changes are correct before committing them.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

Re: using a correlated subquery in update

From
Andrew Hammond
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michael Fuhr wrote:
| On Fri, Dec 03, 2004 at 08:18:27AM -0500, Sean Davis wrote:
|
|
|>I have a table that has a column that has values like XM_29832.11 and I
|>want to do an update to take off the .11 part.  I can do this for a
|>single value using:
|>
|>select substring('XM_29832.11' from '^([A-Z]*_[0-9*])');
|
|
| This query returns 'XM_2' -- is that what you want?  Your description
| sounds like you'd want 'XM_29832'.  Or is the query wrong because
| you typed it into the message instead of cutting and pasting it?
|
|
|>However, how can I write an update to use the above as a subquery to
|>update the whole column at once?
|
|
| UPDATE foo SET value = substring(value FROM '^([A-Z]*_[0-9]*)');
|
| I'd suggest making the update in a transaction so you can verify
| that the changes are correct before committing them.

It sounds like he just wants to truncate the '.11' from the end of a string.

BEGIN;

UPDATE foo
SET xm_value = substring(xm_value FOR char_length(xm_value) - 3)
WHERE xm_value LIKE '%.11';

Then do some SELECTs to confirm that you've got what you need and if so,

COMMIT;

- --
Andrew Hammond    416-673-4138    ahammond@ca.afilias.info
Database Administrator, Afilias Canada Corp.
CB83 2838 4B67 D40F D086 3568 81FC E7E5 27AF 4A9A
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFBsMKIgfzn5SevSpoRAheBAJ4skcRJwPaWsi2Mm+YilzwGt4CNdwCeJdAq
jNWkO2bOd7fTTb/FAo8ikFs=
=1XDe
-----END PGP SIGNATURE-----

Re: using a correlated subquery in update

From
Sean Davis
Date:
Thanks for the replies.  As Michael pointed out, I had the * on the
wrong side of the bracket (typo).  Then, I did exactly what was
suggested and got the result I wanted.

Sean

On Dec 3, 2004, at 2:46 PM, Andrew Hammond wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Michael Fuhr wrote:
> | On Fri, Dec 03, 2004 at 08:18:27AM -0500, Sean Davis wrote:
> |
> |
> |>I have a table that has a column that has values like XM_29832.11
> and I
> |>want to do an update to take off the .11 part.  I can do this for a
> |>single value using:
> |>
> |>select substring('XM_29832.11' from '^([A-Z]*_[0-9*])');
> |
> |
> | This query returns 'XM_2' -- is that what you want?  Your description
> | sounds like you'd want 'XM_29832'.  Or is the query wrong because
> | you typed it into the message instead of cutting and pasting it?
> |
> |
> |>However, how can I write an update to use the above as a subquery to
> |>update the whole column at once?
> |
> |
> | UPDATE foo SET value = substring(value FROM '^([A-Z]*_[0-9]*)');
> |
> | I'd suggest making the update in a transaction so you can verify
> | that the changes are correct before committing them.
>
> It sounds like he just wants to truncate the '.11' from the end of a
> string.
>
> BEGIN;
>
> UPDATE foo
> SET xm_value = substring(xm_value FOR char_length(xm_value) - 3)
> WHERE xm_value LIKE '%.11';
>
> Then do some SELECTs to confirm that you've got what you need and if
> so,
>
> COMMIT;
>
> - --
> Andrew Hammond    416-673-4138    ahammond@ca.afilias.info
> Database Administrator, Afilias Canada Corp.
> CB83 2838 4B67 D40F D086 3568 81FC E7E5 27AF 4A9A
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.5 (GNU/Linux)
>
> iD8DBQFBsMKIgfzn5SevSpoRAheBAJ4skcRJwPaWsi2Mm+YilzwGt4CNdwCeJdAq
> jNWkO2bOd7fTTb/FAo8ikFs=
> =1XDe
> -----END PGP SIGNATURE-----


Re: using a correlated subquery in update

From
Michael Fuhr
Date:
On Fri, Dec 03, 2004 at 02:46:16PM -0500, Andrew Hammond wrote:

> It sounds like he just wants to truncate the '.11' from the end of a string.

We don't know if all strings match that pattern exactly or if it
was just an example.  He might also need to strip '.5' and '.6789'.

> UPDATE foo
> SET xm_value = substring(xm_value FOR char_length(xm_value) - 3)
> WHERE xm_value LIKE '%.11';

That covers a specific case.  Here are some more general solutions
that might work (or might not, depending on the string format):

substring(xm_value FROM '(.+)\\.[0-9]+$')
rtrim(rtrim(xm_value, '0123456789'), '.')
split_part(xm_value, '.', 1)

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/