上传CSV文件,PHP/MySQL查询
我有一个.csv文件,看起来像这样上传CSV文件,PHP/MySQL查询,php,html,mysql,csv,Php,Html,Mysql,Csv,我有一个.csv文件,看起来像这样 Name AC-No. Time State Exception Operation Johnny Starks Depp 1220 4/12/2013 12:45:18 AM Check In OK Johnny Starks Depp 1220 4/12/2013 5:46:58 AM Out O
Name AC-No. Time State Exception Operation
Johnny Starks Depp 1220 4/12/2013 12:45:18 AM Check In OK
Johnny Starks Depp 1220 4/12/2013 5:46:58 AM Out Out
Johnny Starks Depp 1220 4/12/2013 6:22:41 AM Out Back Out
Johnny Starks Depp 1220 4/12/2013 10:42:17 AM Check Out Repeat
Johnny Starks Depp 1220 4/12/2013 10:42:19 AM Check Out OK
我已经可以上传到我的数据库了。我的问题是,结果显示在表中。
在mysql数据库中,我有一个包含列的表(Name、ACNo、Date、CheckIn、Breakout、Breakin、CheckOut)。我想发生的事是我不能做对。。.csv文件中日期相同的记录(显示在时间列中)将与表中的签入、断开、断开和签出一起位于同一行中,不会产生多条记录。
像这样
Name |ACNo | Date | CheckIn | Breakout | Breakin | Checkout
| | | | | |
Johnny Starks Depp|1220 | 4/12/2013 | 12:45:18 AM | 5:46:58 AM | 6:22:41 AM | 10:42:19 AM
现在。。我已经做了上面的例子,我想发生在表中,但。。。当我检查表格时,是的,它每行有不同的日期,但输入时间(签入、中断、中断、签出)是错误的。错误,因为日期4/12/2013中的时间记录在日期4/13/2013中。我使用的代码有什么问题?或者我还有别的方法可以做到这一点吗?这是我的密码:
<?php
$conn = mysql_connect("localhost","root","") or die(mysql_error());
mysql_select_db("dtrlogs",$conn);
$datehere ="";
if(isset($_POST['Submit']))
{
$file = $_FILES['file']['tmp_name'];
if($file == "")
{
?>
<script type="text/javascript">
alert('No File Selected!');
</script>
<?php
}
else
{
$handle = fopen($file,"r");
while(($fileop = fgetcsv($handle,1000,";")) !==false)
{
$Name = $fileop[0];
$ACNo = $fileop[1];
$Time = $fileop[2];
$State = $fileop[3];
$NewState = $fileop[4];
$Exception = $fileop[5];
$Operation = $fileop[6];
//i separated time/date in the Column TIME in the .csv file
$date = date('m/d/Y', strtotime($Time));
$hours = date('H:i:s A', strtotime($Time));
//this is what i used to prevent multiple dates
if($datehere != $date) {
$datehere = $date;
}
else{
$date = "";
}
//this is to insert the name and acno to the other table.
//(this is for the lists of employee)
$sql=mysql_query("SELECT * FROM employee Where ACNo = '$ACNo'");
$row=mysql_fetch_array($sql);
if($row == 0) {
$sql1 = mysql_query("INSERT INTO employee(ACNo, Name) VALUES('$ACNo','$Name')");
}
//Inserts record if Date is not yet recorded and if already has just updates
//the row's column (Checkin, breakout, breakin and Checkout)
//with its correct time according to the date
$query = mysql_query("SELECT * FROM dtrs Where ACNo = '$ACNo' AND Date = '$date'");
$rows = mysql_fetch_array($query);
if($rows == 0) {
$sql2 = mysql_query("INSERT INTO dtrs(Name, ACNo, Date, CheckIn, BreakOut,
BreakIn,CheckOut)
VALUES('$Name','$ACNo','$date','$CheckIn','$Breakout','$Breakin','$Checkout')");
}
else{
$sql2 = mysql_query("Update dtrs Set CheckIn = '$CheckIn', BreakOut =
'$Breakout', BreakIn = '$Breakin', CheckOut = '$Checkout'");
}
//this is my conditions to identify whether the TIME/HOUR is
//Stated as CheckIn, Breakout, Breakin, or Checkout
if($NewState == "Check In" || $State == 'Check In' && $Exception == "OK") {
if($Exception == "Invalid" || $Exception == "Repeat")
{}
else {
$CheckIn = $hours;
}
}
if($State == 'Out' && $Exception == "Out") {
if($Exception == "Invalid" || $Exception == "Repeat")
{}
else {
$Breakout = $hours;
}
}
if($State == 'Out Back' && $Exception == "Out") {
if($Exception == "Invalid" || $Exception == "Repeat")
{}
else {
$Breakin = $hours;
}
}
if($NewState == "Check Out" || $State == "Check Out" && $Exception == "OK") {
if($NewState == "Check In")
{}
else {
$Checkout = $hours;
}
}
}
if($sql2)
{
if($sql2)
{
?>
<script type="text/javascript">
alert('File Upload Successful!');
</script>
<?php
}
}
}
}
?>
警报('未选择文件!');
我建议可能加载到一个临时表中,并从中提取用于填充实际表的详细信息
例如,如果将CSV文件加载到名为LoadTable的表(不是临时表,因为在一段SQL中只能使用一次临时表),则可以提取不同的名称和帐号,然后根据子选择将其合并,以获得每个相关事件的最大事件时间
大概是这样的:-
SELECT DerivMain.Name,
DerivMain.ACNo,
DerivMain.EventDate,
DATE_FORMAT(DerivCheckIn.EventDateTime, '%l:%i:%s %p'),
DATE_FORMAT(DerivBreakout.EventDateTime, '%l:%i:%s %p'),
DATE_FORMAT(DerivBreakin.EventDateTime, '%l:%i:%s %p'),
DATE_FORMAT(DerivCheckout.EventDateTime, '%l:%i:%s %p')
FROM (SELECT DISTINCT Name, ACNo, DATE(STR_TO_DATE(Date,'%c/%e/%Y %l:%i:%s %p')) As EventDate FROM LoadTable) DerivMain
LEFT OUTER JOIN (SELECT Name, ACNo, MAX(STR_TO_DATE(Date,'%c/%e/%Y %l:%i:%s %p') AS EventDateTime) FROM LoadTable WHERE State = 'Check In' GROUP BY Name, ACNo) DerivCheckIn
ON DerivMain.Name = DerivCheckIn Name AND DerivMain.ACNo = DerivCheckIn.ACNo
LEFT OUTER JOIN (SELECT Name, ACNo, MAX(STR_TO_DATE(Date,'%c/%e/%Y %l:%i:%s %p') AS EventDateTime) FROM LoadTable WHERE State = 'Out' GROUP BY Name, ACNo) DerivBreakout
ON DerivMain.Name = DerivBreakout Name AND DerivMain.ACNo = DerivBreakout.ACNo
LEFT OUTER JOIN (SELECT Name, ACNo, MAX(STR_TO_DATE(Date,'%c/%e/%Y %l:%i:%s %p') AS EventDateTime) FROM LoadTable WHERE State = 'Out Back' GROUP BY Name, ACNo) DerivBreakin
ON DerivMain.Name = DerivBreakin Name AND DerivMain.ACNo = DerivBreakin.ACNo
LEFT OUTER JOIN (SELECT Name, ACNo, MAX(STR_TO_DATE(Date,'%c/%e/%Y %l:%i:%s %p') AS EventDateTime) FROM LoadTable WHERE State = 'Check Out' GROUP BY Name, ACNo) DerivCheckout
ON DerivMain.Name = DerivCheckout Name AND DerivMain.ACNo = DerivCheckout.ACNo
插入时查询返回什么?我的意思是$CheckIn、$Breakout、$Breakin、$CheckOut中有什么类型的值,它们在哪里声明?也许这就是问题所在。还有一个很好的提示,当某些东西没有插入update或select from db时,调试您正在发送的字符串查询:)变量($CheckIn、$Breakout、$Breakin、$CheckOut)中的值的副本在IF条件中。此IF将标识$Hour的值是否声明为4(签入、签出、内地、签出)之一。你明白我的意思吗?如果$Hour中的值表示为“签入”,则$Hour中的值将放入$CheckIn中。将再次循环并返回到条件。总之,关于“还有一个很好的提示,当某些东西没有插入更新或从数据库中选择时,调试正在发送的字符串查询:)”你是什么意思?我没听懂你说的话。对不起XD@Steve您说插入的时间是错误的,您能告诉我csv中的值与数据库中每列(签入、签出、内地、签出)的日期时间差吗。它们都有相同的时差吗?如果是,可能是因为您的本地计算机中的时区设置server@dArc可以很抱歉。在调试时,我发现.csv文件中的所有时间都是上载的,但有些时间不在正确的行中,不在正确的日期或应该属于的位置。我认为现在的问题是csv上传程序如何将文件上传到数据库中,或者这是我的IF条件,导致插入的表数据排列不正确。谢谢kickstart。但我不知道如何使用该代码。我对join不太熟悉,很难理解。瞬变的真正作用是什么?我搜索了一下,但似乎很难理解它的作用。感谢您为解决此问题所做的努力。非常欣赏瞬态表我不是指一种特殊类型的表,我只是指在加载时设置一个表(普通表),然后在完成后删除它。一旦它加载到该表中(我在上面刚刚称之为LoadTable),您就可以相对轻松地对其进行操作。上面的SQL有子选择项,每个子选择项为每个名称/acno获取一个事件的最新日期/时间。然后将它们连接在一起,得到一行,其中包含所需的输出值