-1

私はこれらの2つのテーブルを持っています。直近の期間、連続してリマーク「1」を持つcon_idの数をカウントしたい。
例: A1 の場合は 2、A3 の場合は 1 ですが、A2 と B1 の場合は 0 です。これは、次の表の最新の結果に対して連続して「1」がないためです。

t_conmast

  • con_id [pk]
  • オフコード
  
con_id off_code
A1 1
A2 1
B1 2
A3 1

t_readbak

  • con_id [fk]
  • カウンター
  • 述べる
  • タイムスタンプ [表には表示されていません。システムによって自動挿入]
con_id カウンター 備考 タイムスタンプ
A1 1 0
A1 3 1
A1 6 1
B1 1 1
B1 2 0
A2 1 0
A2 2 1
A2 3 0
A3 1 1

私が試して失敗したこと(単一のオフィスの結果を取得するためだけに off_code を追加しました)

select con_id, 
       count(con_id) 
from t_readbak 
where remark=1 and timestamp > (select max(timestamp) 
                                from t_readbak 
                                where remark=0 
                                group by con_id) 
and con_id in (select con_id from t_conmast where off_code=1)

期待される出力

con_id カウント(con_id)
A1 2
A2 0
A3 1
B1 0
4

4 に答える 4

1

期間内のすべてcon_idが である場合にのみカウントを含めたい場合は、次のようにすることができます。 remark1

SELECT
  con_id,
  COUNT(CASE remark = 1 THEN 1 END) AS Remark1Count,
  COUNT(CASE remark <> 1 THEN 1 END) AS RemarkNot1Count
FROM t_conmast
INNER JOIN t_readbak ON t_conmast.con_id = t_readbak.con_id
WHERE your-timestamp-condition
GROUP BY con_id
HAVING COUNT(CASE remark <> 1 THEN 1 END) = 0

は、 を持つものHAVINGを除外します。con_idremark <> 1

于 2013-04-29T14:50:07.290 に答える
1

これは、これを解決するために私が取ったアプローチです。最初に、各 について遡って remark の累積和を計算しますcon_id。次に、 の行に初めてヒットしたときに、remark = 0その行の値を使用します。を使用して、そのような最初の行を見つけることができますrow_number()

複雑なのは、値が 0 のコメントがない場合です。その場合は、合計数を取得するだけです。

次のクエリは、このロジックを SQL に結合します。

select rb.con_id,
       (case when NumZeros = 0 then numRemarks else cumsum end) as count1
from (select rb.*,
             SUM(remark) over (partition by con_id order by counter desc) as cumsum,
             ROW_NUMBER() over (partition by con_id, remark order by counter desc) as remark_counter,
             SUM(case when remark = 0 then 1 else 0 end) as NumZeros,
             SUM(remark) over (partition by con_id) as numRemarks
      from t_readbak rb
     ) rb
where (remark_counter = 1 and remark = 0) or
      (NumZeros = 0 and remark_counter = 1)
于 2013-04-29T14:45:04.357 に答える
1

が 0のcon_id場所ごとに最大のタイムスタンプを取得します。構造により、これらのレコードでは 1 に設定されます。remarkcon_idremark

    select con_id
         , count(*)
      from t_readbak master
inner join t_conmast office on (     office.off_code = 1
                                 and office.con_id   = master.con_id )
inner join (
                select con_id           con_id
                     , max(timestamp)   ts
                  from (
                            select con_id
                                 , remark
                                 , timestamp
                              from t_readbak
                             where remark = 0
                       ) noremark
              group by con_id
            ) cutoff
         on ( master.con_id = cutoff.con_id )
      where master.timestamp > cutoff.ts
   group by master.con_id
          ;

タイムスタンプの順序が信頼できない場合は、( ) を ( ) に置き換えて、比較演算子を変更timestampmax(timestamp)counterください。min(counter)

于 2013-04-29T15:16:50.823 に答える