Thread: sql questions

sql questions

From
hamann.w@t-online.de
Date:

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



Re: sql questions

From
Laurenz Albe
Date:
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


Re: sql questions

From
Thiemo Kellner
Date:
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.


Attachment

Re: sql questions

From
Brian Dunavant
Date:
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)


 

Re: sql questions

From
hamann.w@t-online.de
Date:

>> 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