-2

postgresql 9.1テーブルでクエリを実行しようとしていますが、関連する2つの列は次のとおりです。

occurred - timestamp with timezone
computer - varchar

テーブルが深夜から深夜までの24時間の期間をカバーし、各要素が1日のその時間に1台のコンピューターが持っていた行の数である24の長さのリストを取得する必要があると仮定します。WHERE条項のコンピューター名を取得します。

これまでの私のSQLは次のとおりです。

select extract(hour from occurred) as hr, count(where computer = "computername") 
    from tablename group by extract(hour from occurred) order by 1
4

2 に答える 2

2

たとえば、すべての日の05:00から06:00の間にコンピューターがアクティブだった回数のカウントを生成するのではなく、一度に1日のデータのみをカウントするように、このクエリを強化する必要があります。アクティブとして記録されたとき。また、コンピューターがまったくアクティブであると記録されていないときに、何時間もゼロカウントが生成されることを心配する必要があります。ただし、SQLを多かれ少なかれ機能するものに変更することはできます。

SELECT EXTRACT(HOUR FROM occurred) AS hr, COUNT(*) AS count
  FROM tablename
 WHERE computer = 'computername'  -- corrected (" ⟶ ')
 GROUP BY EXTRACT(HOUR FROM occurred)
 ORDER BY 1

構文的には、それは正しいと思います(私は思います)。

これは、特定の日付を定義するための多くの可能な方法の1つです。より信頼性の高いデータを取得するには、タイムゾーンを指定する必要がある場合があります。

SELECT EXTRACT(HOUR FROM occurred) AS hr, COUNT(*) AS count
  FROM tablename
 WHERE computer = 'computername'  -- corrected (" ⟶ ')
   AND occurred >= TIMESTAMP '2012-08-02 00:00:00'
   AND occurred <  TIMESTAMP '2012-08-03 00:00:00'
 GROUP BY EXTRACT(HOUR FROM occurred)
 ORDER BY 1

24時間の一部の時間帯にコンピューターのアクティビティがない場合でも、24時間すべてのデータを生成することは困難です。どういうわけか24時間のリストを作成し(さまざまな方法があります。PostgreSQLでどれが最も適切かはわかりません)、それをコンピューターアクティビティレコードの投影と外部結合します。

SELECT hh, COUNT(*)
  FROM hours_00_to_23 AS h
  LEFT JOIN
       (SELECT EXTRACT(HOUR FROM occurred) AS hh
          FROM tablename
         WHERE computer = 'computername'  -- corrected (" ⟶ ')
       ) AS a
    ON a.hh = h.hh
 GROUP BY hh
 ORDER BY hh

基準を組み合わせて、特定の日付などのデータを取得できます。

警告:この回答で想定されているSQLを実行しようとして、DBMSに悩まされることはありませんでした。

3番目の問題を修正する方法がわかりません。2行目に「hours_00_to_23」という関係を取得することはできません。

hh適切なタイプ(それ自体が興味深い質問—正しいタイプは何ですか)の列を含む(一時的な?)テーブルを作成する必要があります。値0から23が入力されます。考えられる厄介なブルートフォースソリューション(議論の余地のあるタイプ)は次のとおりです。 :

CREATE TABLE hours_00_to_23(hh INTEGER NOT NULL PRIMARY KEY);
INSERT INTO hours_00_to_23 VALUES(0);
INSERT INTO hours_00_to_23 VALUES(1);
...
INSERT INTO hours_00_to_23 VALUES(23);

同じ効果を達成する方法はおそらく他にもあります。

于 2012-08-03T15:29:33.117 に答える
2

あなたの質問は良い出発点です。値をピボットする必要があります。これが1つの方法です:

select computer,
       sum(case when hr = 1 then cnt else 0 end) as hr01,
       sum(case when hr = 2 then cnt else 0 end) as hr02,
       sum(case when hr = 3 then cnt else 0 end) as hr03,
       ...
       sum(case when hr = 24 then cnt else 0 end) as hr24
from (select computer, extract(hour from occurred) as hr, count(*) as cnt 
      from tablename
      group by computer extract(hour from occurred
     ) t
group by computer

(実際、時間が0から23になるのか、1から24になるのかを忘れてしまいました。)

これにより、各コンピューターのテーブルが作成され、時間ごとのカウントが別々の列に表示されます。

于 2012-08-03T14:57:00.437 に答える