我有一个sqlserver数据表,里面主要的字段有id,时间(格式如2022-11-18 00:05:10),科室,电表度数。其中时间是每5min从下位机返回一次,我想要实现的功能是计算每个科室每年的用电量,就是用2022年12月31日最后一个时间的电表读数减去2022年1月1日最早一个时间的电表读数。与同事沟通,获得了C#的处理方式,里面的逻辑我也大致理解,但是我现在后端用的是PHP,咨询各位专家如何把下面的程序转化成PHP。
请各位放心回答,有满意答复定然不会跑路,盼复!
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Program program = new Program();
program.Calculate();
}
void Calculate()
{
dt.Columns.Add("科室");
dt.Columns.Add("时间");
dt.Columns.Add("用电量");
string sql1 = "select distinct keshi from [GPRSDATA].[dbo].[yunyingjiance] "; //sql1获取科室
DataSet ds = Database_70(sql1);
//第一个数据表(Tables[0])中,一共有的行数(Rows.count)rows指行,count指的数目,此处获得的是科室的数量
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
//年耗电
double dushu = 0;
double haoDianLiang = 0;
int year = 0;
string keshi = ds.Tables[0].Rows[i]["keshi"].ToString();//获取数据表里科室的名称
//sql2按科室、班组、时间倒序排列数据表
string sql2 = "SELECT* FROM[GPRSDATA].[dbo].[yunyingjiance] where keshi='" + keshi + "' order by keshi,banzu,time1 desc";
DataSet ds2 = Database_70(sql2);
for (int j = 0; j < ds2.Tables[0].Rows.Count; j++)
{
if (j == 0)
{
dushu = Convert.ToDouble(ds2.Tables[0].Rows[j]["dianbiaodushu"].ToString());//2022读
year = Convert.ToDateTime(ds2.Tables[0].Rows[j]["time1"].ToString()).Year;//2022
}
else if (Convert.ToDateTime(ds2.Tables[0].Rows[j]["time1"].ToString()).Year < Convert.ToDateTime(ds2.Tables[0].Rows[j - 1]["time1"].ToString()).Year)
{
//每年
haoDianLiang = dushu - Convert.ToDouble(ds2.Tables[0].Rows[j]["dianbiaodushu"].ToString());//2022耗
dushu = Convert.ToDouble(ds2.Tables[0].Rows[j]["dianbiaodushu"].ToString());//2021读
DataRow dr = dt.NewRow();
dr[0] = keshi;
dr[1] = year;
dr[2] = haoDianLiang;
dt.Rows.Add(dr);//创建一行
year = Convert.ToDateTime(ds2.Tables[0].Rows[j]["time1"].ToString()).Year;//2021
}
}
}
}
public static DataSet Database_70(string mySQLStr)
{
string myConnStr = "server=;database=;UID=;password=' ';Connect Timeout=600;"
/* ConfigurationManager.AppSettings["ConnectionString"].ToString()*/;
SqlConnection myConn = new SqlConnection(myConnStr);
myConn.Open();
SqlDataAdapter myDa = new SqlDataAdapter(mySQLStr, myConn);
DataSet myDs = new DataSet();
myDa.Fill(myDs);
myDa.Dispose();
myDs.Dispose();
myConn.Dispose();
myConn.Close();
return myDs;
}
}
}
C# DataSet是获取数据库的数据的一个离线数据集合,php有对应的库读取sqlserver,如果是mysql,那不是直接mysqli_fetch_all读取所有记录集就行了(此时读取的值就是C#的Dataset一样的数据集合)。然后按照C#的逻辑处理下就行了
这个直接用sql不就实现了么?根据科室,年分组,然后获取最大时间的电量-最小时间的电影不就可以了么,假设你的数据是mysql的话,可以用以下语句:
SELECT `科室`,year(`时间`),
((SELECT `电表度数` FROM table b WHERE b.`科室`=a.`科室` and b.`时间`=MAX(a.`时间`))
-
(SELECT `电表度数` FROM table b WHERE b.`科室`=a.`科室` and b.`时间`=min(a.`时间`))) as 每年用电量
FROM table as a GROUP BY `科室`,year(`时间`)
这样就获取到了每个科室,每年的用电量了呀
这样直接用php获取,循环输出就得了,不需要在用程序处理了
我大概看了一下上面的C#代码,代码比较容易读,逻辑也清晰。
对应的PHP代码,最容易想到的是:
首先提取科室名称到一个数组里,然后循环这个数组,
<?php
require 'DBConfig.php';//加载数据库
$KeShiArr=[];//准备接收科室的数组==》 string sql1 = "select distinct keshi from [GPRSDATA].[dbo].[yunyingjiance] ";
//GetData
$JSDuShuData=[];//对应接收数据==》string sql2 = "SELECT* FROM[GPRSDATA].[dbo].[yunyingjiance] where keshi='" + keshi + "' order by keshi,banzu,time1 desc";
//获取$KeShiArr数组的数据
......
//循环科室数组进行dushu的计算
for ($i = 0; $i <= count($KeShiArr); $i++) {
for ($j = 0; $j <= count($JSDuShuData); $j++) {
//获取$JSDuShuData数据GetData
......
}
}
function GetData(string StrSQL) {
//返回数组,好长时间不写PHP忘记写法了,
}
大概是这样做。
因为你没说你PHP对应的数据库是mysql还是mssql 所以我就盲猜你用的mssql来写了。有需要mysql的你自己改下就完了。记得配置数据库链接:
function Calculate()
{
$result = [];
$result[] = array('科室', '时间', '用电量');
$sql1 = "select distinct keshi from [GPRSDATA].[dbo].[yunyingjiance];"; //sql1获取科室
$ds = Database_70($sql1);
//第一个数组中,一共有的行数是科室的数量
for ($i = 0; $i < count($ds); $i++) {
//年耗电
$dushu = 0;
$haoDianLiang = 0;
$year = 0;
$keshi = $ds[$i]["keshi"];//获取数据表里科室的名称
//sql2按科室、班组、时间倒序排列数据表
$sql2 = "SELECT * FROM [GPRSDATA].[dbo].[yunyingjiance] where keshi='" . $keshi . "' order by keshi,banzu,time1 desc";
$ds2 = Database_70($sql2);
for ($j = 0; $j < count($ds2); $j++) {
if ($j == 0) {
$dushu = floatval($ds2[$j]["dianbiaodushu"]);//2022读
$year = date("Y", strtotime($ds2[$j]["time1"]));//2022
} else if (date("Y", strtotime($ds2[$j]["time1"])) < date("Y", strtotime($ds2[$j - 1]["time1"]))) {
//每年
$haoDianLiang = $dushu - floatval($ds2[$j]["dianbiaodushu"]);//2022耗
$dushu = floatval($ds2[$j]["dianbiaodushu"]);//2021读
$result[] = array($keshi, $year, $haoDianLiang);
$year = date("Y", strtotime($ds2[$j]["time1"]));//2021
}
}
}
//最终的计算结果
var_dump($result);
}
function Database_70($mySQLStr)
{
//链接mssql数据库
$dsn = 'mssql:dbname=your_dabase_name;host=192.168.1.106';
$user = 'sa';
$password = '123';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
//$mySQLStr = 'select * from article';
$sth = $dbh->query($mySQLStr);
$result = $sth->fetchAll();
return $result;
}
详情参考
https://blog.csdn.net/weixin_32485965/article/details/116096308