Question

Schema names: "C_GT_Master","C_GT_Master". My table name is items. Both schemas have the same table.

Fields: itemno, itemname, unitno.

I want to get details from items table in both schemas. Am using following code:

SELECT stckreport.* FROM public.crosstab('select itemname, ''GT'' anal,
itemno from  "C_GT_Master".items i 
union all 
select itemname, ''UnitNo'' anal,unitno from  "C_GT_Master".items i 
union all 
select itemname, ''New'' anal,itemno from  "G_New_Master".items i  
union all 
select itemname, ''UnitNo'' anal,unitno from  "G_New_Master".items i 
','select ''GT'' union all select ''New'' union all select ''UnitNo''') 
as stckreport 
(itemname text,GT text,New Text,UnitNo text)

This query returns:

 itemname  gt  new unitno
   AB           1    
   AB                1
   AB       1          
   AB                2

But I want:

itemname  gt   new  unitno
 AB             1    1
 AB       1          2

How to get that result using crosstab(). My real problem in a project is too big, so I explain it using this one table.

Am using PostgreSQL 9.1.

Was it helpful?

Solution

If I understood correctly and you want one row per schema, this modified crosstab() query should work:

SELECT  "schema", itemname, "GT", "New", "UnitNo"
FROM    public.crosstab($$
    SELECT 'c' || itemname, "C_GT_Master" AS sch, itemname
        , 'GT'::text AS anal, itemno FROM "C_GT_Master".items
    UNION ALL 
    SELECT 'c' || itemname, "C_GT_Master",  itemname
       , 'UnitNo', unitno FROM  "C_GT_Master".items
    UNION ALL 
    SELECT 'g' || itemname, "G_New_Master", itemname
        , 'New'   , itemno FROM  "G_New_Master".items
    UNION ALL 
    SELECT 'g' || itemname, "G_New_Master", itemname
        , 'UnitNo', unitno FROM  "G_New_Master".items
   ORDER BY 1$$

    ,$$VALUES ('GT'::text), ('New'), ('UnitNo')$$
   ) 
AS stckreport (
   item text, "schema" text, itemname text
 , "GT" text, "New" text, "UnitNo" text);

Major points

  • Add ORDER BY 1 in the first query string. That was your primary error.

  • I concatenate a hash for the schema to the itemname to a value to group by resulting in one row per (schema, itemname). In addition I add schema and itemname separately to have both in the result. Only select those in the outer SELECT for display. More details about "additional columns":
    Pivot on Multiple Columns using Tablefunc
    And about concatenating a row name:
    crosstab with 2 (or more) row names

  • Use dollar-quoting to make your life easier.

  • Use a VALUES expression for the second query string.

  • More details in my basic go-to answer for crosstab():
    PostgreSQL Crosstab Query

OTHER TIPS

Try to group by result on itemname & unitno column, following is example of sql server,

With CTE as
(
SELECT stckreport.* FROM public.crosstab('select itemname, ''GT'' anal,
itemno from  "C_GT_Master".items i 
union all 
select itemname, ''UnitNo'' anal,unitno from  "C_GT_Master".items i 
union all 
select itemname, ''New'' anal,itemno from  "G_New_Master".items i  
union all 
select itemname, ''UnitNo'' anal,unitno from  "G_New_Master".items i 
','select ''GT'' union all select ''New'' union all select ''UnitNo''') 
as stckreport 
(itemname text,GT text,New Text,UnitNo text)
)
select itemname,sum(DT),SUM(New),UnitNo from CTE
group by itemname,UnitNo
order by itemname,UnitNo
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top