1

我有一张如下所示的表格。

EMPNUM  EMPNAME     LOCATION    CATEGORY    COUNT
123     JOHN DOE    BLDG A      1           5
123     JOHN DOE    BLDG A      1           6
123     JOHN DOE    BLDG A      2           4
123     JOHN DOE    BLDG A      3           7
123     JOHN DOE    BLDG B      1           1
123     JOHN DOE    BLDG B      2           3
234     EMILY DOE   BLDG A      1           1
234     EMILY DOE   BLDG A      2           2
234     EMILY DOE   BLDG A      3           4
234     EMILY DOE   BLDG B      2           3
234     EMILY DOE   BLDG B      2           9
234     EMILY DOE   BLDG B      3           3

我想将它传输到将产生类似于下面的输出的列中。我需要根据 LOCATION 和 CATEGORY 的值得到 COUNT 的总和

EMPNUM  EMPNAME     SUM_A1  SUM_A2  SUM_A3  SUM_B1  SUM_B2  SUM_B3  
123     JOHN DOE    11      4       7       1       3       0
234     EMILY DOE   1       2       4       0       12      3   

有什么方法可以作为 SQL 查询来做到这一点?或在水晶报表中(虽然我更喜欢使用 SQL 输出)

4

3 回答 3

3

This will work providing the values in LOCATION and CATEGORY are constant:

select empnum
       , empname
       , sum(case when location='BLDG A' and category = 1 then count else 0 end) sum_a1 
       , sum(case when location='BLDG A' and category = 2 then count else 0 end) sum_a2
       , sum(case when location='BLDG A' and category = 3 then count else 0 end) sum_a3
       , sum(case when location='BLDG B' and category = 1 then count else 0 end) sum_b1
       , sum(case when location='BLDG B' and category = 2 then count else 0 end) sum_b2
       , sum(case when location='BLDG B' and category = 3 then count else 0 end) sum_b3
from your_table
group by empnum
       , empname

If the values are not known or not stable when you run the query you will need to use dynamic SQL.


Note that if you are on 11g you should employ A B Cade's PIVOT solution, which is more elegant.

于 2012-10-26T07:45:23.027 回答
3

如果您使用的是 11g 或更高版本,请尝试

select * from table1
PIVOT  (SUM("COUNT")         
        FOR ("LOCATION","CATEGORY") IN 
        (('BLDG A',1) AS sum_a1,
         ('BLDG A',2) AS sum_a2,
         ('BLDG A',3) AS sum_a3,
        ('BLDG B',1) AS sum_b1,
        ('BLDG B',2) AS sum_b2,
        ('BLDG B',3) AS sum_b3));

是一个小提琴

否则使用APC 的解决方案

于 2012-10-26T07:47:01.767 回答
0

如果您有已知数量的值要转换为列,则其他答案将非常有用。但是如果你有一个未知数,那么你可以使用动态 sql 来生成结果。

您将创建以下过程:

CREATE OR REPLACE procedure test_dynamic_pivot(p_cursor in out sys_refcursor)
as
    sql_query varchar2(1000) := 'select empnum, empname';

    begin
        for x in (select distinct location, category from yourtable order by 1)
        loop
            sql_query := sql_query ||
              ' , sum(case when location = '''||x.location||''' and category='||x.category||' then cnt else 0 end) as sum_'||substr(x.location, -1, 1)||x.category;

                dbms_output.put_line(sql_query);
        end loop;

        sql_query := sql_query || ' from yourtable group by empnum, empname';

        open p_cursor for sql_query;
    end;
/

然后执行它:

variable x refcursor
exec test_dynamic_pivot(:x)
print x

结果与硬编码版本相同:

| EMPNUM |   EMPNAME | SUM_A1 | SUM_A2 | SUM_A3 | SUM_B1 | SUM_B2 | SUM_B3 |
----------------------------------------------------------------------------
|    234 | EMILY DOE |      1 |      2 |      4 |      0 |     12 |      3 |
|    123 |  JOHN DOE |     11 |      4 |      7 |      1 |      3 |      0 |
于 2012-10-26T10:50:07.900 回答