Dynamically create HTML table from sql query result - php

how can i write the sql query to get rows from multiple MySQL table and then output it to an HTML table as the format below.
I've been trying this for hours and I'm still not getting it.
Below is the HTML structure that I am trying to create
----------------------------------------------------------------
|student_id | full_name | TERM 1 | TERM2 | TERM 3 | TERM 4 |
----------------------------------------------------------------
| 1 | John Doe | 67 | 90 | NA | NA |
| 2 | John Smi | NA | NA | NA | NA |
| 3 | Doe John | 88 | 66 | NA | NA |
| 4 | Mike Doe | 57 | 78 | NA | NA |
| 5 | Doe Mike | NA | NA | NA | NA |
| 6 | Sam Doe | NA | NA | NA | NA |
----------------------------------------------------------------
And Here are the structures for the MySQL tables
--------------------------
| student_id | full_name |
--------------------------
| 1 | John Doe |
| 2 | John Smi |
| 3 | Doe John |
| 4 | Mike Doe |
| 5 | Doe Mike |
| 6 | Sam Doe |
--------------------------
------------------------
| exam_id | exam_name |
------------------------
| 11 | TERM 1 |
| 12 | TERM 2 |
| 13 | TERM 3 |
| 14 | TERM 4 |
------------------------
----------------------------------------
| subject_id | exam_id | subject_name |
----------------------------------------
| 1 | 11 | mathematics |
| 2 | 11 | english |
| 3 | 11 | physics |
| 4 | 12 | mathematics |
| 5 | 12 | english |
| 6 | 12 | physics |
----------------------------------------
---------------------------------------------
| subject_id | marks | student_id |
---------------------------------------------
| 1 | 67 | 1 |
| 2 | 54 | 4 |
| 3 | 88 | 3 |
| 4 | 90 | 1 |
| 5 | 78 | 4 |
| 6 | 66 | 3 |
---------------------------------------------
Thanks.

This is the query you want:
select s.student_id,
s.full_name,
avg(case when te.exam_name = 'TERM 1' then sm.marks else null end) as term_1,
avg(case when te.exam_name = 'TERM 2' then sm.marks else null end) as term_2,
avg(case when te.exam_name = 'TERM 3' then sm.marks else null end) as term_3,
avg(case when te.exam_name = 'TERM 4' then sm.marks else null end) as term_4
from students s
left join subject_marks sm
on s.student_id = sm.student_id
left join subject_exams se
on sm.subject_id = se.subject_id
left join term_exams te
on se.exam_id = te.exam_id
group by s.student_id,
s.full_name
Fiddle: http://sqlfiddle.com/#!2/fd1c82/1/0
As for outputting it to an HTML table, you want to look at a PHP/MySQL tutorial.

Related

How to query from 3 tables like this [duplicate]

This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 3 years ago.
Suppose I have three table project, and I want to make a html with the correct values from database with php.
I have tried like this:
select (SELECT group_concat(DISTINCT wine_name) FROM wine) as wine_name UNION SELECT username FROM user;
Evaluate table
-----------------------------------------------------------------------------
| ev_id | user_id | wine_id | point
-----------------------------------------------------------------------------
| 1 | 1 | 1 | 80
| 2 | 2 | 1 | 67
| 3 | 1 | 2 | 87
| 5 | 2 | 2 | 97
| 6 | 2 | 3 | 81
| 7 | 3 | 2 | 99
| 8 | 3 | 3 | 66
| 9 | 3 | 1 | 79
-----------------------------------------------------------------------------
Wine Table
-----------------------------------------------------------------------------
| wine_id | wine_name | wine_type | wine_color
-----------------------------------------------------------------------------
| 1 | Dominio Campo | sweet | red
| 2 | Guitian Godello | dry | white
| 3 | Cosme Palacio | dry | red
| 4 | Azpilicueta | sweet | red
| 5 | Parotet Vermell | sweet | white
-----------------------------------------------------------------------------
User Table
-----------------------------------------------------------------------------
| user_id | user name | name | email
-----------------------------------------------------------------------------
| 1 | user1 | dsa | asd#asd.com
| 2 | user2 | dsd | abd#asd.com
| 3 | user3 | dss | acd#asd.com
| 4 | user4 | sdd | add#asd.com
| 5 | user5 | ssd | aed#asd.com
-----------------------------------------------------------------------------
Here I want to query from three table like this and display the result.
-----------------------------------------------------------------------------
| | Dominio Campo | Guitian Godello | Cosme Palacio |
-----------------------------------------------------------------------------
| user1 | 80 | 87 | 77 |
| user2 | 67 | 97 | 81 |
| user3 | 79 | 99 | 66 |
-----------------------------------------------------------------------------
This is all the query you need:
SELECT w.*
, e.user_id
, e.point
FROM wine w
JOIN evaluate e
ON e.wine_id = w.wine_id
ORDER
BY e.wine_id
, user_id;
Everything else can and should be done in your application code.

