I have a table in SQL Server with this fields and values.
ID_Employee | ID_Company | Date | Concept | Hours
--------------------------------------------------------
1 | 1 | 14/03/2013 | 1 | 8
1 | 1 | 14/03/2013 | 2 | 0
1 | 1 | 14/03/2013 | 3 | 3
1 | 1 | 14/03/2013 | 4 | 1
1 | 1 | 16/03/2013 | 1 | 5
1 | 1 | 16/03/2013 | 2 | 2
1 | 1 | 16/03/2013 | 3 | 0
1 | 1 | 16/03/2013 | 4 | 0
What I need is to display the values where ID_Employee=1 and ID_Company=1 in a HTML table grouping the rows by date, and ordering the hours in his column as the value of their concept.
Date | Concept_1 | Concept_2 | Concept_3 | Concept_4 |
------------------------------------------------------------
14/03/2013 | 8 hours | 0 hours | 3 hours | 1 hour |
16/03/2013 | 5 hours | 2 hours | 0 hours | 0 hours |
I don't know how to do the query or what statement (while,for,foreach) to use in php to create 1 row (<tr>) for each different date, containing a single cell (<td>) for each concept and hour.
The html should look like this:
<tr id="14/03/2013">
<td class="concept_1">8 hours</td>
<td class="concept_2">0 hours</td>
<td class="concept_3">3 hours</td>
<td class="concept_4">1 hour</td>
</tr>
<tr id="16/03/2013">
<td class="concept_1">5 hours</td>
<td class="concept_2">2 hours</td>
<td class="concept_3">0 hours</td>
<td class="concept_4">0 hour</td>
</tr>
It may be easy, but now I'm a bit confused and I can't find the solution.
You're looking for a PIVOT operator wich allows you do desired stuff. You can use following query:
select
pvt.date,
[1] AS concept_1,
[2] AS concept_2,
[3] AS concept_3,
[4] AS concept_4
from
(
SELECT
date,
hours,
concept
FROM table1
) p
PIVOT
(
AVG(hours)
FOR concept IN
([1], [2], [3], [4])
) as pvt
Providing SqlFiddle as well.
Check this:
declare #tableHTML nvarchar(MAX);
set #tableHTML = CAST((
select
1 AS Tag,
NULL AS Parent,
pvt.[date] AS 'tr!1!id',
ltrim(rtrim(str([1])))+ ' hours' AS 'tr!1!td class="concept_1"!Element',
ltrim(rtrim(str([2])))+ ' hours' AS 'tr!1!td class="concept_2"!Element',
ltrim(rtrim(str([3])))+ ' hours' AS 'tr!1!td class="concept_3"!Element',
ltrim(rtrim(str([4])))+ ' hours' AS 'tr!1!td class="concept_4"!Element'
from
(
SELECT
date,
hours,
concept
FROM table1
) p
PIVOT
(
AVG(hours)
FOR concept IN
([1], [2], [3], [4])
) as pvt
FOR XML EXPLICIT) AS NVARCHAR(MAX));
PRINT REPLACE(REPLACE(REPLACE(REPLACE(#tableHTML, '</td class="concept_1">', '</td>'), '</td class="concept_2">', '</td>'), '</td class="concept_3">', '</td>'), '</td class="concept_4">', '</td>');
Ouput:
<tr id="2013-03-14">
<td class="concept_1">8 hours</td>
<td class="concept_2">0 hours</td>
<td class="concept_3">3 hours</td>
<td class="concept_4">1 hours</td>
</tr>
<tr id="2013-03-16">
<td class="concept_1">5 hours</td>
<td class="concept_2">2 hours</td>
<td class="concept_3">0 hours</td>
<td class="concept_4">0 hours</td>
</tr>
I used the pivot proposed by #Sergio - thanks a lot (+1)
Related
I've got these timerecording data from toggl.com where I need to have my reports formatted a bit different than what they supply - that's why I thought I'd try to import the csv data to MySQL and group and format it myself via MySQL and PHP etc. but I'm stuck almost before I started - got the data into MySQL, so now I need to output it in a html table... somehow.
I've got these data:
+-----------+---------------------------------------+------------+----------+
| Project | Task name | Date | Duration |
+-----------+---------------------------------------+------------+----------+
| Project 1 | Task name 2 | 2016-05-12 | 00:22:03 |
| Project 2 | Task name 1 | 2016-05-12 | 00:04:24 |
| Project 2 | Task name 1 | 2016-05-12 | 00:06:27 |
| Project 1 | 3. correction | 2016-05-13 | 00:08:00 |
| Project 1 | Small correction | 2016-05-13 | 00:02:02 |
| Project 1 | Last correction | 2016-05-16 | 00:05:36 |
| Project 1 | Created low-res | 2016-05-16 | 00:04:21 |
| Project 2 | Layout | 2016-05-24 | 00:27:45 |
| Project 2 | Layout | 2016-05-25 | 01:00:00 |
| Project 2 | Finishing | 2016-05-25 | 00:15:48 |
+-----------+---------------------------------------+------------+----------+
What I dream to achieve is data for each project that looks like this:
Project 2
-----------------------------------------------------
Date Tasks Total
-----------------------------------------------------
12/05/16 Task name 1 00:10:51
24/05/16 Layout 00:27:45
25/05/16 Layout, Finishing 01:15:48
-----------------------------------------------------
Project 2 total 01:54:24
So for each Project, each Date should have its own row, including Date, Task names (comma delimited) and the sum of the Duration for that Date
And then a project total.
Any help would be very appreciated!! :-)
EDIT:
SELECT
Project,
`Task name`,
Date,
Duration,
SEC_TO_TIME( SUM( TIME_TO_SEC( `Duration` ) ) ) AS TotalDuration
FROM timerecordings
GROUP BY Project, Date, `Task name` WITH ROLLUP
Gives me (don't look at the date and time formating, it's excel that does it):
+-----------+------------------+------------+----------+----------+
| Project 1 | Task name 2 | 12/05/2016 | 00.22.03 | 00.22.03 |
| Project 1 | NULL | 12/05/2016 | 00.22.03 | 00.22.03 |
| Project 1 | 3. correction | 13/05/2016 | 00.08.00 | 00.08.00 |
| Project 1 | Small correction | 13/05/2016 | 00.02.02 | 00.02.02 |
| Project 1 | NULL | 13/05/2016 | 00.02.02 | 00.10.02 |
| Project 1 | Created low-res | 16/05/2016 | 00.04.21 | 00.04.21 |
| Project 1 | Last correction | 16/05/2016 | 00.05.36 | 00.05.36 |
| Project 1 | NULL | 16/05/2016 | 00.05.36 | 00.09.57 |
| Project 1 | NULL | NULL | 00.05.36 | 00.42.02 |
| Project 2 | Task name 1 | 12/05/2016 | 00.04.24 | 00.10.51 |
| Project 2 | NULL | 12/05/2016 | 00.04.24 | 00.10.51 |
| Project 2 | Layout | 24/05/2016 | 00.27.45 | 00.27.45 |
| Project 2 | NULL | 24/05/2016 | 00.27.45 | 00.27.45 |
| Project 2 | Finishing | 25/05/2016 | 00.15.48 | 00.15.48 |
| Project 2 | Layout | 25/05/2016 | 01.00.00 | 01.00.00 |
| Project 2 | NULL | 25/05/2016 | 01.00.00 | 01.15.48 |
| Project 2 | NULL | NULL | 01.00.00 | 01.54.24 |
| NULL | NULL | NULL | 01.00.00 | 02.36.26 |
+-----------+------------------+------------+----------+----------+
You can use GROUP_CONCAT aggregate function to combine all task names in one string. Use SEPARATOR keyword to define the separator (default: ','). Use DISTINCT if you don't want same task to be listed multiple times.
For one project:
SELECT Date,
GROUP_CONCAT(DISTINCT `Task name` SEPARATOR ', ') AS Task,
SEC_TO_TIME(SUM(TIME_TO_SEC(Duration))) AS Total
FROM timerecordings r
WHERE Project = 'Project 2'
GROUP BY Date WITH ROLLUP;
For all projects:
SELECT SELECT Project, Date,
GROUP_CONCAT(DISTINCT `Task name` SEPARATOR ', ') AS Task,
SEC_TO_TIME(SUM(TIME_TO_SEC(Duration))) AS Total
FROM timerecordings r
GROUP BY Project, Date WITH ROLLUP;
sqlfiddle
Must be something like
select date, taskName, sum(duration) from tasksTable where Project = "Project 2" group by date
But how will the times be added, and how will you get all the taskNames in one field is still to be experimented.
So just to let you have my final result:
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "timerecordings";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT
IFNULL (Project,'All Projects') Project,
IFNULL (Date,'Project total') Date,
GROUP_CONCAT(DISTINCT `Task name` SEPARATOR ', ') AS Task,
SEC_TO_TIME(SUM(TIME_TO_SEC(Duration))) AS Total
FROM timerecordingstable r
GROUP BY Project, Date WITH ROLLUP;
";
$result = $conn->query($sql);
$data = array();
while($row = $result->fetch_assoc()) {
$projectname = $row["Project"];
if (!array_key_exists($projectname, $data)) {
$data[$projectname] = array();
}
$data[$projectname][] = $row;
}
foreach ($data as $projectname => $rows) {
if($projectname != 'All Projects'){
echo '<h1>', $projectname, '</h1>';
echo '<table class="time-table"><tr class="table-header"><th>Date</th><th>Tasks</th><th>Time used</th><tr>';
foreach ($rows as $row) {
//Convert Total into seconds
$str_time = $row["Total"];
$str_time = preg_replace("/^([\d]{1,2})\:([\d]{2})$/", "00:$1:$2", $str_time);
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$time_seconds = $hours * 3600 + $minutes * 60 + $seconds;
// Round to nearest minute
$time_seconds = round($time_seconds/60)* 60;
$hours = floor($time_seconds / 3600); //Hours
$minutes = floor(($time_seconds / 60) % 60); //Minutes
//Convert minutes to two decimal number (like 15 minutes = 0.25 hour etc.)
$minutes = $minutes / 60;
$minutes = round($minutes,2);
$minutes = $minutes*100;
$seconds = $time_seconds % 60; //Seconds - I don't use it but kept to show it's possible
//Loop each row
if($row["Date"] == 'Project total'){
echo '<tr class="table-footer"><td>', $row["Date"] , '</td><td>' , ' ' , '</td><td>' , $hours, ',',$minutes, ' hour(s)</td></tr>';
} else {
$prettyDate = DateTime::createFromFormat('Y-m-j', $row["Date"]);
echo '<tr><td>', $prettyDate->format('d-m-Y') , ':</td><td>' , $row["Task"] , '</td><td>' , $hours, ',',$minutes, ' hour(s)</td></tr>';
}
}
echo '</table>';
}
}
$conn->close();
?>
Results:
<h1>Project 1</h1>
<table class="time-table">
<tr class="table-header">
<th>Date</th>
<th>Tasks</th>
<th>Time used</th>
<tr>
<tr>
<td>12-05-2016:</td>
<td>Task name 2</td>
<td>0,37 hour(s)</td>
</tr>
<tr>
<td>13-05-2016:</td>
<td>3. correction, Small correction</td>
<td>0,17 hour(s)</td>
</tr>
<tr>
<td>16-05-2016:</td>
<td>Last correction, Created low-res</td>
<td>0,17 hour(s)</td>
</tr>
<tr class="table-footer">
<td>Project total</td>
<td> </td>
<td>0,70 hour(s)</td>
</tr>
</table>
<h1>Project 2</h1>
<table class="time-table">
<tr class="table-header">
<th>Date</th>
<th>Tasks</th>
<th>Time used</th>
<tr>
<tr>
<td>12-05-2016:</td>
<td>Task name 1</td>
<td>0,18 hour(s)</td>
</tr>
<tr>
<td>24-05-2016:</td>
<td>Layout</td>
<td>0,47 hour(s)</td>
</tr>
<tr>
<td>25-05-2016:</td>
<td>Layout, Finishing</td>
<td>101,27 hour(s)</td>
</tr>
<tr class="table-footer">
<td>Project total</td>
<td> </td>
<td>101,90 hour(s)</td>
</tr>
</table>
My database design : http://i.stack.imgur.com/3Rm2e.png
I am trying to use below code :
$myselect = mysql_query("
SELECT
reason.ReasonName,
tblexam.EXAMDATE,
tblexam.EXAMTIME,
prefix.PREFIXABB,
studentmaster.STUDENTNAME,
studentmaster.STUDENTSURNAME,
studentmaster.STUDENTCODE,
program.PROGRAMNAME,
course.COURSENAMEENG
FROM
reason,
formlate,
tblexam,
studentmaster,
prefix,
program,
course
WHERE
reason.ReasonID = formlate.ReasonID AND
formlate.CLASSID = tblexam.CLASSID AND
formlate.COURSEID = formlate.COURSEID AND
formlate.ROOMID = formlate.ROOMID AND
prefix.PREFIXID = studentmaster.PREFIXID AND
formlate.STUDENTID = studentmaster.STUDENTID AND
program.PROGRAMID = studentmaster.PROGRAMID AND
course.COURSEID = tblexam.COURSEID
GROUP BY
reason.ReasonID,studentmaster.STUDENTID
ORDER BY
reason.ReasonID ASC");
<body>
<?php $i =1;
while($rowfet = mysql_fetch_array($myselect)){
?>
<h2><?php echo $rowfet['ReasonName']; ?></h2>
<h3><?php echo DateThai($rowfet['EXAMDATE']) . ' ' . MorningEvening($rowfet['EXAMTIME']); ?></h3>
<table width="100%" border="1">
<thead>
<tr>
<th>No.</th>
<th>studentid </th>
<th>Fullname </th>
<th>Program </th>
<th>Coursename </th>
</tr>
</thead>
<tbody>
<tr>
<td align="center"><?php echo $i; ?></td>
<td><?php echo $rowfet['STUDENTCODE']; ?></td>
<td><?php echo $rowfet['PREFIXABB'] . $rowfet['STUDENTNAME'] . ' '.$rowfet['STUDENTSURNAME']; ?></td>
<td><?php echo $rowfet['PROGRAMNAME']; ?></td>
<td><?php echo $rowfet['COURSENAMEENG']; ?></td>
</tr>
</tbody>
</table>
<?php $i++; } ?>
but it shows the result like :
Reason1
10 Jan 2015 (Morning)
| No | studentid | Fullname | Program | Coursename |
-------------------------------------------------------
| 1 | 111111 | John | ProgA | Math |
---------------------------------------------------------
Reason1
10 Jan 2015 (Morning)
| No | studentid | Fullname | Program | Coursename |
-------------------------------------------------------
| 2 | 2222222 | Jane | ProgB | Math |
-----------------------------------
Reason2
10 Jan 2015 (Evening)
| No | studentid | Fullname | Program | Coursename |
-------------------------------------------------------
| 3 | 3333333 | Hawk | ProgB | Math |
-----------------------------------
I want the result to show like :
Reason1
10 Jan 2015 (Morning)
| No | studentid | Fullname | Program | Coursename |
-------------------------------------------------------
| 1 | 111111 | John | ProgA | Math |
---------------------------------------------------------
| 2 | 2222222 | Jane | ProgB | Math |
-----------------------------------
Reason2
10 Jan 2015 (Evening)
| No | studentid | Fullname | Program | Coursename |
-------------------------------------------------------
| 1 | 3333333 | Hawk | ProgB | Math |
---------------------------------------------------------
I want to group table by
Reasonname
Examdate
Examtime
Please help, I'm a newbie.
I've create database in SQLFiddle Here this please try and help:
SQLFiddle
considered that you have a sql result that looks like this, ordered by reason, date and time :
reason.reasonName | examDate | examTime | prefix | studentName | studentSurname | studentCode | ProgramName | courseName
with a few records, like :
1 | someDate1 | someTime1 | A | James | Jim | 123 | PA | PACourse
1 | someDate1 | someTime1 | A | Tommy | Tim | 222 | PC | PCCourse
1 | someDate2 | someTime2 | B | James | Jim | 123 | PB | PBCourse
2 | someDate1 | someTime1 | C | Jamie | Jam | 444 | PD | PDCourse
2 | someDate1 | someTime1 | E | Willy | Wil | 555 | PE | PECourse
2 | someDate2 | someTime2 | F | Cathy | Cat | 777 | PF | PFCourse
2 | someDate2 | someTime2 | G | David | Dav | 844 | PL | PLCourse
2 | someDate3 | someTime3 | L | James | Jim | 123 | PM | PMCourse
3 | someDate4 | someTime4 | W | Ibear | Ibe | 999 | PX | PXCourse
Here, you get this kind of data, you have,
for reason 1 :
2 students with exam at the same day/time (time1)
1 student with axam at another time (time2)
for reason 2 :
2 students with exam at the same day/time (time1)
2 students with exam at the same day/time (time2)
1 student with exam at another time (time3)
for reason 3 :
1 student with exam at time 4
SO, you want to display :
2 tables for reason 1 (time1 / time2)
3 tables for reason 2 (time1 / time2 / time3)
1 table for reason 3
CONSIDERED that the table, when you get it from your SQL is REALLY oredered like what I wrote above, you have to make your checks on fetch :
<?php
//YOU WILL HAVE TO CHECK THESE VARS TO MAKE IT CLEAR, IF SAME TABLE OR NOT
$i = false;
//I use $i as a table detector, false at start, once a table has been opened it is turned as true
$reason = "";
//I will keep the latest reasonName in this
$examDate = "";
//I will keep the latest examDate in this
$examTime = "";
//I will keep the latest examTime in this
$yourDisplay = "";
//In yourDisplay, i keep the text i have to display (tables, data...)
$closeTable = "</tbody></table>";
//This is the code you need to close a table.
while($rowfet = mysql_fetch_array($myselect)){
if(($rowfet['ReasonName']!=$reason)||(DateThai($rowfet['EXAMDATE'])!=$examDate)||(MorningEvening($rowfet['EXAMTIME'])!=$examTime)){
//YOU GET HERE IF YOU HAVE DIFFERENT REASON/DATE/TIME, SO YOU HAVE TO MAKE A NEW TABLE
$reason = $rowfet['ReasonName'];
$examDate = DateThai($rowfet['EXAMDATE']);
$examTime = MorningEvening($rowfet['EXAMTIME']);
//NOW CHECK IF YOU ALREADY HAVE WRITTEN A TABLE BEFORE
if($i == true){
//You already have written a table before
$yourDisplay.=$closeTable;
}else{
//This is the first table you write
$i=true;
}
$yourDisplay.=" <h2>".$reason."</h2>
<h3>".DateThai($examDate)." ".MorningEvening($examTime)."</h3>
<table width='100%' border='1'>
<thead>
<tr>
<th>No.</th>
<th>studentid</th>
<th>fullname</th>
<th>Program</th>
<th>Coursename</th>
</tr>
</thead>
<tbody>
<tr>
<td>".$rowfet['STUDENTCODE']."</td>
<td>".$rowfet['PREFIXABB']." ".$rowfet['STUDENTNAME']." ".$rowfet['STUDENTSURNAME']."</td>
<td>".$rowfet['PROGRAMNAME']."</td>
<td>".$rowfet['COURSENAMEENG']."</td>
</tr>";
}else{
//YOU ARE ALREADY IN A TABLE! WITH SAME REASON/TIME/DATE
//YOUR RECORD JUST NEEDS TO BE ADDED IN A NEW LINE
$yourDisplay.="<tr>
<td>".$rowfet['STUDENTCODE']."</td>
<td>".$rowfet['PREFIXABB']." ".$rowfet['STUDENTNAME']." ".$rowfet['STUDENTSURNAME']."</td>
<td>".$rowfet['PROGRAMNAME']."</td>
<td>".$rowfet['COURSENAMEENG']."</td>
</tr>";
}
}
//ONCE OUT, CLOSE THE LAST TABLE AND DISPLAY YOUR DATA
if($i==1){
$yourDisplay.=$closeTable;
}
echo $yourDisplay;
?>
In My Opinion, this kind of approach should solve your problem IF THE SQL QUERY returns the rows as explained above. (seems like it is the case)
EDIT :
You asked to "not display" the reasonname if it was the same, so just look at the line you see this :
$yourDisplay.=" <h2>".$reason."</h2>
<h3>".DateThai($examDate)." ................ code continue
and replace it with this :
if($rowfet['ReasonName']!=$reason){
$yourDisplay.="<h2>".$reason."</h2>";
}
$yourDisplay.="<h3>".DateThai($examDate)." ".MorningEvening($examTime)."</h3>
<table width='100%' border='1'>
//.... continue the code
You're looping through all your rows and creating a table for each of the rows.
What you want to do is to create a new table only if a sequence of a new ReasonName starts.
$myselect = mysql_query("SELECT reason.ReasonName,tblexam.EXAMDATE,tblexam.EXAMTIME,prefix.PREFIXABB,studentmaster.STUDENTNAME,studentmaster.STUDENTSURNAME,studentmaster.STUDENTCODE,program.PROGRAMNAME,course.COURSENAMEENG FROM reason, formlate, tblexam, studentmaster,prefix, program, course WHERE reason.ReasonID = formlate.ReasonID AND formlate.CLASSID = tblexam.CLASSID AND formlate.COURSEID = formlate.COURSEID AND formlate.ROOMID = formlate.ROOMID AND prefix.PREFIXID = studentmaster.PREFIXID AND formlate.STUDENTID = studentmaster.STUDENTID AND program.PROGRAMID = studentmaster.PROGRAMID AND course.COURSEID = tblexam.COURSEID GROUP BY reason.ReasonID,studentmaster.STUDENTID ORDER BY reason.ReasonID ASC");
<body>
<?php $i =1;
while($rowfet = mysql_fetch_array($myselect)){
?>
<h2><?php echo $rowfet['ReasonName']; ?></h2>
<h3><?php echo DateThai($rowfet['EXAMDATE']) . ' ' . MorningEvening($rowfet['EXAMTIME']); ?></h3>
<table width="100%" border="1">
<thead>
<tr>
<th>No.</th>
<th>studentid </th>
<th>Fullname </th>
<th>Program </th>
<th>Coursename </th>
</tr>
</thead>
<tbody>
<?php echo "You should create a loop here to loop through your ReasonNames"; ?>
<tr>
<td align="center"><?php echo $i; ?></td>
<td><?php echo $rowfet['STUDENTCODE']; ?></td>
<td><?php echo $rowfet['PREFIXABB'] . $rowfet['STUDENTNAME'] . ' '.$rowfet['STUDENTSURNAME']; ?></td>
<td><?php echo $rowfet['PROGRAMNAME']; ?></td>
<td><?php echo $rowfet['COURSENAMEENG']; ?></td>
</tr>
<?php echo "Your loop should end here"; ?>
</tbody>
</table>
<?php $i++; } ?>
I have a table chart. Lets say 5 by 5. I run a loop such as
<table>
<tbody>
<?php for ($i = 0; $i < 5; $i += 5) {
echo "<tr>
<td>one box</td>
<td>one two</td>
<td>one three</td>
<td>one four</td>
<tr>";
}?>
</tbody>
</table>
It creates a table such as
| | | | | |
-------------------------------------
| | | | | |
-------------------------------------
| | | | | |
-------------------------------------
| | | | | |
-------------------------------------
| | | | | |
-------------------------------------
Now I have mysql data I load for my purposes and I need it to put the data in respectively so the table looks like
| | | | | |
-------------------------------------
| | | | | |
-------------------------------------
| | Res 1| | | |
-------------------------------------
| | | | Res 3| |
-------------------------------------
| |Res 4 | | | Res 2|
-------------------------------------
How would I do this? I have 50 results and need to fill the results into the correct column and row. I need to do some sort of if(results[0-50]['id'] == rowcolumnid) echo the results for the correct table while doing the for loop.
Edit: Here is my full code.
<table id="schedule">
<tbody>
<?php
$time = mktime(0, 0, 0, 1, 1);
for ($i = 28800; $i < 62200; $i += 1800) { ?>
<tr id="row<?php echo $i; ?>">
<td id="hour">
<?php
printf('%1$s',date('g:i a', $time + $i));
?>
</td>
<td id="sunday"></td>
<td id="monday"></td>
<td id="tuesday"></td>
<td id="thursday"></td>
<td id="friday"></td>
<td id="saturday"></td>
</tr>
<?php } ?>
</tbody>
</table>
My mysql results are in datetime format that I'm going to use to propogate the table.
Results:
ID| EVENT NAME | DATEOFEVENT
1 | event name | 2012-11-20 12:00:00
2 | event name | 2012-11-21 13:30:00
3 | event name | 2012-11-22 13:00:00
4 | event name | 2012-11-23 11:00:00
5 | event name | 2012-11-24 08:00:00
etc.
I can do a strtotime of the dates and a date command to match.
If you first fetch the data (or if it is sorted if you first fetch the first data), then you can just iterate over the data when you match the hour/time that you iterate over to draw the table.
As an example, I've chosen to display only one column that represents 5 hours (1-5) of which some can be matched. Those that are matched, are stored in an array and made available as an iterator (ArrayIterator):
$data = [3,5];
$datas = new ArrayIterator($data);
$datas->rewind();
Matched hours are represented with 1, unmatched ones with 0:
echo "+---+---+\n";
foreach(range(1, 5) as $hour)
{
if ($hasData = ($datas->valid() and $datas->current() === $hour)) {
$datas->next();
}
$hasData = (int) $hasData;
echo "| $hour | $hasData |\n";
echo "+---+---+\n";
};
Output:
+---+---+
| 1 | 0 |
+---+---+
| 2 | 0 |
+---+---+
| 3 | 1 |
+---+---+
| 4 | 0 |
+---+---+
| 5 | 1 |
+---+---+
This works perfectly if the data from the data is available as an iterator (often the case, for mysql_* you need to write you one) and if it is sorted.
Even this is only a single list here, for a table this works actually equally because a table is just a different form of representing the data.
I have two tabs named respectly liste_pieces and client_pieces.
The first contain a list of many elements about 1000. the second contain some element of the first.
Actually I'm doing a query to fullfill the second tab with the first.
Also I would like to display all element from the first that are not in the second.
I've thought I could do a joint pas a joint will only display elements that are in both tab.
And actually that is not what I'm looking for.
I've done that query for the moment
<table id="box-table-a" width="100%">
<tr>
<th scope="col" width="50%">LISTE DES PIÈCES</th>
<th scope="col" width="50%">AJOUT ?</th>
</tr>
<?php $sql="SELECT * FROM `liste_pieces`";
$result=mysql_query($sql) or die;$i=0;
while($data=mysql_fetch_assoc($result))
{?>
<tr>
<td><?php echo $data['libelle'] ; ?></td>
<td style="text-align:center" align="center">
<p align="center"> <input type="hidden" name="piece[<?php echo $i ; ?>]" value="0" /><input type="checkbox" class="checkbox" value="1" name="piece[<?php echo ++$i ; ?>]" id="piece[<?php echo ++$i ; ?>]" /></p></td>
</tr>
<?php } ?>
But this display to me all elements from the first tab. I do not really know how to remove elements that exists in the second tab.
I have the column id on liste_pices that is the same in the second tab except that it is called id_piece.
I'm a bit lost.
I do not know how to process.
Receive All my utmost Respect.
Kind regards.
SP.
This query should do the trick for you. Yes, it is a join query by the way that you are asking for:
select
a.col1,
a.col2,
b.col1 // etc
from
liste_pieces a
join client_pieces b
on a.id=b.id_peice
where b.id_piece is null
Here is an example from my database:
mysql> select id, brand from cars;
+----+-------+
| id | brand |
+----+-------+
| 1 | 2 |
| 2 | 1 |
| 3 | 3 |
| 4 | 4 |
| 5 | 2 |
| 6 | 5 |
| 7 | 1 |
| 8 | 2 |
| 9 | 2 |
| 10 | 5 |
| 11 | 2 |
+----+-------+
11 rows in set (0.00 sec)
mysql> select id, brand from brands;
+----+--------+
| id | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 3 | Nissan |
| 4 | Smart |
| 5 | BMW |
| 6 | Holden |
+----+--------+
6 rows in set (0.00 sec)
select
a.brand
from
brands a
left join cars b
on a.id=b.brand
where
b.brand is null
+--------+
| brand |
+--------+
| Holden |
+--------+
1 row in set (0.00 sec)
Also: I just wrote a really lengthy question and answer that covers this exact sort of question which I hope will help to clarify how joins work on tables and how to get information from multiple tables in your database!
Use queries like this
"select * from liste_pieces where column_name not IN (select column_name from client_pieces)"
and
"select * from client_pieces where column_name not IN (select column_name from liste_pieces )"
This will solve your problem, the column_name should present in both table with same datatype.
I have 3 TABLES products, products_extra_fields, products_to_products_extra_fields
products TABLE
+-------------+--------------+---------------+
| products_id | categories_id| products_name |
+-------------+--------------+---------------+
| 1 | 1 | product 1 |
| 2 | 1 | product 2 |
+-------------+--------------+---------------+
products_extra_fields TABLE
+--------------------------+---------------------------+
| products_extra_fields_id | products_extra_fields_name|
+--------------------------+---------------------------+
| 1 | sugar |
| 2 | cocoa |
| 3 | butter |
| 4 | milk |
+--------------------------+---------------------------+
products_to_products_extra_fields TABLE
+-------------+---------------------------+-----------------------------+
| products_id | products_extra_fields_id | products_extra_fields_value |
+-------------+---------------------------+-----------------------------+
| 1 | 1 | 20% |
| 1 | 2 | 45% |
| 1 | 3 | 27% |
| 2 | 1 | 12% |
+-------------+---------------------------+-----------------------------+
I wanna edit product 1 I use this query:
SELECT
products_name,
products_extra_fields_name,
products_extra_fields_value FROM products, products_extra_fields, products_to_products_extra_fields
WHERE products_to_products_extra_fields.products_extra_fields_id = products_extra_fields.products_extra_fields_id AND
products_to_products_extra_fields.products_id=1
GROUP BY products_extra_fields.products_extra_fields_id;
+---------------+---------------------------+----------------------------+
| products_name | products_extra_fields_name| products_extra_fields_value|
+---------------+---------------------------+----------------------------+
| product 1 | sugar | 20% |
| product 1 | cocoa | 45% |
| product 1 | butter | 27% |
+---------------+---------------------------+----------------------------+
But I wanna see
products_extra_fields_name (milk) with no value
+---------------+---------------------------+----------------------------+
| products_name | products_extra_fields_name| products_extra_fields_value|
+---------------+---------------------------+----------------------------+
| product 1 | sugar | 20% |
| product 1 | cocoa | 45% |
| product 1 | butter | 27% |
| product 1 | milk | |
+---------------+---------------------------+----------------------------+
and for product 2 cocoa, butter, milk with no value only sugar 12%
What can I do to get the results I want.
look at my php script (products_edit2.php?id=1 or 2 )
<?php
require ('mysql/mysql_connect.php'); // Connect to the database.
if (is_numeric ($_GET['id']) ) {
$query = "SELECT
products_name, products_extra_fields_name, products_extra_fields_value FROM
products, products_extra_fields, products_to_products_extra_fields WHERE
products_to_products_extra_fields.products_extra_fields_id = products_extra_fields.products_extra_fields_id AND
products_to_products_extra_fields.products_id = {$_GET['id']}
GROUP BY products_extra_fields.products_extra_fields_id";
if ($result = mysql_query ($query)) {
$query2 = "SELECT products_name FROM products WHERE products_id={$_GET['id']}";
if ($result2 = mysql_query ($query2)) {
$row2 = mysql_fetch_array ($result2);
$products_name = $row2['products_name'];
?>
<form action='products_edit.php' enctype='multipart/form-data' method='POST'>
<table width="50%" border="0" cellpadding="2" cellspacing="2">
<tr>
<td width="20%" align="right">PRODUCTS NAME:</td>
<td><input type="text" name="products_name" size="80" value="<?php echo $products_name; ?>" /></td>
</tr>
<?php
}
/***** ***** *****/
while ($row = mysql_fetch_assoc ($result)) {
$products_extra_fields_name = $row['products_extra_fields_name'];
$products_extra_fields_value = $row['products_extra_fields_value'];
$products_extra_fields_id = $row['products_extra_fields_id'];
?>
<tr>
<td width="20%" align="right"><?php echo $products_extra_fields_id .'-'. $products_extra_fields_name; ?></td>
<td><input type="text" name="categories_name" size="80" value="<?php echo $products_extra_fields_value; ?>" /></td>
</tr>
<?php }
/***** ***** END *****/
?>
<input type="hidden" name="categories_id" size="10" value="<?php echo $_GET['id']; ?>" />
<tr>
<td width="100%" colspan="2" align="right"><input type="submit" name="submit" value="SAVE"/></td>
</tr>
</table>
</form>
<?php
} else { // Couldn't get the information.
print "<p>Could retrieve the entry because: <b>" . mysql_error() . "</b><br/><br/>. The query was $query.</p>";
}
}else{ // No ID set.
print '<p><b>You must have made a mistake in using this page.</b></p>';
}
?>
</body>
</html>
I wanna see all 4 products_extra_fields_name and 4 input box (product 1 have 3 value 1 null, product 2 have 1 value 3 null)
When you use a comma separated list in FROM, MySQL uses an Inner Join. To get what you want, you need to use a Left Join.
SELECT
products_name,
products_extra_fields_name,
products_extra_fields_value
FROM products, products_extra_fields
LEFT JOIN products_to_products_extra_fields
ON products_to_products_extra_fields.products_extra_fields_id = products_extra_fields.products_extra_fields_id
AND products_to_products_extra_fields.products_id=1
GROUP BY products_extra_fields.products_extra_fields_id;
This should produce:
+---------------+---------------------------+----------------------------+
| products_name | products_extra_fields_name| products_extra_fields_value|
+---------------+---------------------------+----------------------------+
| product 1 | sugar | 20% |
| product 1 | cocoa | 45% |
| product 1 | butter | 27% |
| product 1 | milk | NULL |
+---------------+---------------------------+----------------------------+