Php 从两个来源提取信息并计数
我被要求在工作中创建一个系统,记录通过VoIP系统拨打和接听的电话数量。如果我能够改变数据源的结构,我就有可能做到这一点,但在这种情况下,我不允许改变它,这取决于我向比我更专业的人请教 使用MSSQL的数据源1-记录已登录到我们内部网的用户及其扩展名:Php 从两个来源提取信息并计数,php,mysql,sql,sql-server,database,Php,Mysql,Sql,Sql Server,Database,我被要求在工作中创建一个系统,记录通过VoIP系统拨打和接听的电话数量。如果我能够改变数据源的结构,我就有可能做到这一点,但在这种情况下,我不允许改变它,这取决于我向比我更专业的人请教 使用MSSQL的数据源1-记录已登录到我们内部网的用户及其扩展名: +-------+----------------+--------------+---------------------+ | ID | USERNAME | EXTENSION | LOGGEDIN
+-------+----------------+--------------+---------------------+
| ID | USERNAME | EXTENSION | LOGGEDIN |
+-------+----------------+--------------+---------------------+
| 1 | JESS | 101 | 2014-11-10 12:00:00 |
+-------+----------------+--------------+---------------------+
| 2 | SARAH | 203 | 2014-11-10 12:21:00 |
+-------+----------------+--------------+---------------------+
| 3 | FERN | 124 | 2014-11-10 12:21:31 |
+-------+----------------+--------------+---------------------+
| 4 | SARAH | 101 | 2014-11-10 13:12:00 |
+-------+----------------+--------------+---------------------+
Datasource 2使用MySQL-Datasource 2包含使用VoIP系统发出和接收的所有呼叫
+-------+----------------+---------------+---------------------+
| ID | SRC | DST | TIME |
+-------+----------------+---------------+---------------------+
| 1 | 101 | 02035654684 | 2014-11-10 12:01:00 |
+-------+----------------+---------------+---------------------+
| 2 | 203 | 02087816328 | 2014-11-10 12:22:00 |
+-------+----------------+---------------+---------------------+
| 3 | 124 | 02078939273 | 2014-11-10 12:23:31 |
+-------+----------------+---------------+---------------------+
| 4 | 101 | 04672738782 | 2014-11-10 13:15:00 |
+-------+----------------+---------------+---------------------+
| 5 | 07863522413 | 101 | 2014-11-10 13:21:00 |
+-------+----------------+---------------+---------------------+
| 6 | 02076352423 | 203 | 2014-11-10 13:25:31 |
+-------+----------------+---------------+---------------------+
| 7 | 07836325726 | 101 | 2014-11-10 13:56:00 |
+-------+----------------+---------------+---------------------+
这是我希望能够打印的内容:
+-------+----------------+--------------+--------------+-------------+
| ID | USERNAME | INCOMING | OUTGOING | TOTAL |
+-------+----------------+--------------+--------------+-------------+
| 1 | JESS | 0 | 1 | 1 |
+-------+----------------+--------------+--------------+-------------+
| 2 | SARAH | 2 | 2 | 4 |
+-------+----------------+--------------+--------------+-------------+
| 3 | FERN | 0 | 1 | 1 |
+-------+----------------+--------------+--------------+-------------+
从上面的表格中可以看出,Sarah开始使用分机203,然后在Jess离开后登录到101。她在203登录时打了1个电话,在101登录时打了1个电话。她在101分机登录时还接了2个电话
我将在这个项目中使用PHP。理想情况下,我希望通过总降序对上面的表进行排序,但我相信,一旦我有了构建块,我可以自己解决这个问题
提前感谢您在这方面提供的任何帮助
注意:我已经考虑过创建一个临时表来提取信息,但是我已经被告知这是一个坏主意,因为查询的执行时间以及我需要提取信息的频率。脚本将每10秒运行一次,因此我使用的任何查询都需要非常精简
SELECT
u.ID,
u.USERNAME,
coalesce(tSRC.INCOMING,0) as INCOMING,
coalesce(tDST.OUTGOING,0) as OUTGOING,
(coalesce(tSRC.INCOMING,0)+coalesce(tDST.OUTGOING,0)) as total
FROM
table1 u
LEFT JOIN (
SELECT a.SRC as ext , count(a.ID) as INCOMING
FROM table2 a WHERE CHAR_LENGTH(a.SRC)=3 GROUP BY a.SRC
) tSRC ON tSRC.ext = u.EXTENSION
LEFT JOIN (
SELECT b.SRC as ext , count(b.ID) as OUTGOING
FROM table2 b WHERE CHAR_LENGTH(b.DST)=3 GROUP BY b.DST
) tDST ON tDST.ext = u.EXTENSION
编辑:更好的版本:
此解决方案假设您能够从PHP连接到这两个数据库,并且可以从这两个表中读取几乎所有的行,并保存一个大小等于用户名数的数组。您遇到了哪些问题?你已经做了多少?我建议设置一个从ms sql到mysql的链接服务器,并编写一个存储过程来组装数据。@TabAlleman我还没有编写任何sql语句,因为我不太确定如何解决这个问题,这就是我来这里的原因。@DanBracuk这是一个可行的选择,但我不知道这是否能给我提供实时信息。我想每隔几秒钟就可以对数据库进行一次轮询。正如@DanBracuk所说的,使用MSSQL服务器中的链接服务器连接MySQL数据库。然后使用建议的存储过程或视图来定义php中所需的布局或最终使用的任何前端。链接服务器实时获取数据,因此无需轮询数据库。我假设您正在尝试创建某种性能仪表板。如果您配置了SQL Server Reporting Services实例,我将使用该实例编写报告,您可以自动设置刷新数据的频率。谢谢David,我相信如果表位于同一数据库中,这会起作用,但它们不是:它们位于两个不同的数据库中,使用两个不同的引擎。数据存储1是MSSQL,数据存储2是MySQL。你能详细说明一下我如何修改它以满足我的需要吗?一个镜像示例将表从一个数据库复制到另一个数据库,或者b使用PHP进行计数。但是,上次我尝试将MSSQL数据库连接到PHP时,我发现将其导出/导入到MySQL并连接MySQL更容易,如果另一个人在不同的时间以相同的扩展名登录,这会像上面那样工作吗?嗯,现在我明白了。这就是问题所在。Solo SQL解决方案将“过于复杂”,或者您可以像其他人暗示的那样使用缓存来完成这项工作。我个人会用PHP并排阅读两个排序的查询,以防你们设法在PHP中连接MSSQL。我听说PDO插件可以做到这一点。
SELECT
u.ID,
u.USERNAME,
u.EXTENSION,
COUNT(distinct a.ID) as INCOMING,
COUNT(distinct b.ID) as OUTGOING,
(COUNT(distinct a.ID)+COUNT(distinct b.ID)) as TOTAL
FROM
table1 u
LEFT JOIN table2 a ON u.EXTENSION=a.SRC
LEFT JOIN table2 b ON u.EXTENSION=b.DST
GROUP BY u.EXTENSION
$q1="SELECT USERNAME, EXTENSION, unix_timestamp(LOGGEDIN) as t FROM table1 WHERE 1 ORDER BY EXTENSION,LOGGEDIN";
$q2="
(SELECT SRC-0 as EXTENSION, 0 as side, unix_timestamp(`TIME`) as t FROM table2 WHERE CHAR_LENGTH(SRC)=3 )
UNION
(SELECT DST-0 as EXTENSION, 1 as side, unix_timestamp(`TIME`) as t FROM table2 WHERE CHAR_LENGTH(DST)=3 )
ORDER BY EXTENSION, t";
$r1 = $db1->query($q1);
$r2 = $db2->query($q2);
$x1 = $r1->fetch_object();
$x2 = $r2->fetch_object();
$users = array();
$future_x1 = $r1->fetch_object();
while($x1 && $x2)
{
if( $x1->EXTENSION < $x2->EXTENSION )
{
$x1=$future_x1 ;
$future_x1=$r1->fetch_object();
}
elseif( $x1->EXTENSION > $x2->EXTENSION )
{
$x2 = $r2->fetch_object();
}
elseif( $future_x1 && $future_x1->EXTENSION == $x1->EXTENSION && $x2->t >= $future_x1->t )
{
$x1=$future_x1 ;
$future_x1=$r1->fetch_object();
}
else
{
@$users[$x1->USERNAME][$x2->side]++;
$x2 = $r2->fetch_object();
}
}
print_r($users);