2014-12-16 4 views
0

전화 시스템 시나리오에서 나는 2 개의 테이블을 가지고 있습니다. customer_id, call_duration, calldate, skip_billing :SQL : UPDATE from complex select

  • 표 1은로 구성된다.
  • table2는 customer_id, bonus_seconds으로 구성됩니다.

table1은 모든 고객에 대한 모든 호출을 저장하고 table2는 정의 된 고객에게 허용 된 자유 대화 시간을 나타내는 bonus_seconds를 저장합니다. 즉 고객 1의 경우 FIRST 40 누적 초는 무료입니다.

아래와 같이 조건에 따라 table1을 업데이트하라는 쿼리를 작성해야합니다. table2에서 정의 된 호출 내에서 skip_billing을 설정하십시오.

그래서 먼저 customer_id로 그룹화 한 다음 call_duration에 누적 변수 (cumsec)를 증가시키고 그에 따라 skip_billing을 설정해야합니다.

표 예입니다 : 내가 withing에 사용하려고하면

SELECT t.cume, t.calldate, t.customer_id FROM (SELECT t.*, (@cume := @cume + billsec) AS cume FROM table1 t CROSS JOIN (SELECT @cume := 0) vars ORDER BY calldate) t, table2 sct WHERE t.cume <= sct.bonus_seconds AND t.customer_id=sct.customer_id ; 

을하지만 : 나는 행의 오른쪽 집합을 반환이 (고든 리노 프에게 감사)과 같은 쿼리를 시도

|sqlid |customer_id |billsec | skipbill| 
|0  |1   |12  | 1  |<--need to set 1 due to cume=12 for customer_id=1 
|1  |1   |10  | 1  |<--need to set 1 due to cume=22 for customer_id=1 
|2  |1   |15  | 1  |<--need to set 1 due to cume=37 for customer_id=1 
|3  |1   |8  | 0  |<--nop(no operation) due to cume=45 
|4  |2   |12  | 1  |<--need to set 1 due to cume=12 for customer_id=2 
|5  |3   |12  | 1  |<--need to set 1 due to cume=12 for customer_id=3 
|6  |2   |12  | 0  |<--nop due to cume=24 for customer_id=2 
|7  |1   |12  | 0  |<--nop due to cume=49 for customer_id=1 
|8  |3   |15  | 0  |<--nop due to cumsec=27 for customer_id=3 

|customer_id |bonus_seconds| 
|1   |40   | 
|2   |20   | 
|3   |15   | 

아래 명령과 같이 업데이트하면 아무 것도 일치하지 않기 때문에 작동하지 않습니다.

UPDATE table1 SET skipbill=1 WHERE sqlid=(SELECT t.sqlid FROM (SELECT t.*, (@cume := @cume + billsec) AS cume FROM table1 t CROSS JOIN (SELECT @cume := 0) vars ORDER BY calldate) t, table2 sct WHERE t.cume <= sct.bonus_seconds AND t.customer_id=sct.customer_id) ; 

어떻게하면 해당 쿼리를 사용하여 업데이트 작업을 작성할 수 있습니까?

가 사전에 감사

답변

1
UPDATE table1 
SET skipbill = 1 
WHERE sqlid IN (
    SELECT DISTINCT t.sqlid 
    FROM (
     SELECT t.*, (@cume := @cume + billsec) AS cume 
     FROM table1 t 
     CROSS JOIN (SELECT @cume := 0) vars 
     ORDER BY calldate 
    ) t, table2 sct 
    WHERE t.cume <= sct.bonus_seconds 
      AND t.customer_id = sct.customer_id 
); 
+0

감사합니다! 그것은 작동합니다. 쿼리 실행 시간은 약 13 초이며, table1의 7k 행에서만 table2가 하나의 행입니다! 이제 복잡성을 줄이는 시간이 있습니다. –

+0

실행 시간을 단축하면 별개로 추가하십시오 ... –

+0

어디에서 sqlid (SELECT 별개 t.sqlid ......... –

1

이 날 것으로 보인다 ... 어쨌든 3 그들의 보너스의 일부가되어야 초 만에 (예를 들어) 고객의 1을 청구하고 그

SELECT x.* 
     , SUM(y.billsec) cumu 
     , IF(SUM(y.billsec)<=z.bonus_seconds,1,0) n 
    FROM my_table x 
    JOIN my_table y 
    ON y.customer_id = x.customer_id 
    AND y.sqlid <= x.sqlid 
    LEFT 
    JOIN bonus z 
    ON z.customer_id = x.customer_id 
    GROUP 
    BY x.customer_id 
     , x.sqlid 
    ORDER 
    BY sqlid; 
+0

네가 맞아! 나는 모든 시간을 올바르게 계산할 수있는 해결책을 찾지 못했습니다. 당신은 자유롭게 해줄 수 있습니다. 어쨌든 고맙습니다. –

+0

이 쿼리는 1 분 50.25 초가 걸립니다. 매우 오랜 시간 !! 그러나 작동 함 –

+0

customer_id는 자체 또는 컴포지트의 일부로 색인화됩니다. – Strawberry