1

我正在处理下表:

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 错误。我真的很感激你的建议。

非常感谢您提前。

4

1 回答 1

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_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_IDDATE(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演示

于 2013-11-06T18:14:02.423 回答