Frage

Using SQL Server 2008.

I have a table of grouped dimensions like the following

Group | Dim1 | Dim2 | ...
1        1      A
1        1      B
2        1      B
3        NULL   C
4        2      NULL

I Then have a fact table like

Amount | Dim1 | Dim2 | ...
 100      1      A
 280      2      NULL
 130      1      NULL
 170      1      C

I would like to aggregate the Amount in the fact table based on the groups of dimensions in the group table. Using GROUP BY CUBE it generates way to many rows for dimension combinations i don't need.

Expected result set would be like

Amount | Group | Dim1 | Dim2 | ...
 300       1      1      A
 200       1      1      B
 400       2      1      B
1000       3      NULL   C
 100       4      2      NULL

Where amount is aggregated from the fact table. SQL Fiddle link to example showing the GROUP BY CUBE result set that i want to restrict to only the groups of dimesnion values in the DimGroups table in the example.

War es hilfreich?

Lösung

You can join the result of the cube onto the DimGroup table. There are two problems. It's fairly simple to deal with joining on nulls. It's slightly harder to deal with the multiple meanings of null. Fortunately there's a Grouping function that can distinguish between an underlying null value and a null added by the cube.

This answer assumes that when you have a null in the DimGroup that you want the cube meaning - i.e. the aggregate over any underlying value.

Select
    d.GroupId,
    d.Dim1,
    d.Dim2,
    d.Dim3,
    total
From (
    Select
        sum(Amount) total,
        Dim1,
        Dim2,
        Dim3
    From
        FactTable
    Group By
        Cube(Dim1,Dim2,Dim3)
    Having -- exclude underlying values with unknown (null) dims
        (Dim1 Is Not Null or Grouping(Dim1) != 0) And
        (Dim2 Is Not Null or Grouping(Dim2) != 0) And
        (Dim3 Is Not Null or Grouping(Dim3) != 0)
    ) c
        inner join
    DimGroups d
        on (c.Dim1 = d.Dim1 Or (c.Dim1 Is Null and d.Dim1 Is Null)) And
           (c.Dim2 = d.Dim2 Or (c.Dim2 Is Null and d.Dim2 Is Null)) And
           (c.Dim3 = d.Dim3 Or (c.Dim3 Is Null and d.Dim3 Is Null))

SQL Fiddle

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top