Question

PostgreSQL function HOWTO return a table

Asked by: Beringhs

Hi experts!

I am currently rebuilding a reporting application using BIRT. Before developping to much, I want to be sure of the database software choice I will have to live with.

I started with mySQL, and could write a fairly sophisticated stored procedure pretty fast, based on my TSQL knowledge. Now I suspect postgreSQL to be even more efficent (and less risky in the future as not taken over yet by a major competitor). It seems to me that pgSQL has many more developping features, plus ready to use statistical functions that I need. I feel much more confident with its querying interface, too.

I had to struggle a lot, yesterday, to convert the MySQL stored proc into pgSQL. Learned about pure SQL not being able to declare variables, about case sensitivity, aso. As for now, even if still not perfect at all, my function is created.

However, it should return a dataset, and it does not. Calling the function returns an well known error message: "la requête n'a pas de destination pour les données résultantes", ie "no destination for the query results".

This is the last step I cannot overcome. Can anyone give me a hint?

In fact, I would be interested in reading a basic pgSQL function returning a dataset and how to call it.

Of course, I am also interested in knowing your opinion on postgres a a DBMS instead of MySQL, and if there are other open source choices to consider.

Thank you for your help!

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-10-16 at 00:42:11ID24817367
Tags

postgreSQL functiun table

,

mySQL

Topics

PostgreSQL Database

,

PL / SQL

Participating Experts
2
Points
500
Comments
8

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. postgreSQL
    Hi, I have just installed Apache Web Server + MySQL + PHP4. Now, I have downloaded postgreSQL (*.tgz file), how can I install (add) postgreSQL so that I can use postgreSQL or MySQL ? p/s: Full code pls.... as I am the beginner of PHP.., thanks :) All your reply will be app...
  2. PostgreSQL problem
    I have Red Hat 8 installed in my computer, then I upgraded to Red Hat 9, but I cann't make Postgresql service working, it tells me that there is an old format of the database, please upgrade the format... I tried to remove Postgresql and install it again, but with no luck, th...
  3. PostgreSQL on Windows
    Hi Experts Can PostgreSQL installed on windows? is there any tech resources/web ? Thanks Dishan
  4. Zeos and postgreSQL basics
    I have a PostgreSQL server running on a FreeBSD machine in my LAN. On it I have superuser access. So I can create databases, tables and so on. Now... with a simple example database, I'd like to test all the Zeos components on their pallete, to see what they do and what are th...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: cminearPosted on 2009-10-16 at 07:57:52ID: 25590161

It would be helpful if you had included your code that you're having trouble with, and an example of how you are calling it.

