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
Related
I am trying to count how many require position there are for each jobseeker.
I have two tables: jobseeker and jobposition.
jobseeker:
+----+---------+-----------+----------------+
| id | fb_name | fullname | desireposition |
+----+---------+-----------+----------------+
| 1 | John | John Cena | 3 |
| 2 | Christ | Christ | 4 |
| 3 | Thomas | Cfitcher | 2 |
+----+---------+-----------+----------------+
and jobposition:
+----+--------+------------------+
| id | job_id | require_position |
+----+--------+------------------+
| 1 | 12 | 3 |
| 2 | 13 | 3 |
| 3 | 14 | 4 |
| 4 | 15 | 5 |
| 5 | 16 | 4 |
| 6 | 17 | 3 |
+----+--------+------------------+
My expected result is:
+----+---------+-----------+----------------+-----------------------+
| id | fb_name | fullname | desireposition | total_requireposition |
+----+---------+-----------+----------------+-----------------------+
| 1 | John | John Cena | 3 | 3 |
| 2 | Christ | Christ | 4 | 2 |
| 3 | Thomas | Cfitcher | 2 | 0 |
+----+---------+-----------+----------------+-----------------------+
I want to count how many require position there for each jobseeker.
Here is what I tried using crossJoin, but am unsure which join I actually need to be using.
$jobseekers = Jobseeker::crossJoin('jobpositions')
>select('fullname','fb_name','desire_position', DB::raw('count(require_position) as total_requireposition'))
->groupBy('fullname')->paginate(10);
Can anyone help guide me? Any help would be highly appreciated.
The regular MySQL query you want is:
SELECT s.id, fullname, fb_name, desireposition, IFNULL(COUNT(require_position), 0) AS require_position
FROM jobseeker AS s
LEFT JOIN jobposition AS p ON s.desireposition = p.require_position
GROUP BY s.id
I don't use Laravel, but I think the translation would be:
$Jobseeker->select('fullname','fb_name','desire_position', DB::raw('IFNULL(COUNT(require_position), 0) as total_requireposition'))
->leftjoin('jobposition', 'desireposition', '=', 'require_position')
->groupBy('jobseeker.id')
->paginate(10)
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
I get form db field (organisations.paths)the following strings:
/1/2/3/4
Each number is the id of organisation's name from this db table:
+----+-------------+----------+----------+----------------------+
| id | frameworkid | path | parentid | fullname |
+----+-------------+----------+----------+----------------------+
| 1 | 1 | /1 | 0 | NYC University |
| 2 | 1 | /2 | 0 | Board of directors |
| 3 | 1 | /1/2/3 | 1 | Math faculty |
| 4 | 1 | /1/2/3/4 | 3 | Statistic department |
| 5 | 1 | /1/2/3/5 | 2 | Linguist department |
+----+-------------+----------+----------+----------------------+
Then I have the description table for each organisation:
+----+----------+---------+----------------+
| id | data | fieldid | organisationid |
+----+----------+---------+----------------+
| 1 | HQ | 1 | 1 |
| 2 | advisory | 1 | 2 |
| 3 | advisory | 1 | 3 |
| 4 | bottom | 1 | 4 |
| 5 | advisory | 1 | 5 |
+----+----------+---------+----------------+
How to join the both description table and main table and loop only through organisations, which have HQ or advisory in their description? So it becomes:
NYC University, Board of directors, Math faculty (Statistic department-won't be shown, as it is with description bottom)
You need to use explode, IN and join Function of PHP and mysql.
$var = "/1/2/3/4";
$in = join(" , ", explode("/", ltrim($var, '/')));
$sql = "SELECT `dt`.`fullname` FROM `db_table` dt
LEFT JOIN `organization` o
ON `o`.`organisationid` = `dt`.`id`
WHERE `o`.`id` IN ($in) AND (`o`.`data` = 'HQ' OR `o`.`data` = 'advisory')";
Make a loop to get the names and show them as you want.
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
I am having the following tables in my DB
PROJECTS
+----+-------------------------------------------+
| id | name |
+----+-------------------------------------------+
| 1 | YANNONALI COURT |
| 2 | UNIVERSITY OF COLORARDO DENVER RESEARCH 2 |
| 3 | G.R.E.A.T PROGRAM DESALTER BUILDING |
| 4 | MONARCH CLUB |
| 5 | LAFAYETTE MERCANTILE |
| 6 | CAMELBACK VILLAGE RAQUET AND HEALTH CLUB |
| 7 | BACK COUNTRY |
| 8 | URBAN CRASHPAD |
| 9 | PRIVATE RESIDENCE |
| 10 | EATON RESIDENCE |
+----+-------------------------------------------+
PROJECT_ASSIGNMENTS(WHERE projects.id=project_assignment.target_id)
+-------+-----------+-------------+
| id | target_id | property_id |
+-------+-----------+-------------+
| 19178 | 1 | 48 |
| 19192 | 1 | 39 |
| 19391 | 1 | 3 |
| 19412 | 2 | 3 |
| 19591 | 2 | 34 |
| 19610 | 2 | 34 |
| 21013 | 3 | 2 |
| 21032 | 3 | 2 |
| 30876 | 4 | 2433 |
| 38424 | 5 | 2580 |
+-------+-----------+-------------+
PROPERTIES(WHERE properties.id= project_assignment.property_id)
+----+------------------+
| id | name |
+----+------------------+
| 2 | Residential |
| 3 | Multi Family |
| 34 | New Construction |
| 39 | Contemporary |
| 48 | Southwest |
+----+------------------+
I want O/P ordered by no.of projects in the list...
Residential(177) //12 - total no.of projects which is having this property
Multi Family(15)
New Construction(13)
Contemporary(11)
please give me some MySQL queries
Thank You
This should do the trick:
select
c.name,
count(c.id) as CountOfProperties
from
projects a,
project_assignments b,
properties c
where
a.ID=b.target_id
and b.property_id=c.ID
group by
c.name
order by
count(c.id) desc;
Try this::
select
prop.name,
count(prop.id) as CountOfProperties
from
projects p
inner join project_assignments pa on (p.ID=pa.target_id)
inner join properties prop on (pa.property_id=prop.ID)
group by
prop.name
order by
count(prop.id) desc;