1

クロス集計機能に問題があります。

私のテーブル「t」は

date;name;hour;cause;c_p
"2013-06-12";167;14;0;2
"2013-06-12";167;16;0;3
"2013-06-12";167;16;0;4
"2013-06-12";167;19;1;1
"2013-06-12";167;19;0;4

私はこの「ピボットテーブル」t_pivotを持っています

day;name;hour;cause_0;cause_1
"2013-06-12";167;14;2;0 -----sum(c_p)
"2013-06-12";167;16;7;0
"2013-06-12";167;19;4;1

SQLコードは

SELECT  * from crosstab (
    'SELECT  day,name,hour,cause, SUM(c_p) AS c_p
        FROM t
        GROUP BY 1,2,3,4
        ORDER BY 3 ',

     'SELECT DISTINCT cause 
         FROM i
         ORDER BY 1')

AS t_pivot (day date, name integer,hour integer, cause_0 integer,cause_1 integer)

クエリ結果は「ORDER BY」による1行テーブル

ORDER BY 3
"2013-06-12";167;14;4;1

ORDER BY 1, ORDER BY 2
"2013-06-12";167;14;7;1

エラーはどこにありますか? ありがとう。

4

2 に答える 2

1

そのcrosstab関数は、行 ID を保持する列が 1 つだけであることを期待しているようです。それが正しければ、日、名前、時間の 3 つの列があります。ただしcrosstab、追加の列も許可します。特別なものとして扱わず、結果に追加するだけです。

したがって、あなたのケースでは、これら 3 つの列を取得し、それらを 1 つだけとして表す必要があります。それが最善のアプローチかどうかはわかりませんが、rowコンストラクターを使用してそれを行いました (したがって、データ型を気にする必要はありません)。

SELECT  * from crosstab (                                           
    'select row(day,hour,name),day, hour, name, cause, sum(c_p) as c_p
     from t
     group by 2, 3, 4, 5
     order by 1',
    'VALUES(0),(1)')
AS t_pivot (row_name text, day date, hour int, name integer, cause_0 integer,cause_1 integer);

これにより、次のような結果が得られます。

      row_name       |    day     | hour | name | cause_0 | cause_1 
---------------------+------------+------+------+---------+---------
 (2013-06-12,14,167) | 2013-06-12 |   14 |  167 |       2 |      --
 (2013-06-12,16,167) | 2013-06-12 |   16 |  167 |       7 |      --
 (2013-06-12,19,167) | 2013-06-12 |   19 |  167 |       4 |       1
 (2013-06-13,14,167) | 2013-06-13 |   14 |  167 |      10 |      --
(4 rows)

最初の列について心配する必要はありません。実際には役に立たないので、削除するだけです。

SELECT day,hour,name,cause_0,cause_1 FROM (SELECT  * from crosstab (
    'select row(day,hour,name),day, hour, name, cause, sum(c_p) as c_p
     from t
     group by 2, 3, 4, 5
     order by 1',
    'VALUES(0),(1)')
AS t_pivot (row_name text, day date, hour int, name integer, cause_0 integer,cause_1 integer)) AS t;

もう一つ。VALUESの代わりに 2 番目の引数を使用したことに注意してSELECT DISTINCTください。これらが使用可能な唯一の値であると確信している場合は、より良いアプローチです。静的でない場合は、AS t_pivot ...も動的にする必要があります。

于 2013-09-12T14:53:58.330 に答える
1

私はcrosstab関数を使用しておらず、今はテストできません (sqlfiddle には tablefunc 拡張機能はありません) が、一般的に、そのようなピボットが必要な場合は単純な SQL を好みます:

select
    date,
    hour,
    sum(case when cause = 0 then c_p else 0 end) cause_0,
    sum(case when cause = 1 then c_p else 0 end) cause_1
from t
group by date, hour
order by hour

sql fiddle demo

今後はその方がメンテしやすく、読みやすいと思います(ただしこれは主観的な意見です)。

更新これは機能します(時間はrow_name、日付と名前がextra列として使用されます):

SELECT  * from crosstab (
    'select hour, date, name, cause, sum(c_p) as c_p
     from t
     group by 1, 2, 3, 4
     order by 1',
    'select distinct cause from t order by 1')
AS t_pivot (hour integer, date timestamp, name integer, cause_0 integer,cause_1 integer)

ドキュメントから:

source_sql は、データのソース セットを生成する SQL ステートメントです。このステートメントは、1 つの row_name 列、1 つのカテゴリ列、および 1 つの値列を返す必要があります。また、1 つ以上の「余分な」列がある場合もあります。row_name 列が最初である必要があります。カテゴリ列と値列は、この順序で最後の 2 つの列である必要があります。row_name と category の間の列はすべて「追加」として扱われます。「余分な」列は、同じrow_name値を持つすべての行で同じであると予想されます。

また

実際には、source_sql クエリは常に ORDER BY 1 を指定して、同じ row_name を持つ値がまとめられるようにする必要があります。ただし、グループ内のカテゴリの順序は重要ではありません。また、category_sql クエリの出力の順序が、指定された出力列の順序と一致していることを確認することが不可欠です。

于 2013-09-12T13:24:40.883 に答える