4

PostgreSQL 9.4 の次のイベント データを検討してください。

      eventTime     | eventName
2015-09-25 18:00:00 | 'AAA'
2015-09-25 17:00:00 | 'BBB'
2015-09-25 16:00:00 | 'BBB'
2015-09-25 15:00:00 | 'BBB'
2015-09-25 14:00:00 | 'AAA'
2015-09-26 13:00:00 | 'CCC'
2015-09-26 12:00:00 | 'AAA'
2015-09-26 11:00:00 | 'BBB'
2015-09-26 10:00:00 | 'CCC'
2015-09-26 09:00:00 | 'BBB'
2015-09-27 08:00:00 | 'AAA'
2015-09-27 07:00:00 | 'CCC'
2015-09-27 05:00:00 | 'CCC'
2015-09-27 04:00:00 | 'CCC'
2015-09-27 03:00:00 | 'CCC'
2015-09-27 02:00:00 | 'AAA'

単一count()ベースのテーブルは単純ですが、たとえば次のようになります。

SELECT eventTime, count(1)
  from (SELECT data->>'eventName' as eventName,
        date_trunc('day', to_timestamp(data->>'timestamp','YYYY-MM-DDZHH24:MI:SS.MS')::timestamp without time zone) AS eventTime
        FROM sidetrack where (data->>'eventName' = 'AAA') IS TRUE) AS tmptab
GROUP BY eventTime
ORDER BY eventTime ASC

の 1 つの値の出現のみをカウントできますeventName。私は SQL の経験があまりなく、双方向度数分布表を作成する方法を見つけるのに苦労しています。この例では、結果は次のようになります。

     day    | 'AAA' | 'BBB' | 'CCC'
------------+-------+-------+-------
 2015-09-25 |    2  |    3  |    0
 2015-09-26 |    1  |    2  |    2
 2015-09-27 |    2  |    0  |    4

数値を持つ変数が を使用してカウントされる例がありますがwith_bucket()、それは文字列値フィールドには一般化されません。

WITH次のようなネストされた選択を試しました。

WITH
    foo AS (
        SELECT ...
    ),
    bar AS (
        SELECT ...
    FROM foo
    ),
SELECT *
FROM bar;

そして、外部JOINSを使用していますが、これをクラックすることはできません.

4

2 に答える 2

1

各列に CASE ステートメントを使用して一致の 1 を生成し、次にすべての行を合計することができます。

SELECT date_trunc('day', timestamp) AS time,
       SUM(CASE WHEN "eventName" = 'AAA' THEN 1 ELSE 0 END) AAA,
       SUM(CASE WHEN "eventName" = 'BBB' THEN 1 ELSE 0 END) BBB,
       SUM(CASE WHEN "eventName" = 'CCC' THEN 1 ELSE 0 END) CCC
FROM sidetrack
GROUP BY date_trunc('day', timestamp)
ORDER BY date_trunc('day', timestamp) ASC

テストする SQLfiddle。

于 2015-12-19T23:13:49.000 に答える
1

このクエリは、毎日のイベント数を選択します。

select day, event, count(*)
from (
    select 
        left(date_trunc('day', (data->>'timestamp')::timestamp)::text, 10) as day, 
        data->>'eventName' as event
    from sidetrack
    ) s
group by 1, 2
order by 1 asc, 2;

    day     | event | count 
------------+-------+-------
 2015-09-25 | AAA   |     2
 2015-09-25 | BBB   |     3
 2015-09-26 | AAA   |     1
 2015-09-26 | BBB   |     2
 2015-09-26 | CCC   |     2
 2015-09-27 | AAA   |     2
 2015-09-27 | CCC   |     4
(7 rows)

crosstab()関数でクエリを使用できます。

create extension if not exists tablefunc;

select * from crosstab (
    $q$
        select day, event, count(*)
        from (
            select 
                left(date_trunc('day', (data->>'timestamp')::timestamp)::text, 10) as day, 
                data->>'eventName' as event
            from sidetrack
            ) s
        group by 1, 2
        order by 1 asc
    $q$,
    $q$
        values ('AAA'), ('BBB'), ('CCC')
    $q$)
as ct (day text, "AAA" int, "BBB" int, "CCC" int);

    day     | AAA | BBB | CCC 
------------+-----+-----+-----
 2015-09-25 |   2 |   3 |    
 2015-09-26 |   1 |   2 |   2
 2015-09-27 |   2 |     |   4
(3 rows)
于 2015-12-19T23:24:26.030 に答える