2017-08-17 10 views
1

は、私は以下のようなデータを持っている:postgresqlで重複したデータのデータを集計する方法は?

t_id s_id date_1  date_2  T_count   expected Result 
N1 1-1I 2012-12-11 2013-01-22 0.21327014218009478622 4.7 
N2 1-1I 2011-08-03 2011-11-10 3.8461538461538462  4.7 
N3 1-1I 2013-12-05 2013-12-20 1.6935483870967742  4.7 
N4 1-1I 2014-12-08 2015-06-25 4.7727272727272727  4.7 
N5 1-1I 2017-03-08 (null)  (null)     4.7 
N6 1-I6 2013-04-11 2013-10-03 0.61538461538461538462 0.97 
N7 1-I6 2011-09-27 2013-06-20 0.37325038880248833651 0.97 

をと私は同じS_IDのDATE1とdate2のは、他の異なるt_idが同じS_IDの最大値を返すために同じS_IDと重複する場合t_count値の合計を計算します。

現在、私が使用しているpostgresコードは、オーバーラップに関係なく値の合計を行っています。お勧めできますか?

いくつかのデータが重複している場合や、あるs_idで重複している場合がありますので、重複している場合は、その一部を個別に、重複して1つの答えはすべての最大です。

select t1.s_id,sum(t1.t_count) 
       from abc t1 
       JOIN abc t2 
       ON daterange(t1.date_1, t1.date_2, '[]') 
          && daterange(t1.date_1, t1.date_2, '[]') 
             and t1.s_id = t2.s_id 
       GROUP BY t1.s_id 
+0

あなただけのS_IDに参加し '場合when'で重複をかどうかを確認する必要があります - しかし、私はあなただけのT1の日付に日付範囲を構築する理由を理解しない - ?何と重複すべきか...それともそのわずか誤植?。 –

+0

そして、特定の 's_id'にいくつかの区間しか重なっていないと、結果はどうなるでしょうか?たとえば、 'date_1'を' N3'に '2013-01-05'に変更した場合、結果はどうなりますか? –

+0

この回答を見てくださいhttps://dba.stackexchange.com/questions/89864/maximum-sum-of-overlapping-ranges – raphael

答えて

0

私はそれ自体と比較して間違いを犯していましたが、私はこの結果を得るために少し修正しました。

with cte as 
(

    select t1.s_id,sum(t1.t_count) as scount 
        from abc t1 
        JOIN abc t2 
        ON daterange(t1.date_1, t1.date_2, '[]') 
           && daterange(t1.date_1, t1.date_2, '[]') 
              and t1.s_id = t2.s_id 
        and t1.s_id ! = t2.s_id 
        GROUP BY t1.s_id 
) 
select 
     s_id,greatest(scount,max(t_count) over (partition by s_id)) as finalvalue 
from abc 
left outer join cte 
on abc.s_id = cte.s_id 
1

特定のs_id重複の間隔の一部といくつかがない場合、ロジックがどのように動作するかを明確ではありません。

データ内のすべての区間が重複しているか、重複していないことがわかっている場合は、それを簡単に判断できます。

各期間の期間を計算し、これらの期間を合計します。最初の日付から最後の日付までの期間と比較してください。

NULLdate_2は、将来かなり大きな日付を意味します。

WITH 
CTE 
AS 
(
    SELECT 
     s_id 
     ,SUM(COALESCE(date_2, '9999-12-31') - date_1) AS TotalDuration 
     ,MIN(date_1) AS FirstDate 
     ,MAX(COALESCE(date_2, '9999-12-31')) AS LastDate 
     ,SUM(T_count) AS SumCount 
     ,MAX(T_count) AS MaxCount 
    FROM YourTable 
    GROUP BY s_id 
) 
SELECT 
    s_id 
    ,CASE WHEN TotalDuration > (LastDate - FirstDate) 
    THEN -- intervals overlap 
     SumCount 
    ELSE -- none of the intervals overlap 
     MaxCount 
    END AS Result 
FROM CTE 
; 
関連する問題