Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / DB2 Topics / November 2005

Tip: Looking for answers? Try searching our database.

User-defined aggregate function

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Larry Menard - 18 Nov 2005 03:43 GMT
  Folks,

  I know that DB2 does not (yet?) support this, but I wonder if anyone can suggest a work-around.

  I've seen article http://www-128.ibm.com/developerworks/db2/library/techarticle/dm-0504greenstein/, which was very helpful for developing the scalar functions I needed, but it does not cover how to emulate aggregate functions.

  And I've seen Knut's dW article (http://www-128.ibm.com/developerworks/db2/library/techarticle/0309stolze/0309sto
lze.html
), but frankly it's a bit advanced for me.  For example, AFAIK I don't need a UDT (do I?).

  Here's my scenario.

  I'm porting a PHP application that currently uses other DBs as a back-end.  This application has a query:

 SELECT BIT_OR(mycolumn) FROM ...

  The BIT_OR() aggregate function is my problem.

  The 'mycolumn' column is defined as VARCHAR(32) FOR BIT DATA.  The BIT_OR() function is supposed to do a bitwise OR of all of the values in that column.

  Can anyone offer any simple, to-the-point guidance on any way to accomplish this?  I'm using DB2 V8.2.2 on Windows XP.  I can write scalar UDFs all I want, but I'm limited as to the amount of major changes I can make to the SQL itself (most specifically, I can't bust it into multiple statements).

  Thanks.

  (Jeez, in this porting project I seem to be hitting everything that DB2 doesn't support.  And I'm not even getting paid for it!  ;-)

Signature

--------------------
Larry Menard
"Defender of Geese and of All Things Natural"

Serge Rielau - 18 Nov 2005 06:47 GMT
>    Folks,
>  
[quoted text clipped - 36 lines]
>    (Jeez, in this porting project I seem to be hitting everything that
> DB2 doesn't support.  And I'm not even getting paid for it!  ;-)

You can write a recursive query (WITH clause).

Cheers
Serge

Signature

Serge Rielau
DB2 SQL Compiler Development
IBM Toronto Lab

Larry Menard - 18 Nov 2005 14:57 GMT
  Thanks, Serge.  I was under the impression (reinforced by Knut's article)
that recursive queries should be avoided.

Signature

--------------------
Larry Menard
"Defender of Geese and of All Things Natural"

>>    Folks,
>>  I know that DB2 does not (yet?) support this, but I wonder if anyone can
[quoted text clipped - 29 lines]
> Cheers
> Serge
Knut Stolze - 21 Nov 2005 07:13 GMT
>    Thanks, Serge.  I was under the impression (reinforced by Knut's
>    article)
> that recursive queries should be avoided.

Really, I didn't want to say that.

And to answer your other question: no, you don't need structured types for
the aggregation.  That was just meant as an example.

Signature

Knut Stolze
DB2 Information Integration Development
IBM Germany

--CELKO-- - 18 Nov 2005 15:00 GMT
Generally speaking you can do aggregate function by putting expressions
into the SUM(), MIN(), or MAX() functions.  Here is a version of the
aggregate product function in SQL.  You will need to have the logorithm
and exponential functions.  They are not standards, but they are very
common.  The idea is that there are three special cases - all positive
numbers, one or more zeroes, and some negative numbers in the set.
Within the case where you have negative numbers, there are two
sub-cases: (1) an even number of negatives or (2) an odd number of
negatives.  You then need to apply some High School algebra to
determine the sign of the final result.

SELECT CASE MIN(ABS(SIGN(nbr)))
      WHEN 0 THEN 0.00  -- some zeroes
      ELSE              -- no zeroes
         EXP(SUM(LOG(ABS(NULLIF(nbr, 0)))))
         * CASE WHEN MOD (CAST(SUM(ABS(SIGN(nbr)-1)/2) AS INTEGER), 2)
= 1
       THEN -1.00 ELSE 1.00 END
END AS big_pi

However, in your particular situation, you are stuck because some diot
thought that SQL is a language for bit fiddling and not a high level
database language.   Nobody uses bits and bytes in SQL.  The real
problem is a completely scerewed up schema that needs to be re-done
properly from scratch.

>> And I'm not even getting paid for it! <<

No good deed goes unpunished.
Larry Menard - 18 Nov 2005 20:48 GMT
  Thanks Joe & Serge.

  I've boned up a bit more on UDFs (Don Chamberlin's "Complete Guide to DB2" book), and I think I should be able to implement this fairly easily using a java scalar SCRATCHPAD UDF.

  In Don's book he says (paraphrased):

    > In statement "SELECT foo(col1) FROM tb1", function "foo" is invoked for each value in column "col1".

  So I think that on each invocation, my UDF should:

 if (scratchpad is empty) then
 {
   simply copy all 32 bits of current row value into the scratchpad.
 }
 else
 {
   for (each bit of the current scratchpad string contents)
   {
     if (the appropriate bit in the scratchpad contents is already "non-0") then
     {
       nop.
     }
     else  // scratchpad bit must be "0"
     {
       if (the corresponding bit in the current row value is also "0") then
       {
         set the appropriate bit in the scratchpad string to "0".
       }
       else  // row value bit is "non-0"
       {
         set the appropriate bit in the scratchpad string to the value of the bit in the current row value.
       }
     }
   }
 }
 return (current scratchpad string)

  And the SQL invocation should remain pretty much unchanged:

 SELECT BIT_OR(mycolumn) FROM ...

  But I'm not 100% sure of one thing:

  Note that my UDF always returns the current scratchpad string.  If the UDF is re-invoked for each row value in the column, does the overall SQL statement ever see the returned values for the interim invocations, or does it see only the value returned by the last invocation?

  Thanks.

Signature

--------------------
Larry Menard
"Defender of Geese and of All Things Natural"

> Generally speaking you can do aggregate function by putting expressions
> into the SUM(), MIN(), or MAX() functions.  Here is a version of the
[quoted text clipped - 25 lines]
>
> No good deed goes unpunished.
Larry Menard - 18 Nov 2005 21:40 GMT
  Never mind, I take back my question.  Thanks.

Signature

--------------------
Larry Menard
"Defender of Geese and of All Things Natural"

    Thanks Joe & Serge.

    I've boned up a bit more on UDFs (Don Chamberlin's "Complete Guide to DB2" book), and I think I should be able to implement this fairly easily using a java scalar SCRATCHPAD UDF.

    In Don's book he says (paraphrased):

      > In statement "SELECT foo(col1) FROM tb1", function "foo" is invoked for each value in column "col1".

    So I think that on each invocation, my UDF should:

   if (scratchpad is empty) then
   {
     simply copy all 32 bits of current row value into the scratchpad.
   }
   else
   {
     for (each bit of the current scratchpad string contents)
     {
       if (the appropriate bit in the scratchpad contents is already "non-0") then
       {
         nop.
       }
       else  // scratchpad bit must be "0"
       {
         if (the corresponding bit in the current row value is also "0") then
         {
           set the appropriate bit in the scratchpad string to "0".
         }
         else  // row value bit is "non-0"
         {
           set the appropriate bit in the scratchpad string to the value of the bit in the current row value.
         }
       }
     }
   }
   return (current scratchpad string)

    And the SQL invocation should remain pretty much unchanged:

   SELECT BIT_OR(mycolumn) FROM ...

    But I'm not 100% sure of one thing:

    Note that my UDF always returns the current scratchpad string.  If the UDF is re-invoked for each row value in the column, does the overall SQL statement ever see the returned values for the interim invocations, or does it see only the value returned by the last invocation?

    Thanks.

 --
 --------------------
 Larry Menard
 "Defender of Geese and of All Things Natural"

 "--CELKO--" <jcelko212@earthlink.net> wrote in message news:1132326046.849049.55620@o13g2000cwo.googlegroups.com...
 > Generally speaking you can do aggregate function by putting expressions
 > into the SUM(), MIN(), or MAX() functions.  Here is a version of the
 > aggregate product function in SQL.  You will need to have the logorithm
 > and exponential functions.  They are not standards, but they are very
 > common.  The idea is that there are three special cases - all positive
 > numbers, one or more zeroes, and some negative numbers in the set.
 > Within the case where you have negative numbers, there are two
 > sub-cases: (1) an even number of negatives or (2) an odd number of
 > negatives.  You then need to apply some High School algebra to
 > determine the sign of the final result.
 >
 > SELECT CASE MIN(ABS(SIGN(nbr)))
 >       WHEN 0 THEN 0.00  -- some zeroes
 >       ELSE              -- no zeroes
 >          EXP(SUM(LOG(ABS(NULLIF(nbr, 0)))))
 >          * CASE WHEN MOD (CAST(SUM(ABS(SIGN(nbr)-1)/2) AS INTEGER), 2)
 > = 1
 >        THEN -1.00 ELSE 1.00 END
 > END AS big_pi
 >
 > However, in your particular situation, you are stuck because some diot
 > thought that SQL is a language for bit fiddling and not a high level
 > database language.   Nobody uses bits and bytes in SQL.  The real
 > problem is a completely scerewed up schema that needs to be re-done
 > properly from scratch.
 >
 >>> And I'm not even getting paid for it! <<
 >
 > No good deed goes unpunished.
 >
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.