sql questions

Started by Nonameover 7 years ago5 messagesgeneral
Jump to latest
#1Noname
hamann.w@t-online.de

Hi,

a) I am running some select query
select ... order by ....
Now, I would like to preserver the ordering through further processing by adding a sequence number
Of course I can do:
create temp sequence mseq;
select xx.*, nextval('mseq') as ord from (select ... order by ....) xx;
drop sequence mseq;
Is there a simpler way (avoiding the create/drop parts)

b) can a sql function return the count of affected rows of some query?
create function merge_names(int, int) returns void as
$_$
update namelinks set nid = $2 where nid = $1;
-- want the affected rows of the above query
delete from names where nid = $1
-- return result here
$_$
language sql;

Best regards
Wolfgang Hamann

#2Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Noname (#1)
Re: sql questions

hamann.w@t-online.de wrote:

a) I am running some select query
select ... order by ....
Now, I would like to preserver the ordering through further processing by adding a sequence number
Of course I can do:
create temp sequence mseq;
select xx.*, nextval('mseq') as ord from (select ... order by ....) xx;
drop sequence mseq;
Is there a simpler way (avoiding the create/drop parts)

A window function would be the best thing:

SELECT ...,
row_number() OVER (ORDER BY ...)
FROM ...

b) can a sql function return the count of affected rows of some query?
create function merge_names(int, int) returns void as
$_$
update namelinks set nid = $2 where nid = $1;
-- want the affected rows of the above query
delete from names where nid = $1
-- return result here
$_$
language sql;

You cannot do it in an SQL function.

In PL/pgSQL you can use

GET DIAGNOSTICS avariable = ROW_COUNT;

Yours,
Laurenz Albe

--
Cybertec | https://www.cybertec-postgresql.com

#3Thiemo Kellner
thiemo@gelassene-pferde.biz
In reply to: Noname (#1)
Re: sql questions

Zitat von hamann.w@t-online.de:

a) I am running some select query
select ... order by ....
Now, I would like to preserver the ordering through further
processing by adding a sequence number
Of course I can do:
create temp sequence mseq;
select xx.*, nextval('mseq') as ord from (select ... order by ....) xx;
drop sequence mseq;
Is there a simpler way (avoiding the create/drop parts)

Can't you just do the ordering at the end of the processing? Maybe you
need to drag along the order by columns and just dump them at the very
end if applicable.

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

#4Brian Dunavant
brian@omniti.com
In reply to: Noname (#1)
Re: sql questions

On Fri, Jul 20, 2018 at 4:27 AM <hamann.w@t-online.de> wrote:

b) can a sql function return the count of affected rows of some query?
create function merge_names(int, int) returns void as
$_$
update namelinks set nid = $2 where nid = $1;
-- want the affected rows of the above query
delete from names where nid = $1
-- return result here
$_$
language sql;

Yes. You can do this in pure SQL by using CTEs like the following
example.

with myupdate as (
update test set a = 4 where a = 1
returning a
),
mydelete as (
delete from testnames where nid = 1
)
select count(1) from myupdate;

You can then just wrap a function around this. Full test case below.

-- Create test tables
create table test ( a integer );
insert into test values (1),(1),(3);
create table testnames ( nid integer );
insert into testnames values (1);

-- Update, delete, and return the number of updates in a single statement
create function test_names(integer, integer) returns bigint as
$_$
with myupdate as (
update test set a = $2 where a = $1
returning a
),
mydelete as (
delete from testnames where nid = $1
)
select count(1) from myupdate
$_$
language sql;

-- Run it
# select test_names(1,4);
test_names
------------
2
(1 row)

-- Verify results
=# select * from test;
a
---
3
4
4
(3 rows)

=# select * from testnames;
nid
-----
(0 rows)

#5Noname
hamann.w@t-online.de
In reply to: Thiemo Kellner (#3)
Re: sql questions

Zitat von hamann.w@t-online.de:

a) I am running some select query
select ... order by ....
Now, I would like to preserver the ordering through further
processing by adding a sequence number
Of course I can do:
create temp sequence mseq;
select xx.*, nextval('mseq') as ord from (select ... order by ....) xx;
drop sequence mseq;
Is there a simpler way (avoiding the create/drop parts)

Can't you just do the ordering at the end of the processing? Maybe you
need to drag along the order by columns and just dump them at the very
end if applicable.

Hi,

in this specific case every search result consists of a pair of related entries that are not close to each other in
ordering. So I order by first entry and use the row number to keep the second entry next to the first one,

BTW: the use case is scanning a database of people for duplicates. Whenever there are 3 or more
components in a name, the split betwwen first and last name can be ambiguous, and so its is common to find
both "Ludwig" "van Beethoven" and "Ludwig van" "Beethoven"

Best regards
WOlfgang