How to select mysql results?

invoice
+----+-----+---------+-------+
| Sr | BRN | Name | Amnt |
+----+-----+---------+-------+
| 1 | 1 | John | 10 |
| 2 | 1 | John | 4 |
| 3 | 2 | Belly | 4 |
| 4 | 3 | John | 14 |
| 5 | 4 | John | 5 |
| 6 | 4 | John | 14 |
+----+-----+---------+-------+
I want to select all rows except the duplicate BRN. (If there are two/more ge in BRN then it should only select one)
I tried:
SELECT *(DISTINCT BRN) FROM invoice
Expected result:
+-----+---------+-------+
| BRN | Name | Amnt |
+-----+---------+-------+
| 1 | John | 10 |
| 2 | Belly | 4 |
| 3 | John | 14 |
| 4 | John | 5 |
+-----+---------+-------+
Given the following table:
+----+-----+---------+-------+
| Sr | BRN | Name | Amnt |
+----+-----+---------+-------+
| 1 | 1 | John | 10 |
| 2 | 1 | John | 4 |
| 3 | 2 | Belly | 4 |
| 4 | 3 | John | 14 |
| 5 | 4 | John | 5 |
| 6 | 4 | John | 14 |
+----+-----+---------+-------+
with the expected results:
+-----+---------+-------+
| BRN | Name | Amnt |
+-----+---------+-------+
| 1 | John | 10 |
| 2 | Belly | 4 |
| 3 | John | 14 |
| 4 | John | 5 |
+-----+---------+-------+
The difficult part is getting the amount, because it is arbitrary, not to mention that the values in Amnt are pretty much worthless in this result.
If you want distinct BRN, the query would be SELECT DISTINCT BRN FROM invoice
You might even get away with SELECT DISTINCT BRN, Name FROM invoice
An intermediate step would be SELECT BRN,Name FROM invoice GROUP BY BRN, Name
But if you try to include Amnt in the equation, then the query will fail because there's no way for the database to determine which Amnt to show.
So, you could try this kludge:
SELECT a.BRN, a.Name, b.Amnt FROM invoice AS a LEFT JOIN invoice AS b ON a.BRN=b.BRN
No guarantees on which Amnt it will pick up, though.
Hope that helps.
SELECT * FROM invoice WHERE Date >= :fdate GROUP BY BRN
See Here Use GROUP BY in Query with your Conditions

Connect 2 columns to 1 column

