2013-11-06 3 views
1

Я работаю на следующей таблице:Невозможно вставить дублированием KEY UPDATE из другого запроса

CREATE TABLE `cons` (
    `Id` char(20) NOT NULL, 
    `Client_ID` char(12) NOT NULL, 
    `voice_cons` decimal(11,8) DEFAULT '0.00000000', 
    `data_cons` int(11) DEFAULT '0', 
    `day` date DEFAULT NULL, 
    PRIMARY KEY (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Мне нужно получить некоторые данные из другой таблицы, cdr, который содержит строку для каждого события. Это означает, что каждый вызов или соединение с данными имеет свою собственную строку.

+-----------+--------------+----------------+-------+ 
| Client_ID | Data_Up_Link | Data_Down_Link | Price | 
+-----------+--------------+----------------+-------+ 
|   1 |   23 |    56 |  0 | 
|   1 |   12 |    3 |  0 | 
|   1 |   0 |    0 |  5 | 
+-----------+--------------+----------------+-------+ 

Мне нужно вычислить общий голос и потребление данных для каждого Client_ID в моем новом cons стола, но просто держать одну запись для каждого Client_ID и day. Чтобы вопрос был простым, я рассмотрю только один день.

+-----------+-----------+------------+ 
| Client_ID | data_cons | voice_cons | 
+-----------+-----------+------------+ 
|   1 |  94 |   5 | 
+-----------+-----------+------------+ 

я безуспешно пытался следующее, среди многих других (псевдоним.

insert into cons_day (Id, Client_ID, voice_cons, MSISDN, day) 
select 
concat(Client_ID,date_format(date,'%Y%m%d')), 
Client_ID, 
sum(Price) as voice_cons, 
date as day 
from cdr 
where Type_Cdr='VOICE' 
group by Client_ID; 

insert into cons_day (Id, Client_ID, data_cons, MSISDN, day) 
select 
    concat(Client_ID,date_format(date,'%Y%m%d')), 
    Client_ID, 
    sum(Data_Down_Link+Data_Up_Link) as data_cons, 
    Calling_Number as MSISDN, 
    date as day 
from cdr 
where Type_Cdr='DATA' 
group by Client_ID 
on duplicate key update data_cons=data_cons; 

Но я продолжаю получать значения без изменений или получения ошибок SQL. Я бы очень признателен за совет.

большое спасибо заранее.

+1

Можете ли вы объяснить, как вы получите '64' для' 'data_cons' с суммой (Data_Down_Link + Data_Up_Link)'? Разве это не '94'? Также похоже, что вам нужны 'data_cons' и' voice_cons' в день. Это верно? – peterm

+0

@peterm Извините, опечатка. Вы правы, мне нужна строка за каждый клиентский_идентификатор и день. Я постарался максимально упростить вопрос, но я переусердствовал. Сейчас я отредактирую. Спасибо! – Serge

ответ

2

Прежде всего, кажется, что Id столбец в таблице cons абсолютно излишними. вам уже есть ClientID и Day столбцов. Просто сделайте их PRIMARY KEY.

Это сказанное предложенная схема таблицы может выглядеть

CREATE TABLE `cons` 
(
    `Client_ID` char(12) NOT NULL, 
    `voice_cons` decimal(11,8) DEFAULT '0.00000000', 
    `data_cons` int(11) DEFAULT '0', 
    `day` date DEFAULT NULL, 
    PRIMARY KEY (`Client_ID`, `day`) 
); 

Теперь вы можете использовать условную агрегацию, чтобы получить voice_cons и data_cons в один идти

SELECT Client_ID, 
     SUM(CASE WHEN Type_CDR = 'VOICE' THEN price END) voice_cons, 
     SUM(CASE WHEN Type_CDR = 'DATA' THEN Data_Up_Link + Data_Down_Link END) data_cons, 
     DATE(date) day 
    FROM cdr 
GROUP BY Client_ID, DATE(date) 

Примечание: вы должныGROUP BY и на Client_ID и DATE(date)

Теперь INSERT заявление должно выглядеть

INSERT INTO cons (Client_ID, voice_cons, data_cons, day) 
SELECT Client_ID, 
     SUM(CASE WHEN Type_CDR = 'VOICE' THEN price END) voice_cons, 
     SUM(CASE WHEN Type_CDR = 'DATA' THEN Data_Up_Link + Data_Down_Link END) data_cons, 
     DATE(date) day 
    FROM cdr 
GROUP BY Client_ID, DATE(date) 
ON DUPLICATE KEY UPDATE voice_cons = VALUES(voice_cons), 
         data_cons = VALUES(data_cons); 

Примечание: так как теперь вы одновременно получаете и voice_cons и data_cons Вам не придется ON DUPLICATE KEY пункт вообще, если не обрабатывать данные в те же сроки несколько раз.

Вот SQLFiddle демо

+0

Ваш ответ потрясающий. Вы не только решили мою конкретную проблему, но и улучшили мое понимание SQL и уменьшили мой код примерно на 80%. Большое вам спасибо, peterm! – Serge

+1

@Serge Вы очень желанны. Я рад, что смогу помочь. Удачи :) – peterm

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