MySQL query to show a format based on three tables - php

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

Related

Color Coding a Table Based on the Count of a Column in the Table

So I have a table. What it does is it has a count for different users. I want to color code it so that a certain color shows up based on the count for the users. So if the count is 0 it will be green. If the count is 1-2 it will be yellow. If the count is 3+ it will be red. I would like a query that can do this. The current search query for the table is "SELECT * FROM table1 WHERE firstname ='$name'"
+--------------------------------------------------------------------------+
| ID | firstname | lastname | address | count |
| | | | | |
+--------------------------------------------------------------------------+
| 1 | john | doe |james street, idaho, usa | 2 |
| | | | | |
+--------------------------------------------------------------------------+
| 2 | cindy | smith |rollingwood av,lyn, canada| 0 |
| | | | | |
+--------------------------------------------------------------------------+
| 3 | rita | chatsworth |arajo ct, alameda, cali | 1 |
| | | | | |
+--------------------------------------------------------------------------+
| 4 | randy | plies |smith spring, lima, (peru)| 2 |
| | | | | |
+--------------------------------------------------------------------------+
| 5 | Matt | gwalio |park lane, (atlanta), usa | 4 |
| | | | | |
+--------------------------------------------------------------------------+```
Here is the table with the

How to join other table and count the row in laravel?

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)

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

Cross database multiple records with join in MySQL

In this case each person can be assigned to an unlimited number of companies. One of these assigned companies should always be the person's main company. As you can see in the SQL query which I have posted the ID of the person's main organization is stored in the column "main_company_id" in the "person" table.
I have database Internal on server 192.168.0.1 with Person_Company Table as given
+----+-----------+------------+------------+
| id | person_id | company_id | created_at |
+----+-----------+------------+------------+
| 1 | 1005 | 2589 | 00:00:00 |
| 2 | 1006 | 2590 | 00:00:00 |
| 3 | 1007 | 2591 | 00:00:00 |
+----+-----------+------------+------------+
Person Table is as given
+------+-------+---------+-----------------+-----------------+
| id | name | phone | main_company_id | ref_id |
+------+-------+---------+-----------------+-----------------+
| 1005 | John | 0123456 | 2590 | 273722702297768 |
| 1006 | Doe | 7894560 | 2591 | 955413080598021 |
| 1007 | Smith | 9517530 | 2589 | 164283934074454 |
+------+-------+---------+-----------------+-----------------+
Company Table is as given
+------+-----------+---------+-----------------+
| id | name | vat | ref_id |
+------+-----------+---------+-----------------+
| 2589 | Company A | 0123456 | 540603005841231 |
| 2590 | Company B | 7894560 | 725472422399397 |
| 2591 | Company C | 9517530 | 367043795528136 |
+------+-----------+---------+-----------------+
Now there is another database External on the same server 192.168.0.1 with External_Person tables as given:
+----+-----------------+-------+----------------------+--------+
| id | ref_id | name | internal_primary_key | gender |
+----+-----------------+-------+----------------------+--------+
| 1 | 273722702297768 | John | ABC123456 | male |
| 2 | 955413080598021 | Doe | BCD456789 | female |
| 3 | 164283934074454 | Smith | DEF789456 | male |
+----+-----------------+-------+----------------------+--------+
And another table on this External database is External_Company
+----+-----------------+-----------+----------------------+
| id | ref_id | name | internal_primary_key |
+----+-----------------+-----------+----------------------+
| 1 | 540603005841231 | Company A | XX4123456 |
| 2 | 725472422399397 | Company B | XX5456789 |
| 3 | 367043795528136 | Company C | XX6789456 |
+----+-----------------+-----------+----------------------+
What I want to achieve is like this result:
+----+------------+-------------+------------------+
| id | person_key | company_key | main_company_key |
+----+------------+-------------+------------------+
| 1 | ABC123456 | XX4123456 | XX5456789 |
| 2 | BCD456789 | XX5456789 | XX6789456 |
| 3 | DEF789456 | XX6789456 | XX4123456 |
+----+------------+-------------+------------------+
I have already achieved two columns through this statement:
SELECT EEP.internal_primary_key as Person_Key, EEC.internal_primary_key as Company_Key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
WHERE IPC.person_id = 1005;
And this has the output like this result:
+----+------------+-------------+
| id | person_key | company_key |
+----+------------+-------------+
| 1 | ABC123456 | XX4123456 |
| 2 | BCD456789 | XX5456789 |
| 3 | DEF789456 | XX6789456 |
+----+------------+-------------+
How can I get the main company's internal_primary_key of the person in this given scenario? How can I amend my this existing query to achieve the desired result which I have mentioned above?
Does this work for you? You have a lot of good work, it seems all you would need is add the EEC.internal_primary_key as main_company_key code to your select statement.
SELECT EEP.internal_primary_key as person_Key, EEC.internal_primary_key as company_Key, EEC.internal_primary_key as main_company_key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
WHERE IPC.person_id = 1005;
I have done this successfully after doing some research upon databases
SELECT EEP.internal_primary_key as Person_Key, EEC.internal_primary_key as Company_Key, MEEC.internal_primary_key as Main_Company_Key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
JOIN Internal.Company as MIC on MIC.id = IP.main_company_id
JOIN External.External_Company as MEEC on MIC.ref_id = MEEC.ref_id
WHERE IPC.person_id = 1005;
And now this results as I wanted:
+----+------------+-------------+------------------+
| id | person_key | company_key | main_company_key |
+----+------------+-------------+------------------+
| 1 | ABC123456 | XX4123456 | XX5456789 |
| 2 | BCD456789 | XX5456789 | XX6789456 |
| 3 | DEF789456 | XX6789456 | XX4123456 |
+----+------------+-------------+------------------+

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

Categories