I need to connect 2 columns to 1 column, but I can't figure it out how to connect those columns.
This is how it looks like:
Table(appointment)
-------------------------------------------
| id | home | salesman | buyer | date |
| 1 | 3 | 2 | 4 | 12-6-2016|
| 2 | 1 | 1 | 3 | 15-6-2016|
| 3 | 2 | 5 | 6 | 20-6-2016|
-------------------------------------------
Table(person)
---------------------------------------------------------
| id | name | email | phonenumber | permission |
| 1 | John | John#gmail.com | 12345678 | 1 |
| 2 | Jack | Jack#gmail.com | 12345678 | 1 |
| 3 | Henk | Henk#gmail.com | 12345678 | 0 |
| 4 | Mike | Mike#gmail.com | 12345678 | 0 |
| 5 | Tom | Tom#gmail.com | 12345678 | 1 |
| 6 | Ben | Ben#gmail.com | 12345678 | 0 |
---------------------------------------------------------
Table(home)
--------------------------------------
| id | salesman | price | city |
| 1 | 2 | 123000 | London |
| 2 | 1 | 123000 | New York |
| 3 | 5 | 123000 | Paris |
--------------------------------------
This is how I want to see it on my php page:
-------------------------------------------------
| home | salesman | buyer | date |
| Home in Paris | Jack | Mike | 12-6-2016|
| Home in London | John | Henk | 15-6-2016|
| Home in New York| Tom | Ben | 20-6-2016|
-------------------------------------------------
People with permission 1 are salesman, permission 0 are buyers.
So my question is, how can I change the numbers to the correct value? Without change the number in table appointment to values in the database...
I don't know much about SQL, so could someone please come with a solution that isn't an example and works with my tables and columns?
Edit:
Table(afspraak)
-------------------------------------------
| id | huis | verkoper | koper | datum |
| 1 | 3 | 2 | 4 | 12-6-2016|
| 2 | 1 | 1 | 3 | 15-6-2016|
| 3 | 2 | 5 | 6 | 20-6-2016|
-------------------------------------------
Table(persoon)
---------------------------------------------------------
| id | naam | email | phonenumber | rechten |
| 1 | John | John#gmail.com | 12345678 | 1 |
| 2 | Jack | Jack#gmail.com | 12345678 | 1 |
| 3 | Henk | Henk#gmail.com | 12345678 | 0 |
| 4 | Mike | Mike#gmail.com | 12345678 | 0 |
| 5 | Tom | Tom#gmail.com | 12345678 | 1 |
| 6 | Ben | Ben#gmail.com | 12345678 | 0 |
---------------------------------------------------------
Table(huis)
--------------------------------------
| id | verkoper | prijs | stad |
| 1 | 2 | 123000 | London |
| 2 | 1 | 123000 | New York |
| 3 | 5 | 123000 | Paris |
--------------------------------------
My php code:
include('config.php');
$getAfspraak = "SELECT CONCAT('Home in ', HO.stad) AS Home,
SA.`naam` AS verkoper,
BU.`naam` AS koper,
AP.`datum`
FROM afspraak AP
INNER JOIN huis HO ON HO.id = AP.huis
INNER JOIN persoon SA ON SA.id = AP.verkoper AND SA.rechten = 1
INNER JOIN persoon BU ON BU.id = AP.koper AND BU.rechten = 0";
//Inner join for huis SELECT afspraak.huis, huis.stad FROM afspraak INNER JOIN huis ON afspraak.huis = huis.id; This query should show "huis in [stad]" it means, a home in London.
$dataAfspraak = mysqli_query($con, $getAfspraak) or die(mysqli_error($con));
<table cellspacing=1 border=0 width=100%>
<tr>
<th>Koper</th>
<th>Verkoper</th>
<th>Huis</th>
<th>Datum</th>
</tr>
<?php while($resAfspraak = mysqli_fetch_assoc($dataAfspraak)): ?>
<tr>
<td><?php echo $resAfspraak['koper']?></td> <!-- value is naam if the row has 0 at rechten -->
<td><?php echo $resAfspraak['verkoper']?></td> <!-- value is naam if the row has 1 at rechten -->
<td><?php echo $resAfspraak['huis']?></td>
<td><?php echo $resAfspraak['datum']?></td>
</tr>
<?php endwhile;?>
By the below JOIN and CONCAT query you can achieve your expected result:
SELECT CONCAT('Home in ', HO.city) AS Home,
SA.`Name` AS Salesman,
BU.`Name` AS Buyer,
AP.`Date`
FROM Appointment AP
INNER JOIN Home HO ON HO.Id = AP.Home
INNER JOIN Person SA ON SA.Id = AP.Salesman AND SA.Permission = 1
INNER JOIN Person BU ON BU.Id = AP.Buyer AND BU.Permission = 0
UPDATE:
You no need to get the huis value from separate join. The below query returns the koper, verkoper, huis and datum values.
$getAfspraak = "SELECT BU.naam AS koper, SA.naam AS verkoper, CONCAT('Huis in ', HO.stad) AS Huis, AP.datum
FROM afspraak AP
INNER JOIN huis HO ON HO.id = AP.huis
INNER JOIN persoon SA ON SA.id = AP.verkoper AND SA.rechten = 1
INNER JOIN persoon BU ON BU.id = AP.koper AND BU.rechten = 0";
$dataAfspraak = mysqli_query($con, $getAfspraak) or die(mysqli_error($con));

Treat data from mysql for html

