I have two tables:
Table students and table of school work delivered
Students table
+--------------------------+---------------------------------+
| id | name |
+--------------------------+---------------------------------+
| 1 | ADAM |
| 2 | BRIGITTE |
| 3 | ANNE |
+--------------------------+---------------------------------+
table student works
+---------------+-------------------------+------------------+
| id_works | works | id_student |
+---------------+-------------------------+------------------+
| 1 | airplane wing | 1 |
| 2 | volcano | 2 |
| 3 | law of gravity | 1 |
| 4 | airplane wing | 3 |
| 5 | law of gravity | 1 |
+-----------------------------------------+------------------+
How do I make a SELECT for work that returns the entire list of students, indicating that the work is delivered? (IMPORTANT: list of all students)
Example
LIST FOR WORK **airplane wing**
+--------------------------+---------------------------------+
| ADAM | X |
| BRIGITTE | |
| ANNE | X |
+--------------------------+--------------------- -----------+
I have tried it with LEF JOIN and IF, but it is not the list of all the students without repeating them.
SELECT
s.name ,
w.work,
w.resid_id,
if(w.work = 'airplane wing', 'X', '') as mark
FROM students s
LEFT JOIN works w
ON s.id = w.id_student
ORDER BY s.name ASC
This will give you a list of all students
And fields id_works and works will be null for those who didn't complete the work
SELECT s.name, w.id_works, w.works
FROM students s
LEFT JOIN works w
ON (w.id_student = s.id AND w.works = 'airplane wing')
ORDER BY s.name ASC
Related
I have three tables. Two of them are separate irrelevant tables (students and subjects), the third (entries) is one which links them both with foreign keys (student_id and subject_id).
Here are all the tables with the records:
students:
+------------+------------+-----------+---------------------+---------------------+
| student_id | first_name | surname | email | reg_date |
+------------+------------+-----------+---------------------+---------------------+
| 1 | Emily | Jackson | emilym#gmail.com | 2012-10-14 11:14:13 |
| 2 | Daniel | ALexander | daniela#hotmail.com | 2014-08-19 08:08:23 |
| 3 | Sarah | Bell | sbell#gmail.com | 1998-07-04 13:16:32 |
| 4 | Alex | Harte | AHarte#hotmail.com | 1982-06-14 00:00:00 |
+------------+------------+-----------+---------------------+---------------------+
subjects:
+------------+--------------+------------+----------------+
| subject_id | subject_name | exam_board | level_of_entry |
+------------+--------------+------------+----------------+
| 1 | Art | CCEA | AS |
| 2 | Biology | CCEA | A |
| 3 | Computing | OCR | GCSE |
| 4 | French | CCEA | GCSE |
| 5 | Maths | OCR | AS |
| 6 | Chemistry | CCEA | GCSE |
| 7 | Physics | OCR | AS |
| 8 | RS | CCEA | GCSE |
+------------+--------------+------------+----------------+
entries:
+----------+---------------+---------------+------------+
| entry_id | student_id_fk | subject_id_fk | entry_date |
+----------+---------------+---------------+------------+
| 1 | 1 | 1 | 2012-10-15 |
| 2 | 1 | 4 | 2011-09-21 |
| 3 | 1 | 3 | 2015-08-10 |
| 4 | 2 | 6 | 1992-07-13 |
| 5 | 3 | 7 | 2013-02-12 |
| 6 | 3 | 8 | 2016-01-14 |
+----------+---------------+---------------+------------+
How would I go about selecting the names of all the students (students.first_name), and the name (subjects.subject_name) of whichever subject entries they have? What I mean is that all student names are returned, and all the subject names for their entries listed beside them, with NULL for those which don't have any entries. I also want it grouped by the first_name alphabetically.
I want the output to be something like:
first_name subject_name
--------------------------
Alex NULL
Daniel Chemistry
Emily French
Emily Computing
Sarah Physics
Sarah RS
though I'm not sure if that's entirely correct.
My guess is it's like this:
SELECT students.first_name, subjects.subject_name
FROM students
JOIN entries ON entries.student_id_fk = students.student_id
JOIN subjects ON entries.subject_id_fk = subjects.subject_id
GROUP BY students.first_name;
Really the only thing I'm not sure about is which join to use and where to put it, or if the tables need to be listed in a different order. I'm thinking it should be a left join but I'm not sure.
Help is much appreciated!
You should use left join since you want to return also row for student that has no subject assigned. Plus you want to sort the result, not group. So in the end should be like this:
SELECT students.first_name, subjects.subject_name
FROM students
LEFT JOIN entries ON entries.student_id_fk = students.student_id
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id
ORDER BY students.first_name;
I think this could be the query but use order by and not group by (group by is for aggregate function like count() or max() )
SELECT students.first_name, subjects.subject_name
FROM entries
LEFT JOIN students ON entries.student_id_fk = students.student_id
LEFT JOIN subjects ON entries.subject_id_fk = subjects.subject_id
ORDER BY students.first_name;
You likely want a LEFT OUTER JOIN:
select stu.first_name, sub.subject_name
from students stu
join entries e
on stu.student_id = e.student_id_fk
left outer join subjects sub
on sub.subject_id = e.subject_id_fk
order by stu.first_name;
I'm away from my PC with any SQL installed, so this is untested, but should give you what you want.
Modified my answer to replace the group by with an order by as pointed out by the others. That is the proper way to do it, unless the group is there as part of a larger query that you may have trimmed out.
Left join students table on the remaining two tables sequentially is the right choice to grab all the students first name.
To order the names order by should be used.
I have create a sql fiddle for better visualization of how to get the desired output.
Here is the link: http://sqlfiddle.com/#!9/a1c850/7
The query is
select students.student_name, subjects.subject_name
from
students
left join entries on entries.student_id=students.student_id
left join subjects on entries.subject_id=subjects.subject_id
order by students.student_name;
I have two tables.
|Table One: Adversitements-----------------------|
| ID | ADVTITLE |
|----|-------------------------------------------|
| 1 | IT Staff will be taken. |
| 2 | Human resources personnel will be taken. |
| 3 | CNC Operator will be taken. |
|Table Two: Applications-----|
| ID | ADVID | APPLICANTNAME |
|----|-------|---------------|
| 1 | 1 | John Doe |
| 2 | 1 | John Doe 2 |
| 3 | 1 | Jane Doe |
| 4 | 2 | John Doe |
| 5 | 2 | Jane Doe |
| 6 | 3 | John Doe |
I Want result:
| ADVTITLE | APPLICANTCOUNT |
|-------------------------------------------|----------------|
| IT Staff will be taken. | 3 |
| Human resources personnel will be taken. | 2 |
| CNC Operator will be taken. | 1 |
But returning a single result;
OUTPUT:
| ADVTITLE | APPLICANTCOUNT |
|-------------------------|----------------|
| IT Staff will be taken. | 6 |
MySQL Query;
SELECT adv.advtitle, COUNT(applications.id) as applicantCount
FROM advertisements as adv
LEFT JOIN applications
ON adv.id = applications.advid
All listings can be related to how the number of applicants?
SQL Fiddle Link: http://sqlfiddle.com/#!2/8644c/1/0
You missed the GROUP BY clause:
SELECT adv.advtitle, COUNT(applications.id) as applicantCount
FROM advertisements as adv
LEFT JOIN applications ON adv.id = applications.advid
GROUP BY adv.advtitle
ORDER BY applicantCount desc
Result:
ADVTITLE APPLICANTCOUNT
---------------------------------------------------------
IT Staff will be taken. 3
Human resources personnel will be taken.. 2
CNC Operator will be taken. 1
Fiddle Example
You need GROUP BY clause
SELECT adv.advtitle, COUNT(applications.id) as applicantCount
FROM advertisements as adv
LEFT JOIN applications
ON adv.id = applications.advid
GROUP BY applications.advid
SQL Fiddle
i already test it on my own try to paste it in your sqlfiddle :)
SELECT A.advtitle,COUNT(B.advid) AS ApplicantCount FROM advertisements A
LEFT JOIN applications B ON B.advid = A.id
GROUP BY A.id
I need to get emtpy fields where data is repeated
For example an customer can have two or more contact persons, so query return (just shorted qyery resul):
CUSTOMER_NAME| CONTACT_PERSON|ETC..
dell | Ighor |etc..
dell | Dima |etc..
but I'm need :
CUSTOMER_NAME| CONTACT_PERSON|etc...
dell | Ighor |etc..
NULL | Dima |etc..
SELECT
`contact`.*,
`branch_has_equipment`.*,
`branch_has_contact`.*,
`equipment`.*,
`customer_has_branch`.*,
`branch`.*,
`customer`.*,
`ip`.*
FROM `customer`
INNER JOIN `customer_has_branch`
ON `customer`.`customer_id` = `customer_has_branch`.`customer_id`
INNER JOIN `branch`
ON `customer_has_branch`.`branch_id` = `branch`.`branch_id`
INNER JOIN `branch_has_equipment`
ON `branch`.`branch_id` = `branch_has_equipment`.`branch_id`
INNER JOIN `equipment`
ON `branch_has_equipment`.`equipment_id` = `equipment`.`equipment_id`
INNER JOIN `branch_has_contact`
ON `branch`.`branch_id` = `branch_has_contact`.`branch_id`
INNER JOIN `contact`
ON `branch_has_contact`.`contact_id` = `contact`.`contact_id`
INNER JOIN `equipment_has_ip`
ON `equipment`.`equipment_id` = `equipment_has_ip`.`equipment_id`
INNER JOIN `ip`
ON `equipment_has_ip`.`equipment_id` = `ip`.`ip_id`
WHERE `customer`.`inservice` = 'Yes'
ORDER BY `customer`.`customer_name`
in additional, tables ^
Customer
customer_id
customer_name
inservice
service_type
comment
Branch
branch_id
city
address
Equipment
equipment_id
brand
model
connection_param
connection_type
serial_number
id
release
Contact
contact_id
name
surname
phone_mobile
phone_work
phone_other
position
customer_has_branch_id
customer_id
branch_id
Since I have no idea how any of those tables relate to one another, my only answer to you is to use an OUTER JOIN, which will keep NULL results.
I'm not seriously advocating this solution because really i think this sort of thing should be handled in application level code (e.g. a bit of PHP), but anyway, consider the following:
SELECT * FROM my_table;
+------+--------+--------+
| game | points | player |
+------+--------+--------+
| 1 | 5 | Adam |
| 1 | 8 | Alan |
| 1 | 7 | Brian |
| 1 | 6 | John |
| 2 | 2 | Adam |
| 2 | 3 | Alan |
| 2 | 4 | Brian |
| 2 | 6 | John |
+------+--------+--------+
SELECT IF(game= #prev,'',game)
, #prev := game
FROM my_table ORDER BY game,player;
+-------------------------+---------------+
| IF(game= #prev,'',game) | #prev := game |
+-------------------------+---------------+
| 1 | 1 |
| | 1 |
| | 1 |
| | 1 |
| 2 | 2 |
| | 2 |
| | 2 |
| | 2 |
+-------------------------+---------------+
I have a db in mysql with multiple tables and would like to join multiple tables into one view to save me from having to build 3 or 4 sql statements or even one large joining statement in php to get the same info.
Here are all my tables that I want to join
track_title
+----+------------------+
| ID | TITLE |
+----+------------------+
| 1 | Title Here |
| 2 | Another Title |
| 3 | Some Other Title |
+----+------------------+
track_artist
+----+----------------+-----------+-----------+
| ID | TRACK_TITLE_ID | ARTIST_ID | SYMBOL_ID |
+----+----------------+-----------+-----------+
| 1 | 1 | 1 | 2 |
| 2 | 1 | 2 | 1 |
| 3 | 3 | 1 | 1 |
+----+----------------+-----------+-----------+
artist
+----+-------------+
| ID | ARTIST |
+----+-------------+
| 1 | Linkin Park |
| 2 | Metallica |
+----+-------------+
symbol
+----+--------+
| ID | SYMBOL |
+----+--------+
| 1 | |
| 2 | Feat. |
+----+--------+
tracklisting
+----+----------+----------+---------------+---------+
| ID | TRACK NO | TITLE_ID | VERSION | DISC NO |
+----+----------+----------+---------------+---------+
| 1 | 1 | 1 | | 1 |
| 2 | 1 | 2 | Album Version | 1 |
| 3 | 1 | 3 | Live Version | 1 |
+----+----------+----------+---------------+---------+
This is the final view I'm looking for
+----+----------+------------------+---------------+-----------------------------+---------+
| ID | TRACK NO | TITLE | VERSION | ARTIST | DISC NO |
+----+----------+------------------+---------------+-----------------------------+---------+
| 1 | 1 | Title Here | | Linkin Park Feat. Metallica | 1 |
| 2 | 1 | Another Title | Album Version | | 1 |
| 3 | 1 | Some Other Title | Live Version | Linkin Park | 1 |
+----+----------+------------------+---------------+-----------------------------+---------+
I have been bashing my head for the past 3 days with left, right, join and full join and just can't seem to get this to work.
Basically what I want to happen is the track_artist table will get the artist and symbol form the respective tables and concat them together into one column. Then join title and the concat column to have this view.
full_artist_view
+----------+------------------+-----------------------------+
| TITLE_ID | TITLE | FULL_ARTIST |
+----------+------------------+-----------------------------+
| 1 | Title Here | Linkin Park Feat. Metallica |
| 2 | Another Title | |
| 3 | Some Other Title | Linkin Park |
+----------+------------------+-----------------------------+
I have gotten this far but when I try join this to the tracklisting table I seem to crash my server which is getting very painful. No mysql error so I'm guessing I'm using the wrong join or this is just not possible.(though I can't see how this is not possible)
The tracklisting table is continuesly growing every week by 1000 records comfortable and is sitting at +- 75000 records.
To me this is the sql that should work, but doesn't
FROM full_artist_view LEFT JOIN tracklisting ON
full_artist_view.TITLE_ID = tracklisting.TITLE_ID
While I have only your small data sample and I can't see what your full_artist_view code looks like. You should be able to get the result using the following:
select tt.id,
tl.`track no`,
tt.title,
coalesce(tl.version, '') version,
group_concat(concat(coalesce(a.artist, ''), ' ', coalesce(s.symbol, '')) order by a.artist SEPARATOR ' ') artist,
tl.`disc no`
from track_title tt
inner join tracklisting tl
on tt.id = tl.TITLE_ID
left join track_artist ta
on tt.id = ta.TRACK_TITLE_ID
left join artist a
on ta.artist_id = a.id
left join symbol s
on ta.symbol_id = s.id
group by tt.id, tl.`track no`, tt.title, tl.version, tl.`disc no`
See SQL Fiddle with Demo. This returns:
| ID | TRACK NO | TITLE | VERSION | ARTIST | DISC NO |
---------------------------------------------------------------------------------------------
| 1 | 1 | Title Here | | Linkin Park Feat. Metallica | 1 |
| 2 | 1 | Another Title | Album Version | | 1 |
| 3 | 1 | Some Other Title | Live Version | Linkin Park | 1 |
Quick play, and I think (but not certain) it is something like this that you need:-
SELECT a.Id, a.Track_No, b.Title, a.Version, GROUP_CONCAT(CONCAT(d.Artists, e.Symbol)), a.Disc_No
FROM tracklisting a
INNER JOIN track_title b ON a.Title_id = b.Id
LEFT OUTER JOIN track_artist c ON b.Id = c.Track_Title_Id
LEFT OUTER JOIN artist d ON c.Artist_Id = d.Id
LEFT OUTER JOIN symbol e ON d.SymbolId = e.Id
GROUP BY a.Id, a.Track_No, b.Title, a.Version, a.Disc_No
But I might have missed something so let me know!
I have multiple MySQL tables containing varying numbers of columns. After joining three of the tables, I have a resulting table that's structured as follows:
+------------+------------+-----------+-------+------+
| student_id | first_name | last_name | class | rank |
+------------+------------+-----------+-------+------+
| 1 | John | Doe | 2012 | 1 |
+------------+------------+-----------+-------+------+
| 2 | Suzy | Public | 2013 | 12 |
+------------+------------+-----------+-------+------+
| 3 | Mike | Smith | 2014 | 50 |
+------------+------------+-----------+-------+------+
I also have two additional tables that aren't involved in the initial join:
interest
+-------------+------------+-----------------------+----------------+
| interest_id | student_id | employer_interest | interest_level |
+-------------+------------+-----------------------+----------------+
| 1 | 1 | Wayne Enterprises | High |
+-------------+------------+-----------------------+----------------+
| 2 | 1 | Gotham National Bank | Medium |
+-------------+------------+-----------------------+----------------+
| 3 | 2 | Wayne Enterprises | Low |
+-------------+------------+-----------------------+----------------+
| 4 | 3 | Gotham National Bank | High |
+-------------+------------+-----------------------+----------------+
offers
+----------+------------+-----------------------+
| offer_id | student_id | employer_offer |
+----------+------------+-----------------------+
| 1 | 1 | Wayne Enterprises |
+----------+------------+-----------------------+
| 2 | 1 | Gotham National Bank |
+----------+------------+-----------------------+
| 3 | 2 | Wayne Enterprises |
+----------+------------+-----------------------+
The interest and offers table won't necessarily contain a record for every student_id but at the same time contain multiple records that reference a single student_id.
For each of the latter two tables, I'd like to:
Select all rows where the employer_interest or employer_offer value is equal to $var (a variable I've set in PHP)
Join these rows to the original table
For example, if $var is set to Wayne Enterprises, I'd like the resulting table to be:
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| student_id | first_name | last_name | class | rank | employer_interest | interest_level | employer_offer |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 1 | John | Doe | 2012 | 1 | Wayne Enterprises | High | Wayne Enterprises |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 2 | Suzy | Public | 2013 | 12 | Wayne Enterprises | Low | Wayne Enterprises |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 3 | Mike | Smith | 2014 | 50 | NULL | NULL | NULL |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
Is what I'm trying to do possible using just a MySQL query? If so, how do I do it?
it sounds like you just need a LEFT JOIN to the other tables since it appears you want to see all students from the first set regardless of any job offer/interest.
If so... ensure both the "Interest" and "Offers" tables have an index where the student ID is either a single element index, or first in that of a compound index.
select STRAIGHT_JOIN
ORS.Student_ID,
ORS.First_Name,
ORS.Last_Name,
ORS.Class,
ORS.Rank,
JI.Employer_Interest,
JI.Interest,
OFR.Employer_Offer
from
OriginalResultSet ORS
LEFT JOIN Interest JI
ON ORS.Student_ID = JI.Student_ID
AND JI.Employer_Interest = YourPHPVariable
LEFT JOIN Offers OFR
on JI.Student_ID = OFR.Student_ID
AND JI.Employer_Interest = OFR.Employer_Offer
To prevent "NULL" results in the employer interest, interest and offer, you can wrap them in a Coalesce() call such as (for all three columns on left join)
COALESCE( JI.Employer_Interest, " " ) Employer_Interest
Your query should be something like this:
select
s.student_id, s.first_name, s.last_name, s.class, s.rank,
i.employer_interest, i.interest_level,
o.employer_offer
from students s
left join interest i
on i.student_id = s.student_id
and i.employer_interest = 'Wayne Enterprises'
left join offers o
on o.student_id = s.student_id
and o.employer_offer = 'Wayne Enterprises'