2013-04-29 3 views
-1

У меня эти 2 таблицы. Я хочу подсчитать количество con_id, которое имеет замечание «1» непрерывно в течение последнего периода (периодов).
ex: 2 для A1, 1 для A3, но 0 для A2 и B1, поскольку они не имеют «1» непрерывно для последнего результата (ов) для следующей таблицы.SQL-помощь по группе по запросу с встроенным запросом

t_conmast

  • con_id [рк]
  • off_code
 
con_id off_code 
A1  1 
A2  1 
B1  2 
A3  1 

t_readbak

  • con_id [FK]
  • счетчик
  • примечание
  • временная метка [не показана в таблице; авто вставлено системы]
 
con_id counter remark timestamp 
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 count(con_id) 
A1  2 
A2  0 
A3  1 
B1  0 
+0

Можете ли вы опубликовать ожидаемый результат на основе данных в вашем вопросе? –

+0

@EdGibbs Edited :) – Sourav

+0

Можете ли вы (а) описать, как вы определяете «период» (как в * «Я хочу подсчитать количество con_id, которое имеет замечание« 1 »непрерывно за последний период (ы)» *), (б) уточнить значимость офиса (предположительно определяемого 'off_code') и (c) добавить данные временной метки в ваш образец данных? –

ответ

1

Это подход, который я принял для решения этого. Сначала вычислите кумулятивную сумму замечания, идущего назад для каждого 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) 
1

Левое автообъединение может работать. Что-то вроде этого:

select con_id, count(*) records 
from t_readback t1 left join t_readback t2 using (con_id, remark) 
where remark = 1 
and t1.counter < t2.counter 
group by con_id 
1

Если вы имеете в виду, что вы только хотите включить con_id счетчики, если каждыйremark в период 1, вы можете сделать что-то вроде этого:

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_id, который имеет remark <> 1.

1

получить максимальную временную метку для каждого con_id где remark 0. после этого, опять же для каждого con_id, подсчитывать элементы с младшими временными метками.remark устанавливается в 1 в этих записях по конструкции:

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 
      ; 

заменить timestamp (max(timestamp)) по counter (min(counter)) и изменить оператор сравнения, если вы не можете доверять вашего заказа временной метки.

Смежные вопросы