I want to treat data from mysql for display in HTML, using PHP.
I have three database tables: student, course, student_x_course
student:
| idStudent | firstname | surname |
-----------------------------------
| 1 | John | Regular |
| 2 | John | Smith |
| 3 | Claire | White |
course:
| idCourse | coursename |
--------------------------
| 1 | Art |
| 2 | Music |
| 3 | Math |
| 3 | Biology |
student_x_course:
| idsc | idStudent | idCourse |
-------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 2 | 4 |
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| 9 | 3 | 3 |
| 10 | 3 | 4 |
And I want to create an html table which looks like this:
| Art | Music | Math | Biology |
------------------------------------------------
John Regular | x | x | x | - |
John Smith | x | x | - | x |
Claire White | x | x | x | x |
My sql query is:
SELECT s.firstname, s.surname, c.coursename FROM student AS s INNER JOIN student_x_course AS sxc ON (s.idStudent = sxc.idStudent) INNER JOIN course ON (c.idCourse = sxc.idCourse);
which gets me the following:
| John | Regular | Art |
| John | Regular | Music |
| John | Regular | Math |
| John | Smith | Art |
| John | Regular | Music |
| John | Smith | Biology |
| Claire | White | Art |
| Claire | White | Music |
| Claire | White | Math |
| Claire | White | Biology |
My question is: How can I get from many rows to lines?
Is there a better sql query or do I have to handle this in PHP Code?
Any suggestions?
You are trying to pivot your results. In mysql, you can do this with conditional aggregation:
SELECT s.idStudent, s.firstname, s.surname,
max(case when c.coursename = 'Art' then 'x' end) Art,
max(case when c.coursename = 'Music' then 'x' end) Music,
max(case when c.coursename = 'Math' then 'x' end) Math,
max(case when c.coursename = 'Biologoy' then 'x' end) Biologoy
FROM student AS s
INNER JOIN student_x_course AS sxc ON (s.idStudent = sxc.idStudent)
INNER JOIN course ON (c.idCourse = sxc.idCourse)
GROUP BY s.idStudent

MySQL query to show a format based on three tables

I have three tables below that shows the student records, subjects and students with subjects.
I would like to ask what is the effective SQL query to show the results below. I can show it using JOIN but not with the format below.
+------+-----------+-----------+-----+----------+-----------+--------+
| Name | Address | Telephone | Sex | Subjects | Teacher | Active |
+------+-----------+-----------+-----+----------+-----------+--------+
| John | somewhere | 12345 | M | | Teacher 1 | YES |
| John | somewhere | 12345 | M | Math | | YES |
| John | somewhere | 12345 | M | Science | | YES |
| John | somewhere | 12345 | M | English | | YES |
| Matt | somewhere | 123456 | M | | Teacher 2 | YES |
| Matt | somewhere | 23456 | M | Math | | YES |
| Matt | somewhere | 123456 | M | Science | | YES |
| Girl | somewhere | 5431 | F | | Teacher3 | YES |
| Girl | somewhere | 5431 | F | Physics | | YES |
| Girl | somewhere | 5431 | F | Math | | YES |
+------+-----------+-----------+-----+----------+-----------+--------+
select * from student_record;
+------------+------+-----------------+-----------+-----+----------+--------+
| id_student | name | address | telephone | sex | teacher | active |
+------------+------+-----------------+-----------+-----+----------+--------+
| 1 | John | Somewhere | 12345 | M | Teacher | 0 |
| 2 | Matt | Somewhere There | 12345222 | M | Teacher1 | 0 |
| 3 | Girl | Somewhere here | 3333 | F | Teacher2 | 0 |
+------------+------+-----------------+-----------+-----+----------+--------+
select * from subjects;
+------------+--------------+---------------------+
| id_subject | subject_name | subject_description |
+------------+--------------+---------------------+
| 1 | Math | Math |
| 2 | Science | Science |
| 3 | English | English |
| 4 | Physics | Physics |
+------------+--------------+---------------------+
select * from with_subjects;
+--------------------+--------------------+------------+
| id_student_subject | student_id_subject | student_id |
+--------------------+--------------------+------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 4 | 2 |
| 6 | 3 | 2 |
| 8 | 1 | 2 |
| 9 | 1 | 3 |
| 10 | 2 | 3 |
| 11 | 3 | 3 |
| 12 | 4 | 3 |
+--------------------+--------------------+------------+
how about
select a.name as "Name",a.address as "Address",a.telephone as "Telephone" ,a.sex as "Sex",null as "Subject",a.teacher as "Teacher",a.active as "Active" from student_record as a
union a.name as "Name",a.address as "Address",a.telephone as "Telephone" ,a.sex as "Sex",b.subject_name as "Subject",null as "Teacher",a.active as "Active" from (student_record as a inner join with_subjects as c on a.id_student = c.student_id) inner join subjects as b on c.student_id_subject = b.id_subject
Not tested it. It wotn be in the same order as your example, but should have all of the data there

Categories