Also, what version of PostgreSQL are you using?  According to the documentation, 8.4 supports the return of a table from a function (http://www.postgresql.org/docs/8.4/interactive/sql-createfunction.html), but 8.3 and prior do not (http://www.postgresql.org/docs/8.3/interactive/sql-createfunction.html).  So if that functionality is important, you will need to work with 8.4.1 (current as of today).

There's a little danger of bias in the question about opinion of PostgreSQL over Mysql, if you only ask the 'PostgreSQL Database' zone.  Still, I'll give my response.  When I started developing the database that I still administer, it originally used Mysql.  This was because I was adapting the application code from another group, and they were already using Mysql.  I had initially put migrating to PostgreSQL on the backburner because there were enough hurdles that I couldn't just do a drop-in replacement.  (Primarily the lack of a boolean type in Mysql was the hiccup.)  Well, at some point I started having trouble with how the application was behaving.  It turned out that the field for storing hashed passwords was supposed to be 40 characters long; however, in my database it was only _4_ characters.  Now I can't say if the configuration error was my mistake or something I inherited from the other group, but the fact that Mysql was silently dropping 36 characters since the first day I started working with it scared me; I was working on a database application, where I wanted some trust in the data being stored.  Finding that out, I changed over to PostgreSQL as fast as I could.  

 

by: BeringhsPosted on 2009-10-16 at 08:10:19ID: 25590294

Thank you.

You are right, and you are right again and again.

As for the bias of my question, I will try to modify the thread to register in mySQL too... Thank you for your experience anyway. Very much the kind of stuff I am expecting.

Using 8.4, and completely new to it. This is why I forgot that "detail". Sorry.

Here is the function call:

********************
select * from eGap_Evolution(
25,
2,
'1',
'2',
4
)
********************

Here are the pg messages provides :

--------------------
NOTICE:  la table « tmproute » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpRoute »
PL/pgSQL function "egap_evolution" line 41 at instruction SQL
NOTICE:  la table « tmpsection » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpSection »
PL/pgSQL function "egap_evolution" line 42 at instruction SQL
NOTICE:  la table « tmpsummary » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpSummary »
PL/pgSQL function "egap_evolution" line 43 at instruction SQL
NOTICE:  la table « tmpairline » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpAirline »
PL/pgSQL function "egap_evolution" line 44 at instruction SQL
NOTICE:  la table « tmpquestion » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpQuestion »
PL/pgSQL function "egap_evolution" line 45 at instruction SQL
NOTICE:  la table « tmpsummarycomp » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpSummaryComp »
PL/pgSQL function "egap_evolution" line 46 at instruction SQL
NOTICE:  la table « tmpstats » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpStats »
PL/pgSQL function "egap_evolution" line 47 at instruction SQL
NOTICE:  la table « tmpvals » n'existe pas, poursuite du traitement
CONTEXT:  instruction SQL « drop table IF EXISTS tmpVals »
PL/pgSQL function "egap_evolution" line 48 at instruction SQL
ERREUR:  la requête n'a pas de destination pour les données résultantes
HINT:  Si vous voulez annuler les résultats d'un SELECT, utilisez PERFORM à la place.
CONTEXT:  fonction PL/pgsql « egap_evolution », ligne 307 à instruction SQL

********** Error **********

ERREUR: la requête n'a pas de destination pour les données résultantes
SQL state: 42601
Hint: Si vous voulez annuler les résultats d'un SELECT, utilisez PERFORM à la place.
Context: fonction PL/pgsql « egap_evolution », ligne 307 à instruction SQL

----------------------------

And here is the function. Don't hit me: lots of stuff is just a trial and error to have pg at least building the function. If you are kind enough to go through it...

**********************
CREATE or replace function eGap_Evolution(
int,
int,
character varying(100),
character varying(100),
int
) returns table(
MeanHit character varying(10),
T2BHit character varying(10),
XLHit character varying(10),
B2BHit character varying(10),
ALID int,
quarter  int,
pos int,
Mean double precision,
T2Bw double precision,
T2B double precision,
B2Bw double precision,
B2B double precision,
XLw double precision,
XL double precision,
VGw double precision,
VG double precision,
Gw double precision,
G double precision,
Pw double precision,
P double precision,
VPw double precision,
VP double precision,
Base int,
WeightedBase double precision,
EffectiveBase double precision,
StdDeviation double precision,

compMean double precision,
compT2Bw double precision,
compT2B double precision,
compB2Bw double precision,
compB2B double precision,
compXLw double precision,
compXL double precision,

compWeightedBase double precision,
compEffectiveBase double precision,
compStdDeviation double precision
)

as $$

/*-------------------------------------------------------*/
/*Alias "input variable names*/
/*-------------------------------------------------------*/
declare ALID alias for $1;
declare QID alias for $2;
declare inRoutes alias for $3;
declare inSections alias for $4;
declare "Shift" alias for $5;

/*-------------------------------------------------------*/
/*map multiparameters to workable parameters */
/*(pg does not allow modifying their content in the function)*/
/*-------------------------------------------------------*/

declare Routes character varying(100);
declare Sections character varying(100);

/*-------------------------------------------------------*/
/*other variables*/
/*-------------------------------------------------------*/

declare Param character varying(5);
declare MinMean double precision;
declare MinT2B double precision;
declare MinXL double precision;
declare MinB2B double precision;
declare MaxMean double precision;
declare MaxT2B double precision;
declare MaxXL double precision;
declare MaxB2B double precision;

begin

/*-------------------------------------------------------*/
/*take care of multi parameters*/
/*-------------------------------------------------------*/
Routes = inRoutes;
Sections = inSections;

drop table IF EXISTS tmpRoute;
drop table IF EXISTS tmpSection;
drop table IF EXISTS tmpSummary;
drop table IF EXISTS tmpAirline;
drop table IF EXISTS tmpQuestion;
drop table IF EXISTS tmpSummaryComp;
drop table IF EXISTS tmpStats;
drop table IF EXISTS tmpVals;

/*-------------------------------------------------------*/
/*store parameters in temporary tables for efficency*/
/*as "joins are much faster than where clauses*/
/*-------------------------------------------------------*/

create temporary table tmpRoute(myParam int);
create temporary table tmpSection(myParam int);
create temporary table tmpAirline(myParam int);
create temporary table tmpQuestion(myParam int);

if ALID = 0 then
  insert into tmpAirline(myParam) (select id from vw_airlines);
else
  insert into tmpAirline(myParam) values(ALID);
end if;

insert into tmpQuestion(myParam) values(QID);

Param = substring(Routes from 1 for 1);

while Param <> '' loop

  insert into tmpRoute(myParam) values(cast(Param as int));

  if length(Routes) > 1 then Routes = substring(Routes from 3);
    else Routes = ''; end if;
  Param = substring(Routes from 1 for 1);
end loop;

Param = substring(Sections, 1);

while Param <> '' loop

  insert into tmpSection(myParam) values(cast(Param as int));

  if length(Sections) > 1 then Sections = substring(Sections, 3);
    else Sections = ''; end if;
  Param = substring(Sections, 1);
end loop;

/*-------------------------------------------------------*/
/*extract and store means by airlines*/
/*-------------------------------------------------------*/

CREATE TEMPORARY TABLE "tmpVals"

as

select

"tmpAirline"."myParam" as "ALID",

"interview"."quarter",

sum(answer.value) / sum(interview.weight) as "Mean",

sum(case when answer.value in (4,5) then interview.weight else 0 end) as "T2Bw",

sum(case when answer.value in (4,5) then interview.weight else 0 end) /  sum(interview.weight)  as "T2B",

sum(case when answer.value in (1,2) then interview.weight else 0 end)  as "B2Bw",

sum(case when answer.value in (1,2) then interview.weight else 0 end) /  sum(interview.weight)  as "B2B",

sum(case when answer.value = 5 then interview.weight else 0 end)

  as "XLw",

sum(case when answer.value = 5 then interview.weight else 0 end) /
  sum(interview.weight)

  as "XL",

sum(case when answer.value = 4 then interview.weight else 0 end)

  as "VGw",

sum(case when answer.value = 4 then interview.weight else 0 end) /
  sum(interview.weight)

  as "VG",

sum(case when answer.value = 3 then interview.weight else 0 end)

  as "Gw",

sum(case when answer.value = 3 then interview.weight else 0 end) /
  sum(interview.weight)

  as "G",

sum(case when answer.value = 2 then interview.weight else 0 end)

  as "Pw",

sum(case when answer.value = 2 then interview.weight else 0 end) /
  sum(interview.weight)

  as "P",

sum(case when answer.value = 1 then interview.weight else 0 end)

  as "VPw",

sum(case when answer.value = 1 then interview.weight else 0 end) /
  sum(interview.weight)

  as "VP",

count(interview.id) as "Base",

sum(interview.weight) as "WeightedBase",

POW(sum(interview.weight), 2) / sum(POW(interview.weight,2)) as "EffectiveBase",

SQRT((sum(interview.weight * POW(answer.value, 2))
 - POW(sum(interview.weight * answer.value), 2) /
 sum(interview.weight)) / (sum(interview.weight) - 1))

 as "StdDeviation"

from interview join answer
on answer.interview_id = interview.id

join "tmpSection"
on interview.section_bis_id = "tmpSection"."myParam"

join "tmpRoute"
on interview.route_id = "tmpRoute"."myParam"

join "tmpAirline"
on interview.airline_id = "tmpAirline"."myParam"

join "tmpQuestion"
on answer.question_id = "tmpQuestion"."myParam"

group by "tmpAirline"."myParam", interview.quarter
;

/*-------------------------------------------------------*/
/*store specific values*/
/*-------------------------------------------------------*/
Select min("Mean") into MinMean from "tmpVals";
Select min("T2B") into MinT2B from "tmpVals";
select min("XL") into MinXL from "tmpVals";
select min("B2B") into MinB2B from "tmpVals";
select max("Mean") into MaxMean from "tmpVals";
select max("T2B") into MaxT2B from "tmpVals";
select max("XL") into MaxXL from "tmpVals";
select max("B2B") into MaxB2B from "tmpVals";

/*-------------------------------------------------------*/
/*Summarize*/
/*-------------------------------------------------------*/
CREATE TEMPORARY TABLE "tmpSummary"

as

select

case when "Mean" = MinMean then 'Min' else case when "Mean" = MaxMean then 'Max' else '' end end as "MeanHit",
case when "T2B" = MinT2B then 'Min' else case when "T2B" = MaxT2B then 'Max' else '' end end as "T2BHit",
case when "XL" = MinXL then 'Min' else case when "XL" = MaxXL then 'Max' else '' end end as "XLHit",
case when "B2B" = MinB2B then 'Min' else case when "B2B" = MaxB2B then 'Max' else '' end end as "B2BHit",
rank() over(order by quarter) AS rnk,
"ALID",
v."quarter",
"Mean",
"T2Bw",
"T2B",
"B2Bw",
"B2B",
"XLw",
"XL",
"VGw",
"VG",
"Gw",
"G",
"Pw",
"P",
"VPw",
"VP",
"Base",
"WeightedBase",
"EffectiveBase",
"StdDeviation"

from "tmpVals" v
;


/*-------------------------------------------------------*/
/*Duplicate temporary table for join with comparable quarter*/
/*-------------------------------------------------------*/
create temporary table "tmpSummaryComp"

as

select * from "tmpSummary";

/*-------------------------------------------------------*/
/*Prepare significance tests*/
/*-------------------------------------------------------*/

create temporary table "tmpStats"

as

select

s."MeanHit",
s."T2BHit",
s."XLHit",
s."B2BHit",
s."ALID",
s."quarter",
s.rnk,
s."Mean",
s."T2Bw",
s."T2B",
s."B2Bw",
s."B2B",
s."XLw",
s."XL",
s."VGw",
s."VG",
s."Gw",
s."G",
s."Pw",
s."P",
s."VPw",
s."VP",
s."Base",
s."WeightedBase",
s."EffectiveBase",
s."StdDeviation",

c."Mean" as "compMean",
c."T2Bw" as "compT2Bw",
c."T2B" as "compT2B",
c."B2Bw" as "compB2Bw",
c."B2B" as "compB2B",
c."XLw" as "compXLw",
c."XL" as "compXL",

c."WeightedBase" as "compWeightedBase",
c."EffectiveBase" as "compEffectiveBase",
c."StdDeviation" as "compStdDeviation"

from "tmpSummary" s left join "tmpSummaryComp" c
on c.rnk = (s.rnk - "Shift")
;

/*-------------------------------------------------------*/
/*Return result set*/
/*-------------------------------------------------------*/

select

"MeanHit",
"T2BHit",
"XLHit",
"B2BHit",
"rnk",
"ALID",
"quarter",
"Mean",
"T2Bw",
"T2B",
"B2Bw",
"B2B",
"XLw",
"XL",
"VGw",
"VG",
"Gw",
"G",
"Pw",
"P",
"VPw",
"VP",
"Base",
"WeightedBase",
"EffectiveBase",
"StdDeviation",
"EffectiveBase" + "compEffectiveBase" -1 as "DOF",

("Mean" - "compMean") /
sqrt(
(
(("EffectiveBase" - 1) * POW("StdDeviation", 2) + ("compEffectiveBase" - 1) * POW("compStdDeviation", 2)) /
("EffectiveBase" + "compEffectiveBase" - 2)
) *
(1 / "EffectiveBase" + 1 / "compEffectiveBase")
)

as "tMean",

("T2B" - "compT2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
sqrt(
(((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase"))) /
 (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))
)
 as "tT2B",


("XL" - "compXL" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
sqrt(
(((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compXLw" + "XLw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compXLw" + "XLw") / ("compWeightedBase" + "WeightedBase"))) /
 (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))
)

 as "tXL",

("B2B" - "compB2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
sqrt(
(((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compB2Bw" + "B2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compB2Bw" + "B2Bw") / ("compWeightedBase" + "WeightedBase"))) /
 (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))
)
 as "tB2B"

 from "tmpStats" s;

/*-------------------------------------------------------*/
/*Clean temporary tables*/
/*-------------------------------------------------------*/
drop table IF EXISTS "tmpRoute";
drop table IF EXISTS "tmpSection";
drop table IF EXISTS "tmpAirline";
drop table IF EXISTS "tmpQuestion";
drop table IF EXISTS "tmpSummary";
drop table IF EXISTS "tmpSummaryComp";
drop table IF EXISTS "tmpStats";
drop table IF EXISTS "tmpVals";

end $$ LANGUAGE plpgsql;
**********************

Have a nice week-end anyway.

Vincent

 

by: earthman2Posted on 2009-10-17 at 03:17:32ID: 25595443

PostgreSQL 8.4 has RETURN QUERY syntax.
For assignment use ":=" not comparison operator "=".
Only need one declare statement
can put alias into parameter list
check you can drop temporary tables.
white space is your friend.
call using
select * from eGap_Evolution( 1,2,'ABCDEFGHI'.....);

CREATE or replace function eGap_Evolution( ALID int, QID int, inRoutes character varying(100), inSections character varying(100), "Shift" int ) returns
table (
  MeanHit           character varying(10),
  T2BHit            character varying(10),
  XLHit             character varying(10),
  B2BHit            character varying(10),
  ALID              int,
  quarter           int,
  pos               int,
  Mean              double precision,
  T2Bw              double precision,
  T2B               double precision,
  B2Bw              double precision,
  B2B               double precision,
  XLw               double precision,
  XL                double precision,
  VGw               double precision,
  VG                double precision,
  Gw                double precision,
  G                 double precision,
  Pw                double precision,
  P                 double precision,
  VPw               double precision,
  VP                double precision,
  Base              int,
  WeightedBase      double precision,
  EffectiveBase     double precision,
  StdDeviation      double precision,
  compMean          double precision,
  compT2Bw          double precision,
  compT2B           double precision,
  compB2Bw          double precision,
  compB2B           double precision,
  compXLw           double precision,
  compXL            double precision,
  compWeightedBase  double precision,
  compEffectiveBase double precision,
  compStdDeviation  double precision ) as $$
declare
  Routes   character varying(100);
  Sections character varying(100);

  Param character varying(5);
  MinMean double precision;
  MinT2B  double precision;
  MinXL   double precision;
  MinB2B  double precision;
  MaxMean double precision;
  MaxT2B  double precision;
  MaxXL   double precision;
  MaxB2B  double precision;

begin
  /* multiparameters */
  Routes   := inRoutes;
  Sections := inSections;

  drop table IF EXISTS tmpRoute;
  drop table IF EXISTS tmpSection;
  drop table IF EXISTS tmpSummary;
  drop table IF EXISTS tmpAirline;
  drop table IF EXISTS tmpQuestion;
  drop table IF EXISTS tmpStats;
  drop table IF EXISTS tmpVals;

  create temporary table tmpRoute(myParam int);
  create temporary table tmpSection(myParam int);
  create temporary table tmpAirline(myParam int);
  create temporary table tmpQuestion(myParam int);

  if ALID = 0 then
    insert into tmpAirline(myParam) (select id from vw_airlines);
  else
    insert into tmpAirline(myParam) values(ALID);
  end if;

  insert into tmpQuestion(myParam) values(QID);

  Param = substring(Routes from 1 for 1);

  while Param <> '' loop
    insert into tmpRoute(myParam) values(cast(Param as int));
    if length(Routes) > 1 then Routes = substring(Routes from 3); else Routes = ''; end if;
    Param = substring(Routes from 1 for 1);
  end loop;

  Param = substring(Sections, 1);

  while Param <> '' loop
    insert into tmpSection(myParam) values(cast(Param as int));
    if length(Sections) > 1 then Sections = substring(Sections, 3);
      else Sections = ''; end if;
    Param = substring(Sections, 1);
  end loop;

  /* means by airline */
  CREATE TEMPORARY TABLE "tmpVals" as select
    "tmpAirline"."myParam"                                                                         as "ALID",
    "interview"."quarter",
    sum(answer.value) / sum(interview.weight)                                                      as "Mean",
    sum(case when answer.value in (4,5) then interview.weight else 0 end)                          as "T2Bw",
    sum(case when answer.value in (4,5) then interview.weight else 0 end) / sum(interview.weight)  as "T2B",
    sum(case when answer.value in (1,2) then interview.weight else 0 end)                          as "B2Bw",
    sum(case when answer.value in (1,2) then interview.weight else 0 end) /  sum(interview.weight) as "B2B",
    sum(case when answer.value = 5 then interview.weight else 0 end)                               as "XLw",
    sum(case when answer.value = 5 then interview.weight else 0 end) / sum(interview.weight)       as "XL",
    sum(case when answer.value = 4 then interview.weight else 0 end)                               as "VGw",
    sum(case when answer.value = 4 then interview.weight else 0 end) / sum(interview.weight)       as "VG",
    sum(case when answer.value = 3 then interview.weight else 0 end)                               as "Gw",
    sum(case when answer.value = 3 then interview.weight else 0 end) / sum(interview.weight)       as "G",
    sum(case when answer.value = 2 then interview.weight else 0 end)                               as "Pw",
    sum(case when answer.value = 2 then interview.weight else 0 end) / sum(interview.weight)       as "P",
    sum(case when answer.value = 1 then interview.weight else 0 end)                               as "VPw",
    sum(case when answer.value = 1 then interview.weight else 0 end) / sum(interview.weight)       as "VP",
    count(interview.id)                                                                            as "Base",
    sum(interview.weight)                                                                          as "WeightedBase",
    POW(sum(interview.weight), 2) / sum(POW(interview.weight,2))                                   as "EffectiveBase",
    SQRT((sum(interview.weight * POW(answer.value, 2)) - POW(sum(interview.weight * answer.value), 2) / sum(interview.weight)) / (sum(interview.weight) - 1)) as "StdDeviation"
  from interview
    join answer        on answer.interview_id      = interview.id
    join "tmpSection"  on interview.section_bis_id = "tmpSection"."myParam"
    join "tmpRoute"    on interview.route_id       = "tmpRoute"."myParam"
    join "tmpAirline"  on interview.airline_id     = "tmpAirline"."myParam"
    join "tmpQuestion" on answer.question_id       = "tmpQuestion"."myParam"
  group by "tmpAirline"."myParam", interview.quarter;

  /* store specific values */
  Select min( "Mean") into MinMean from "tmpVals";
  Select min( "T2B" ) into MinT2B  from "tmpVals";
  select min( "XL"  ) into MinXL   from "tmpVals";
  select min( "B2B" ) into MinB2B  from "tmpVals";
  select max( "Mean") into MaxMean from "tmpVals";
  select max( "T2B" ) into MaxT2B  from "tmpVals";
  select max( "XL"  ) into MaxXL   from "tmpVals";
  select max( "B2B" ) into MaxB2B  from "tmpVals";

  /* Summarize */
  CREATE TEMPORARY TABLE "tmpSummary" as select
    case when "Mean" = MinMean then 'Min' else case when "Mean" = MaxMean then 'Max' else '' end end as "MeanHit",
    case when "T2B"  = MinT2B  then 'Min' else case when "T2B"  = MaxT2B  then 'Max' else '' end end as "T2BHit",
    case when "XL"   = MinXL   then 'Min' else case when "XL"   = MaxXL   then 'Max' else '' end end as "XLHit",
    case when "B2B"  = MinB2B  then 'Min' else case when "B2B"  = MaxB2B  then 'Max' else '' end end as "B2BHit",
    rank() over(order by quarter) AS rnk,
    "ALID",
    v."quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw", "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation"
  from "tmpVals" v;

  /*  Prepare significance tests */
  create temporary table "tmpStats" as select
    s."MeanHit", s."T2BHit", s."XLHit", s."B2BHit", s."ALID", s."quarter", s.rnk, s."Mean", s."T2Bw", s."T2B", s."B2Bw", s."B2B",
    s."XLw", s."XL", s."VGw", s."VG", s."Gw", s."G", s."Pw", s."P", s."VPw", s."VP", s."Base", s."WeightedBase", s."EffectiveBase", s."StdDeviation",
    c."Mean" as "compMean", c."T2Bw" as "compT2Bw", c."T2B" as "compT2B", c."B2Bw" as "compB2Bw", c."B2B" as "compB2B", c."XLw" as "compXLw", c."XL" as "compXL",
    c."WeightedBase" as "compWeightedBase", c."EffectiveBase" as "compEffectiveBase", c."StdDeviation" as "compStdDeviation"
  from "tmpSummary" s left join "tmpSummary" c on c.rnk = (s.rnk - "Shift");

  /* Return result set*/
  RETURN QUERY select
    "MeanHit","T2BHit","XLHit", "B2BHit", "rnk", "ALID", "quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw",
    "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation",
    "EffectiveBase" + "compEffectiveBase" -1 as "DOF",

    ("Mean" - "compMean") /
    sqrt(((("EffectiveBase" - 1) * POW("StdDeviation", 2) + ("compEffectiveBase" - 1) * POW("compStdDeviation", 2)) /
    ("EffectiveBase" + "compEffectiveBase" - 2)) * (1 / "EffectiveBase" + 1 / "compEffectiveBase")) as "tMean",

    ("T2B" - "compT2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tT2B",

    ("XL" - "compXL" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compXLw" + "XLw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compXLw" + "XLw") / ("compWeightedBase" +     "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tXL",

    ("B2B" - "compB2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compB2Bw" + "B2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compB2Bw" + "B2Bw") / ("compWeightedBase" +   "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tB2B"
    from "tmpStats" s;

  /* Clean temporary tables */
  drop table IF EXISTS "tmpRoute";
  drop table IF EXISTS "tmpSection";
  drop table IF EXISTS "tmpAirline";
  drop table IF EXISTS "tmpQuestion";
  drop table IF EXISTS "tmpSummary";
  drop table IF EXISTS "tmpStats";
  drop table IF EXISTS "tmpVals";
  RETURN;
end $$ LANGUAGE plpgsql;

 

by: earthman2Posted on 2009-10-17 at 03:24:48ID: 25595480

also you do not need tmpSummaryComp you should be able to make a self referential join on tmpSummary.  Some :='s not corrected

CREATE or replace function eGap_Evolution( ALID int, QID int, inRoutes character varying(100), inSections character varying(100), "Shift" int ) returns
table (
  MeanHit           character varying(10),
  T2BHit            character varying(10),
  XLHit             character varying(10),
  B2BHit            character varying(10),
  ALID              int,
  quarter           int,
  pos               int,
  Mean              double precision,
  T2Bw              double precision,
  T2B               double precision,
  B2Bw              double precision,
  B2B               double precision,
  XLw               double precision,
  XL                double precision,
  VGw               double precision,
  VG                double precision,
  Gw                double precision,
  G                 double precision,
  Pw                double precision,
  P                 double precision,
  VPw               double precision,
  VP                double precision,
  Base              int,
  WeightedBase      double precision,
  EffectiveBase     double precision,
  StdDeviation      double precision,
  compMean          double precision,
  compT2Bw          double precision,
  compT2B           double precision,
  compB2Bw          double precision,
  compB2B           double precision,
  compXLw           double precision,
  compXL            double precision,
  compWeightedBase  double precision,
  compEffectiveBase double precision,
  compStdDeviation  double precision ) as $$
declare
  Routes   character varying(100);
  Sections character varying(100);

  Param character varying(5);
  MinMean double precision;
  MinT2B  double precision;
  MinXL   double precision;
  MinB2B  double precision;
  MaxMean double precision;
  MaxT2B  double precision;
  MaxXL   double precision;
  MaxB2B  double precision;

begin
  /* multiparameters */
  Routes   := inRoutes;
  Sections := inSections;

  drop table IF EXISTS tmpRoute;
  drop table IF EXISTS tmpSection;
  drop table IF EXISTS tmpSummary;
  drop table IF EXISTS tmpAirline;
  drop table IF EXISTS tmpQuestion;
  drop table IF EXISTS tmpStats;
  drop table IF EXISTS tmpVals;

  create temporary table tmpRoute(myParam int);
  create temporary table tmpSection(myParam int);
  create temporary table tmpAirline(myParam int);
  create temporary table tmpQuestion(myParam int);

  if ALID = 0 then
    insert into tmpAirline(myParam) (select id from vw_airlines);
  else
    insert into tmpAirline(myParam) values(ALID);
  end if;

  insert into tmpQuestion(myParam) values(QID);

  Param := substring(Routes from 1 for 1);

  while Param <> '' loop
    insert into tmpRoute(myParam) values(cast(Param as int));
    if length(Routes) > 1 then Routes = substring(Routes from 3); else Routes = ''; end if;
    Param = substring(Routes from 1 for 1);
  end loop;

  Param := substring(Sections, 1);

  while Param <> '' loop
    insert into tmpSection(myParam) values(cast(Param as int));
    if length(Sections) > 1 then Sections = substring(Sections, 3); else Sections = ''; end if;
    Param := substring(Sections, 1);
  end loop;

  /* means by airline */
  CREATE TEMPORARY TABLE "tmpVals" as select
    "tmpAirline"."myParam"                                                                         as "ALID",
    "interview"."quarter",
    sum(answer.value) / sum(interview.weight)                                                      as "Mean",
    sum(case when answer.value in (4,5) then interview.weight else 0 end)                          as "T2Bw",
    sum(case when answer.value in (4,5) then interview.weight else 0 end) / sum(interview.weight)  as "T2B",
    sum(case when answer.value in (1,2) then interview.weight else 0 end)                          as "B2Bw",
    sum(case when answer.value in (1,2) then interview.weight else 0 end) /  sum(interview.weight) as "B2B",
    sum(case when answer.value = 5 then interview.weight else 0 end)                               as "XLw",
    sum(case when answer.value = 5 then interview.weight else 0 end) / sum(interview.weight)       as "XL",
    sum(case when answer.value = 4 then interview.weight else 0 end)                               as "VGw",
    sum(case when answer.value = 4 then interview.weight else 0 end) / sum(interview.weight)       as "VG",
    sum(case when answer.value = 3 then interview.weight else 0 end)                               as "Gw",
    sum(case when answer.value = 3 then interview.weight else 0 end) / sum(interview.weight)       as "G",
    sum(case when answer.value = 2 then interview.weight else 0 end)                               as "Pw",
    sum(case when answer.value = 2 then interview.weight else 0 end) / sum(interview.weight)       as "P",
    sum(case when answer.value = 1 then interview.weight else 0 end)                               as "VPw",
    sum(case when answer.value = 1 then interview.weight else 0 end) / sum(interview.weight)       as "VP",
    count(interview.id)                                                                            as "Base",
    sum(interview.weight)                                                                          as "WeightedBase",
    POW(sum(interview.weight), 2) / sum(POW(interview.weight,2))                                   as "EffectiveBase",
    SQRT((sum(interview.weight * POW(answer.value, 2)) - POW(sum(interview.weight * answer.value), 2) / sum(interview.weight)) / (sum(interview.weight) - 1)) as "StdDeviation"
  from interview
    join answer        on answer.interview_id      = interview.id
    join "tmpSection"  on interview.section_bis_id = "tmpSection"."myParam"
    join "tmpRoute"    on interview.route_id       = "tmpRoute"."myParam"
    join "tmpAirline"  on interview.airline_id     = "tmpAirline"."myParam"
    join "tmpQuestion" on answer.question_id       = "tmpQuestion"."myParam"
  group by "tmpAirline"."myParam", interview.quarter;

  /* store specific values */
  Select min( "Mean") into MinMean from "tmpVals";
  Select min( "T2B" ) into MinT2B  from "tmpVals";
  select min( "XL"  ) into MinXL   from "tmpVals";
  select min( "B2B" ) into MinB2B  from "tmpVals";
  select max( "Mean") into MaxMean from "tmpVals";
  select max( "T2B" ) into MaxT2B  from "tmpVals";
  select max( "XL"  ) into MaxXL   from "tmpVals";
  select max( "B2B" ) into MaxB2B  from "tmpVals";

  /* Summarize */
  CREATE TEMPORARY TABLE "tmpSummary" as select
    case when "Mean" = MinMean then 'Min' else case when "Mean" = MaxMean then 'Max' else '' end end as "MeanHit",
    case when "T2B"  = MinT2B  then 'Min' else case when "T2B"  = MaxT2B  then 'Max' else '' end end as "T2BHit",
    case when "XL"   = MinXL   then 'Min' else case when "XL"   = MaxXL   then 'Max' else '' end end as "XLHit",
    case when "B2B"  = MinB2B  then 'Min' else case when "B2B"  = MaxB2B  then 'Max' else '' end end as "B2BHit",
    rank() over(order by quarter) AS rnk,
    "ALID",
    v."quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw", "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation"
  from "tmpVals" v;

  /*  Prepare significance tests */
  create temporary table "tmpStats" as select
    s."MeanHit", s."T2BHit", s."XLHit", s."B2BHit", s."ALID", s."quarter", s.rnk, s."Mean", s."T2Bw", s."T2B", s."B2Bw", s."B2B",
    s."XLw", s."XL", s."VGw", s."VG", s."Gw", s."G", s."Pw", s."P", s."VPw", s."VP", s."Base", s."WeightedBase", s."EffectiveBase", s."StdDeviation",
    c."Mean" as "compMean", c."T2Bw" as "compT2Bw", c."T2B" as "compT2B", c."B2Bw" as "compB2Bw", c."B2B" as "compB2B", c."XLw" as "compXLw", c."XL" as "compXL",
    c."WeightedBase" as "compWeightedBase", c."EffectiveBase" as "compEffectiveBase", c."StdDeviation" as "compStdDeviation"
  from "tmpSummary" s left join "tmpSummary" c on c.rnk = (s.rnk - "Shift");

  /* Return result set*/
  RETURN QUERY select
    "MeanHit","T2BHit","XLHit", "B2BHit", "rnk", "ALID", "quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw",
    "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation",
    "EffectiveBase" + "compEffectiveBase" -1 as "DOF",

    ("Mean" - "compMean") /
    sqrt(((("EffectiveBase" - 1) * POW("StdDeviation", 2) + ("compEffectiveBase" - 1) * POW("compStdDeviation", 2)) /
    ("EffectiveBase" + "compEffectiveBase" - 2)) * (1 / "EffectiveBase" + 1 / "compEffectiveBase")) as "tMean",

    ("T2B" - "compT2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tT2B",

    ("XL" - "compXL" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compXLw" + "XLw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compXLw" + "XLw") / ("compWeightedBase" +     "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tXL",

    ("B2B" - "compB2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compB2Bw" + "B2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compB2Bw" + "B2Bw") / ("compWeightedBase" +   "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tB2B"
    from "tmpStats" s;

  /* Clean temporary tables */
  drop table IF EXISTS "tmpRoute";
  drop table IF EXISTS "tmpSection";
  drop table IF EXISTS "tmpAirline";
  drop table IF EXISTS "tmpQuestion";
  drop table IF EXISTS "tmpSummary";
  drop table IF EXISTS "tmpStats";
  drop table IF EXISTS "tmpVals";
  RETURN;
end $$ LANGUAGE plpgsql;

 

by: earthman2Posted on 2009-10-17 at 03:33:26ID: 25595503

If performance is slow
set in postgresql.conf file
work_mem = some_bigger_value_in_MB

restart server

 

by: earthman2Posted on 2009-10-17 at 03:37:01ID: 25595511

CREATE or replace function eGap_Evolution( ALID int, QID int, inRoutes character varying(100), inSections character varying(100), "Shift" int ) returns
table (
  MeanHit           character varying(10),
  T2BHit            character varying(10),
  XLHit             character varying(10),
  B2BHit            character varying(10),
  ALID              int,
  quarter           int,
  pos               int,
  Mean              double precision,
  T2Bw              double precision,
  T2B               double precision,
  B2Bw              double precision,
  B2B               double precision,
  XLw               double precision,
  XL                double precision,
  VGw               double precision,
  VG                double precision,
  Gw                double precision,
  G                 double precision,
  Pw                double precision,
  P                 double precision,
  VPw               double precision,
  VP                double precision,
  Base              int,
  WeightedBase      double precision,
  EffectiveBase     double precision,
  StdDeviation      double precision,
  compMean          double precision,
  compT2Bw          double precision,
  compT2B           double precision,
  compB2Bw          double precision,
  compB2B           double precision,
  compXLw           double precision,
  compXL            double precision,
  compWeightedBase  double precision,
  compEffectiveBase double precision,
  compStdDeviation  double precision ) as $$
declare
  Routes   character varying(100);
  Sections character varying(100);

  Param character varying(5);
  MinMean double precision;
  MinT2B  double precision;
  MinXL   double precision;
  MinB2B  double precision;
  MaxMean double precision;
  MaxT2B  double precision;
  MaxXL   double precision;
  MaxB2B  double precision;

begin
  /* multiparameters */
  Routes   := inRoutes;
  Sections := inSections;

  drop table IF EXISTS tmpRoute;
  drop table IF EXISTS tmpSection;
  drop table IF EXISTS tmpSummary;
  drop table IF EXISTS tmpAirline;
  drop table IF EXISTS tmpQuestion;
  drop table IF EXISTS tmpStats;
  drop table IF EXISTS tmpVals;

  create temporary table tmpRoute(myParam int);
  create temporary table tmpSection(myParam int);
  create temporary table tmpAirline(myParam int);
  create temporary table tmpQuestion(myParam int);

  if ALID = 0 then
    insert into tmpAirline(myParam) (select id from vw_airlines);
  else
    insert into tmpAirline(myParam) values(ALID);
  end if;

  insert into tmpQuestion(myParam) values(QID);

  Param := substring(Routes from 1 for 1);

  while Param <> '' loop
    insert into tmpRoute(myParam) values(cast(Param as int));
    if length(Routes) > 1 then Routes := substring(Routes from 3); else Routes := ''; end if;
    Param := substring(Routes from 1 for 1);
  end loop;

  Param := substring(Sections, 1);

  while Param <> '' loop
    insert into tmpSection(myParam) values(cast(Param as int));
    if length(Sections) > 1 then Sections := substring(Sections, 3); else Sections := ''; end if;
    Param := substring(Sections, 1);
  end loop;

  /* means by airline */
  CREATE TEMPORARY TABLE "tmpVals" as select
    "tmpAirline"."myParam"                                                                         as "ALID",
    "interview"."quarter",
    sum(answer.value) / sum(interview.weight)                                                      as "Mean",
    sum(case when answer.value in (4,5) then interview.weight else 0 end)                          as "T2Bw",
    sum(case when answer.value in (4,5) then interview.weight else 0 end) / sum(interview.weight)  as "T2B",
    sum(case when answer.value in (1,2) then interview.weight else 0 end)                          as "B2Bw",
    sum(case when answer.value in (1,2) then interview.weight else 0 end) /  sum(interview.weight) as "B2B",
    sum(case when answer.value = 5 then interview.weight else 0 end)                               as "XLw",
    sum(case when answer.value = 5 then interview.weight else 0 end) / sum(interview.weight)       as "XL",
    sum(case when answer.value = 4 then interview.weight else 0 end)                               as "VGw",
    sum(case when answer.value = 4 then interview.weight else 0 end) / sum(interview.weight)       as "VG",
    sum(case when answer.value = 3 then interview.weight else 0 end)                               as "Gw",
    sum(case when answer.value = 3 then interview.weight else 0 end) / sum(interview.weight)       as "G",
    sum(case when answer.value = 2 then interview.weight else 0 end)                               as "Pw",
    sum(case when answer.value = 2 then interview.weight else 0 end) / sum(interview.weight)       as "P",
    sum(case when answer.value = 1 then interview.weight else 0 end)                               as "VPw",
    sum(case when answer.value = 1 then interview.weight else 0 end) / sum(interview.weight)       as "VP",
    count(interview.id)                                                                            as "Base",
    sum(interview.weight)                                                                          as "WeightedBase",
    POW(sum(interview.weight), 2) / sum(POW(interview.weight,2))                                   as "EffectiveBase",
    SQRT((sum(interview.weight * POW(answer.value, 2)) - POW(sum(interview.weight * answer.value), 2) / sum(interview.weight)) / (sum(interview.weight) - 1)) as "StdDeviation"
  from interview
    join answer        on answer.interview_id      = interview.id
    join "tmpSection"  on interview.section_bis_id = "tmpSection"."myParam"
    join "tmpRoute"    on interview.route_id       = "tmpRoute"."myParam"
    join "tmpAirline"  on interview.airline_id     = "tmpAirline"."myParam"
    join "tmpQuestion" on answer.question_id       = "tmpQuestion"."myParam"
  group by "tmpAirline"."myParam", interview.quarter;

  /* store specific values */
  Select min( "Mean") into MinMean from "tmpVals";
  Select min( "T2B" ) into MinT2B  from "tmpVals";
  select min( "XL"  ) into MinXL   from "tmpVals";
  select min( "B2B" ) into MinB2B  from "tmpVals";
  select max( "Mean") into MaxMean from "tmpVals";
  select max( "T2B" ) into MaxT2B  from "tmpVals";
  select max( "XL"  ) into MaxXL   from "tmpVals";
  select max( "B2B" ) into MaxB2B  from "tmpVals";

  /* Summarize */
  CREATE TEMPORARY TABLE "tmpSummary" as select
    case when "Mean" = MinMean then 'Min' else case when "Mean" = MaxMean then 'Max' else '' end end as "MeanHit",
    case when "T2B"  = MinT2B  then 'Min' else case when "T2B"  = MaxT2B  then 'Max' else '' end end as "T2BHit",
    case when "XL"   = MinXL   then 'Min' else case when "XL"   = MaxXL   then 'Max' else '' end end as "XLHit",
    case when "B2B"  = MinB2B  then 'Min' else case when "B2B"  = MaxB2B  then 'Max' else '' end end as "B2BHit",
    rank() over(order by quarter) AS rnk,
    "ALID",
    v."quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw", "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation"
  from "tmpVals" v;

  /*  Prepare significance tests */
  create temporary table "tmpStats" as select
    s."MeanHit", s."T2BHit", s."XLHit", s."B2BHit", s."ALID", s."quarter", s.rnk, s."Mean", s."T2Bw", s."T2B", s."B2Bw", s."B2B",
    s."XLw", s."XL", s."VGw", s."VG", s."Gw", s."G", s."Pw", s."P", s."VPw", s."VP", s."Base", s."WeightedBase", s."EffectiveBase", s."StdDeviation",
    c."Mean" as "compMean", c."T2Bw" as "compT2Bw", c."T2B" as "compT2B", c."B2Bw" as "compB2Bw", c."B2B" as "compB2B", c."XLw" as "compXLw", c."XL" as "compXL",
    c."WeightedBase" as "compWeightedBase", c."EffectiveBase" as "compEffectiveBase", c."StdDeviation" as "compStdDeviation"
  from "tmpSummary" s left join "tmpSummary" c on c.rnk = (s.rnk - "Shift");

  /* Return result set*/
  RETURN QUERY select
    "MeanHit","T2BHit","XLHit", "B2BHit", "rnk", "ALID", "quarter", "Mean", "T2Bw", "T2B", "B2Bw", "B2B", "XLw", "XL", "VGw", "VG", "Gw", "G", "Pw", "P", "VPw",
    "VP", "Base", "WeightedBase", "EffectiveBase", "StdDeviation",
    "EffectiveBase" + "compEffectiveBase" -1 as "DOF",

    ("Mean" - "compMean") /
    sqrt(((("EffectiveBase" - 1) * POW("StdDeviation", 2) + ("compEffectiveBase" - 1) * POW("compStdDeviation", 2)) /
    ("EffectiveBase" + "compEffectiveBase" - 2)) * (1 / "EffectiveBase" + 1 / "compEffectiveBase")) as "tMean",

    ("T2B" - "compT2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compT2Bw" + "T2Bw") / ("compWeightedBase" + "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tT2B",

    ("XL" - "compXL" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compXLw" + "XLw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compXLw" + "XLw") / ("compWeightedBase" +     "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tXL",

    ("B2B" - "compB2B" + abs((1 / "compEffectiveBase") + (1 / "EffectiveBase")) / 2) /
    sqrt((((1 / "compEffectiveBase") + (1 / "EffectiveBase")) * (("compB2Bw" + "B2Bw") / ("compWeightedBase" + "WeightedBase")) * (1 - ("compB2Bw" + "B2Bw") / ("compWeightedBase" +   "WeightedBase"))) /
    (1 - 1 / ("EffectiveBase" + "compEffectiveBase"))) as "tB2B"
    from "tmpStats" s;

  /* Clean temporary tables */
  drop table IF EXISTS "tmpRoute";
  drop table IF EXISTS "tmpSection";
  drop table IF EXISTS "tmpAirline";
  drop table IF EXISTS "tmpQuestion";
  drop table IF EXISTS "tmpSummary";
  drop table IF EXISTS "tmpStats";
  drop table IF EXISTS "tmpVals";
  RETURN;
end $$ LANGUAGE plpgsql;

 

by: BeringhsPosted on 2009-10-19 at 02:10:54ID: 31642807

Thank you very, very much. Your advice was most usefull and brought me to a wunning solution very easily.

As for my follow up:

1. postgreSQL users should stick to low case letters (this helped me to further implement the proposed solution).

2. Except when using its cache (executing the exact same query a second time), for my application, and with my very limited current knowledge of both systems, postgreSQL beats mySQL by far in speed (5 times faster to extract the same results the first time). I had to increase the mentioned memory parameter, though,

3. Using the cache, though, mySQL is 7 times faster than postgreSQL.

 

by: earthman2Posted on 2009-10-19 at 10:43:02ID: 25607291

consider increasing database cache size if it is limiting performance
parameter shared_buffers in postgresql.conf file.
see
http://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-SHARED-BUFFERS

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...