2017-04-06 6 views
0

私の問題では、簡単な例を作成しようとします。
表「順序」:動的な期間別にグループ化する

ID | date | client | product | product_limit_period (in months) 
1 | 2015-01-01 | Bob | table | 1 
2 | 2015-01-31 | Bob | table | 1 
3 | 2015-02-01 | Bob | table | 1 
4 | 2015-01-01 | Mary | lamb | 12 
5 | 2015-06-01 | Mary | lamb | 12 
6 | 2016-01-01 | Mary | lamb | 12 
7 | 2016-12-31 | Mary | lamb | 12 

これは結果であり、私が取得したいのですが:

client | product | group | count 
Bob | table | 1  | 2  #ID 1, 2 
Bob | table | 2  | 1  #ID 3 
Mary | lamb | 3  | 2  #ID 4, 5 
Mary | lamb | 4  | 2  #ID 6, 7 

すべての製品が限界と(数ヶ月で)制限期間があります。私は、一定期間内に製品の制限を超えるものを注文した顧客がいるかどうかを確認する必要があります。 月の期間は、1ヶ月または数ヶ月である場合があります。期間は1ヶ月、12ヶ月、24ヶ月、... 108ヶ月(9年)まで可能です。

私は、ウィンドウ関数とグループ化のいくつかの組み合わせを使用する必要があるように感じる。しかし、私はどのように考え出していない。

私はpostgres 9.1を使用しています。私が提供する必要がある情報が他にもある場合はお知らせください。

私は正しい方向に向いています。

編集:
グループがどのように機能するかを明確にする:制限期間は、最初の注文から始まります。 Bobの最初の注文は2015-01-01で、この期間は2015-01-31で終了します。 2015-02-01は第2の期間を開始します。 期間は常に1か月の最初の日から始まり、月の最後の日で終了します。

+0

あなたのグループをやったのはなぜ'#ID 1、2'は一緒ですが、'#2、3'ではありません。 2&3も月差がありません。異なるグループを探したい場合は、苦労します。代わりに 'product'テーブルを' limit'カラムで記述してください。制限制約に違反した(しかし、明確なグループを持たない)人のみを見つけることは簡単です。 – pozs

+0

制限期間は最初の注文から始まります。 Bobの最初の注文は2015-01-01で、この期間は2015-01-31で終了します。 2015-02-01は第2の期間を開始します。 期間は常に1か月の最初の日から始まり、1か月の最後の日で終了します。私は私の質問でもこれを追加します、ありがとう! – Harry

+0

したがって、最初の注文が「2015-03-15」で、「product_limit_period」が「12」(または1年以上)である場合、期間は実際の**月の最初の日に開始されます** ? (私の例では '2015-03-01')。 – pozs

答えて

1

によって両方のウィンドウとグループで複雑にする必要はありません、ちょうどここのように、ウィンドウまたはグループのいずれかにcaseを追加します。

t=# select 
    client 
, product 
, count(1) 
, string_agg(id::text,',') 
from so44 
group by 
    client 
, product 
, date_trunc(case when product_limit_period = 1 then 'month' else 'year' end,date); 
    client | product | count | string_agg 
----------+-----------+-------+------------ 
    Bob  | table |  2 | 1,2 
    Bob  | table |  1 | 3 
    Mary | lamb  |  2 | 4,5 
    Mary | lamb  |  2 | 6,7 
(4 rows) 

サンプル:

t=# create table so44 (i int,"date" date,client text,product text,product_limit_period int); 
CREATE TABLE 
t=# copy so44 from stdin delimiter '|'; 
Enter data to be copied followed by a newline. 
End with a backslash and a period on a line by itself. 
>> 1 | 2015-01-01 | Bob | table | 1 
>> 2 | 2015-01-31 | Bob | table | 1 
3 | 2015-02-01 | Bob | table | 1 
4 | 2015-01-01 | Mary | lamb | 12 
5 | 2015-06-01 | Mary | lamb | 12 
6 | 2016-01-01 | Mary | lamb | 12 
7 | 2016-12-31 | Mary | lamb | 12>> >> >> >> >> 
>> \. 
COPY 7 
+0

ええ、大丈夫です。しかし、期間が数年あればどうでしょうか。私のシステムでは、1ヶ月、12ヶ月、24ヶ月... 108ヶ月(9年)まで受け入れることができます – Harry

+0

私はあなたの質問で、人々があなたを助けようとする前に言っておくべきだと信じています:) –

+0

私の質問では"月間の期間は、1ヶ月または数ヶ月間であるかもしれません。"それが簡単に見逃されるように書かれていたのは残念です。私は自分の質問を編集して大胆にします。ご協力いただきありがとうございます。このソリューションは2つ以上の異なる期間に使用できますか? – Harry

関連する問題