无法从另一个查询中插入DUPLICATE KEY UPDATE

时间:2013-11-06 17:47:24

标签: mysql sql insert-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_IDday保留一条记录。为了简化这个问题,我会考虑一天。

+-----------+-----------+------------+
| 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 个答案:

答案 0 :(得分:2)

首先,似乎Id表中的cons列绝对是多余的。您已有ClientIDDay列。只需让他们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_consdata_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)

注意:{strong}必须<{1}}和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子句。

这是 SQLFiddle 演示