我试图执行大量MySQL查询并将结果作为一行写入不同的数据库和表。
所以这是有效的
INSERT INTO bridgedb.stats (longestcall, totalmins, totalconfs)
SELECT
(SELECT MAX(duration) AS longestcall FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT SUM(duration) AS totalmins FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT COUNT(*) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY);
这是有效的
INSERT INTO bridgedb.stats (date, peakchan)
SELECT
`calldate`,
MAX(concurrent)+1 AS peakcount
FROM (
SELECT
DATE(a.calldate) as calldate,
COUNT(b.uniqueid) AS concurrent
FROM asteriskcdr.cdr AS a, asteriskcdr.cdr AS b
WHERE
a.calldate >= NOW() - INTERVAL 4 DAY
AND (
(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
)
AND a.uniqueid>b.uniqueid
GROUP BY a.uniqueid
) AS baseview
GROUP BY calldate;
但这不起作用
INSERT INTO bridgedb.stats (date, peakchan, longestcall, totalmins, totalconfs)
SELECT
(SELECT
`calldate`,
MAX(concurrent)+1 AS peakcount
FROM (
SELECT
DATE(a.calldate) as calldate,
COUNT(b.uniqueid) AS concurrent
FROM asteriskcdr.cdr AS a, asteriskcdr.cdr AS b
WHERE
a.calldate >= NOW() - INTERVAL 1 DAY
AND (
(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
)
AND a.uniqueid>b.uniqueid
GROUP BY a.uniqueid
) AS baseview
GROUP BY calldate),
(SELECT MAX(duration) AS longestcall FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT SUM(duration) AS totalmins FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT COUNT(*) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY);
我收到错误#1241 - 操作数应包含1列
有谁知道我如何才能使这项工作适用于所有查询?
答案 0 :(得分:0)
尝试使用会话变量或将其抽象为存储过程,例如 -
首先:
SELECT
@calldate:=`calldate`,
@peakchan:=MAX(concurrent)+1
FROM (
...
) AS baseview
GROUP BY calldate
第二
SELECT @longestcall:=MAX(duration) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY
第三
SELECT @totalmins:=SUM(duration) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY
第四:
SELECT @totalconfs:=COUNT(*) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY;
最后
INSERT INTO bridgedb.stats (date, peakchan, longestcall, totalmins, totalconfs)
VALUES (@calldate, @peakchan, @longestcall, @totalmins, @totalconfs)
BTW:调用专栏date
不是一个好主意。
修改强>
当然,您需要确保这些查询在同一会话中运行以使用会话变量。这是在PHP中使用单个数据库连接运行时的默认值
编辑2
要处理没有活动的时段,您可以
SELECT @calldate:=DATE(NOW() - INTERVAL 1 DAY), @peakchan:=0, @longestcall:=0, @totalmins:=0, @totalconfs:=0;
(创建默认值的记录)编辑3
这对我有用:
DELIMITER //
CREATE PROCEDURE ReportYesterday()
BEGIN
DECLARE calldate DATE;
DECLARE peakchan, longestcall, totalmins, totalconfs INT;
SELECT
@calldate:=`calldate`,
@peakchan:=MAX(concurrent)+1
FROM (
SELECT
DATE(a.calldate) as calldate,
COUNT(b.uniqueid) AS concurrent
FROM asteriskcdr.cdr AS a, asteriskcdr.cdr AS b
WHERE
a.calldate >= NOW() - INTERVAL 1 DAY
AND (
(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
)
AND a.uniqueid>b.uniqueid
GROUP BY a.uniqueid) AS baseview
GROUP BY calldate
;
-- EDIT 4 IS THE FOLLOWING LINE
IF @calldate IS NOT NULL THEN
SELECT @longestcall:=MAX(duration) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY
;
SELECT @totalmins:=SUM(duration) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY
;
SELECT @totalconfs:=COUNT(*) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY
;
INSERT INTO bridgedb.stats (date, peakchan, longestcall, totalmins, totalconfs)
VALUES (@calldate, @peakchan, @longestcall, @totalmins, @totalconfs)
;
END IF;
END
;
//
DELIMITER ;
接着是
CALL ReportYesterday();
答案 1 :(得分:0)
您必须构建一个返回所有行的(有效)SELECT查询。您之前的SELECT无效。这应该工作:
INSERT INTO bridgedb.stats (date, peakchan, longestcall, totalmins, totalconfs)
SELECT
`calldate`,
MAX(concurrent)+1 AS peakcount,
(SELECT MAX(duration) AS longestcall FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT SUM(duration) AS totalmins FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY),
(SELECT COUNT(*) FROM bridgedb.log WHERE `start` >= NOW() - INTERVAL 1 DAY)
FROM (
SELECT
DATE(a.calldate) as calldate,
COUNT(b.uniqueid) AS concurrent
FROM asteriskcdr.cdr AS a, asteriskcdr.cdr AS b
WHERE
a.calldate >= NOW() - INTERVAL 1 DAY
AND (
(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
)
AND a.uniqueid>b.uniqueid
GROUP BY a.uniqueid
) AS baseview
GROUP BY calldate;