How do I combine results from more than one table? - php

I have to tables: cities and clients
cities: cities_id, cities_name
New York
Amsterdam
Paris
Milan
etc.
Clients:
columns with personal informaition but the following two columns are importen: plac_of_residence_id and place_of_birth_id. These two columns contain the different value from cities. For example:
client_id: 1
client_name: John
client_sex: m
plac_of_residence_id: 3 (cities_id)
place_of_birth_id: 1 (cities_id)
How do I get two different values from table cities?
My sql statement is as follows:
SELECT * FROM clients C LEFT JOIN cities C ON C.plac_of_residence_id = C.cities_id AND place_of_birth_id = C.cities_id WHERE C.client_id = $client_id";
I get same citiesname for plac_of_residence_id as for place_of_birth_id instead of two different cities
How can i get as output: Paris and New York?

You should join cities two times
"SELECT C.*, a.*, b.* FROM clients C
LEFT JOIN cities a ON C.plac_of_residence_id = a.cities_id
LEFT JOIN cities b on c.place_of_birth_id = b.cities_id
WHERE C.client_id = $client_id";

Instead of using an AND in your statement you have to use an OR:
SELECT * FROM clients C LEFT JOIN cities C ON C.plac_of_residence_id = C.cities_id OR place_of_birth_id = C.cities_id WHERE C.client_id = $client_id";
This is because you want to have both: city of birth and the current residence. With your example above:
For John the join requirement (your "ON" part) should evaluate to true iff current row in cities table is no. 3 OR no. 1 because John is in a relationship to both entries.

Related

How to use group by statement on multiple fields in sql?

I have the following tables:
StudentProfile in which I have fields RollNumber, Major
StudentEnrollment in which I have fields RollNumber, CourseCode, Section, Semester
DepartmentFees in which I have fields DepartmentName, Semester, Fees
What I'm trying to do it to find the fees a student has to pay in a particular semester. The problem is the StudentEnrollment table has multiple repeated values which is making it difficult to find the exact fees.
My StudentEnrollment table is like this:
RollNO |CourseCode |Section |Semester
-----------+---------------+------------+------------
ST-0001 |BIOL 300 |A |Fall 2018
ST-0001 |BIOL 500 |A |Spring 2018
ST-0001 |BIOL 450 |B |Spring 2018
ST-0001 |BIOL 475 |A |Spring 2018
ST-0002 |CHEM 500 |A |Spring 2018
ST-0002 |CHEM 450 |B |Spring 2019
Now with repeated values of roll number and Semester how do I get the correct answer.
If I use GROUP BY (StudentEnrollment.RollNo) , the roll number does not repeat I cant get all the semesters the student has attended and if I use GROUP BY (StudentEnrollment.RollNo) I dont get all the student's rollnumbers in the semsester.
Initially I tried using
Select
a.RollNo,
b.Semester,
c.Fees
FROM StudentProfile a
LEFT JOIN StudentEnrollment b ON b.RollNo = c.RollNo
LEFT JOIN DepartmentFees C ON c.DepartmentName = a.Major //AND maybe join semester?
But it doesn't seem to work. What can I try next?
Just add the columns to the Group by clause:
Select
a.RollNo,
b.Semester,
sum(c.Fees) AS 'total'
FROM StudentProfile a
LEFT JOIN StudentEnrollment b ON b.RollNo = c.RollNo
LEFT JOIN DepartmentFees C ON c.DepartmentName = a.Major //AND maybe join semester?
GROUP BY
a.RollNo,
b.Semester
Since you have mention b.Semester, c.Fees in select statement, so to do group by RollNo and Semester, add a.RollNo and b.Semester in GROUP BY clause, I have used "JOIN" instead of "LEFT JOIN" cause use JOIN/INNER JOIN when you want to return only records having pair on both sides, and you’ll use LEFT JOIN when you need all records from the “left” table, no matter if they have pair in the “right” table or not.
Select
a.RollNo,
b.Semester,
sum(c.Fees) AS 'total'
FROM StudentProfile a
JOIN StudentEnrollment b ON b.RollNo = c.RollNo
JOIN DepartmentFees C ON c.DepartmentName = a.Major
GROUP BY
a.RollNo,
b.Semester

Inner Join problems PHP

I have three tables: bound, station and time
Bound has 2 columns: boundID and boundName
Station has 3 columns: stationID stationName boundID
Time has 4 columns: timeID departureTime tramID stationID
I am wanting to display the startStation and endStation the user enters into the form and display the time if the stations entered by the user in the textfields have the same boundID. Currently, this is all I have managed to do and can't seem to get a result. Any help would be greatly appreciated!
//display tram times from one station to another
ELSE if($startStation != '' && $endStation !='' && $DepartureTime =='' && $DepartureTime2 =='')
$query ="SELECT b.boundName, s.stationName, t.departureTime
FROM Station s, Time t, Bound b
INNER JOIN Bound b
ON S.boundID=B.boundID
WHERE s.stationName = '$startStation'AND'$endStation'";
I get this message when I try this: "Not unique table/alias: 'b'"
This is an example of the data I have:
stationID stationName boundID
5 | CitySquare | 2 ________________________________________________________________________________
boundID boundName
2 | South-Southbound ________________________________________________________________________________
timeID departureTime tramID stationID
1 | 07:18:00 | 1 | 5
The expected result is the user is able to insert a startStartion and an endStation and obtain the departure time, if the boundID are the same.
This is the result I want to output
Bound Name | Start Station | End Station | Departure Time
South-SouthBound | Stourton | CitySquare | 09:49:00
Try changing your query to something like below:
SELECT b.boundName as bond_name, s.stationName as station_name, t.departureTime as departure_time
FROM Station as s, Time as t, Bound as b
INNER JOIN Bound as b
ON s.boundID = b.boundID
WHERE s.stationName = '$startStation' AND s.stationName = '$endStation'
Change the below portion of code
INNER JOIN Bound b
with
INNER JOIN Bound c
and change the alias names of the columns too. There are too same alias assignment found in your query
It will make confusion while compile the query. Mysql cound not understand which table you are referring to.
Edit:
Try with the below code. I am not sure which table have the "boundID" field
$query ="SELECT b.boundName, s.stationName, t.departureTime
FROM Station s, Time t, Bound b
INNER JOIN Bound c
ON s.boundID=b.boundID
WHERE s.stationName = '$startStation'AND'$endStation'";
Your DB schema is a bit weird to me. From my point of view you are missing a lot of necessary data columns in your tables.
But just to get your expected result you can try this query:
http://sqlfiddle.com/#!9/e5ef0/1
SELECT
b.boundName `Bound Name`,
s.stationName `Start Station`,
e.stationName `End Station`,
t.departureTime `Departure Time`
FROM station s
INNER JOIN station e
ON e.boundId = s.boundId
AND e.stationName='$endStation'
INNER JOIN bound b
ON b.boundId=s.boundId
INNER JOIN `time` t
ON t.stationId=s.stationId
WHERE s.stationName = '$startStation'

Counts of two fields in different table with grouping not working

I have three table a, b and c in mysql. a has events, b has ticket categories for each event of a, and c has tickets each of b. So a pure relational datbase. What i'm trying to find out is the count of total ticket categories and total tickets each of the event a has.
I had tried like this:
SELECT a. * , COUNT( b.at_id ) AS totTktCat, COUNT( c.bt_id ) AS totTkts
FROM a_table a
JOIN b_table b
USING ( at_id )
JOIN c_table c
USING ( bt_id )
GROUP BY a.at_id
but no luck, the totals are wrong.
A little help from the mysql gurus will help.
I have added an sql fiddle: http://sqlfiddle.com/#!9/ec8b0/1.
I'm getting total like this
at_id at_cat at_event totTktCat totTkts
1 1 aevent1 6 6
2 2 aevent2 2 2
which is wrong.
MY expected output is
at_id at_cat at_event COUNT(bt_ticktgrp) COUNT(ct_tickets)
2 2 aevent2 2 4
For the sql fiddle: http://sqlfiddle.com/#!9/ebc9ea6
As per your given description, i have written query like this..
SELECT a.at_id,a.at_cat,a.at_event,count(*) as bt_ticktgrp,(SELECT count(*) FROM `b_table` b JOIN `c_table` c ON c.bt_id=b.bt_id where b.at_id=a.at_id) as ct_tickets FROM `a_table` a JOIN `b_table` b
ON a.at_id=b.at_id
GROUP BY a.at_cat;
Here i have grouped outer one with table a and inner one with table c by mapping it with table b.
i.e With each id of table a it joins table b and table c.
Hope this solves your query.

Unexpected results from SQL Query using GROUP_CONCAT

I'm having an issue with an sql query and I'm not sure what I am doing wrong. Anyways let me explain:
Initially this was the original query:
SELECT cl.*,
c.id,c.type,
c.firstname,
c.surname,
c.job,
c.company,
c.directorycompany_id,
dc.id, dc.name,
es.id FROM contactlist_contact cl
INNER JOIN contact c ON cl.contact_id = c.id
LEFT JOIN directorycompany dc ON dc.id = c.directorycompany_id
LEFT JOIN expertsection es ON es.id = c.expertsection_id
WHERE cl.contactlist_id = 36311
ORDER BY dc.surname
The statement fetches all of the details from the contactlist table where the id is X. The information it returns is a row for each contact in the contactlist table along with information on the company (directorycompany) they work for and various other details about the contact from the contact table. So the information looks something like this:
contactlist_id contact_id id active id type firstname surname job company directorycompany_id id name id
36311 1939 316955375 1 1939 directory Joe Bloggs Deputy Editor 786 786 Herald People 0
36311 1935 316955374 1 1935 directory Jim Bloggs Advertising Manager 786 786 Herald People 0
36311 28034 316955373 1 28034 directory Jay Bloggs News Reporter 786 786 Herald People 0
I then went and attempted to modify the above SQL as additional functionality was required but I've been seeing unwanted results. Basically I am trying to JOIN 3 other tables
directorycolumn
directorysupplement
directoryprogramme
The idea being that it would return all of the columns, supplements and programmes that the contact in the contactlist has also written. Also to point out, in some cases a contact may have written more than 1 column, supplement or programme and as a result I ideally wanted to display this in the same row as the contact as opposed to duplicating the rows so I used the GROUP_CONCAT() function.
This is the modified SQL
SELECT cl.*,
c.id,
c.type,
c.firstname,
c.surname,
c.job,
c.company,
c.directorycompany_id,
dc.id, dc.name,
es.id,
GROUP_CONCAT(dirc.name) AS gcname,
GROUP_CONCAT(dirp.name) AS gpname,
GROUP_CONCAT(dirs.name) AS gsname
FROM contactlist_contact cl
INNER JOIN contact c ON cl.contact_id = c.id
LEFT JOIN directorycompany dc ON dc.id = c.directorycompany_id
LEFT JOIN expertsection es ON es.id = c.expertsection_id
LEFT JOIN directorycolumn dirc ON dirc.directorycontact_id = c.id
LEFT JOIN directoryprogramme dirp ON dirp.directorycontact_id = c.id
LEFT JOIN directorysupplement dirs ON dirs.directorycontact_id = c.id
WHERE cl.contactlist_id = 36311
ORDER BY dc.surname
This returns:
contactlist_id contact_id id active id type firstname surname job company directorycompany_id id name id gcname gpname gsname
36311 28034 316955373 1 28034 directory Jay Bloggs News Reporter 786 786 Herald People 0 The Arts Scene,Farming \N \N
So my question is, where have the other 2 results gone and why are they not showing? And also why is the information in gcname being displayed for this contact when in fact it is related to the contact with the id 1939
if you remove GROUP_CONCAT it would display correct records, because when you use this function you should have GROUP BY clause. Currently it will consider all records as a single group.
If you look values in gcname is multiple, which is correct.
Group_concat is part of mysql aggregate functions. That means it will group all equal values together into one row, in your case all three columns have the same value, thats why you only get one as result. what result would you expect using group_concat?

mySQL select with PHP - left join

I have two tables 'all' and 'jdetails'. I have an existing select query on the all table which works. I want to add some additional data from jdetails table if available.
all table:
judge, year, ...
jane doe, 2012
john doe, 2011
jdetails table:
name, designation,...
jane doe, level 1
jane doe, level 5
john doe, special
How do I change my query below to include the 'designation's (from jdetails) for each judge (in all)?
I think a left join is the solution but I have the where clause to consider. Also, I absolutely must have the results of this query below, but with added data from jdetails table if it exists.
Additionally, there can be multiple rows (jdetails.name) of designations for each all.judge which I want listed as a single value. e.g.-- jane doe would have designation value of 'level 1 level 5'.
I would join on all.judge=jdetails.name
current query:
$rows = $my->get_row("SELECT all.judge, `year`, `totlevel_avg`, `totlevel_count`, `genrank`, `poprank`, `tlevel_avg`, `tlevel_count`, `1level_avg` as `onelevel_avg`, `1level_count` as `onelevel_count`, `2level_avg` as `twolevel_avg`, `2level_count` as `twolevel_count`, `3level_avg` as `threelevel_avg`, `3level_count` as `threelevel_count`, `4level_avg` as `fourlevel_avg`, `4level_count` as `fourlevel_count`, `PSGlevel_avg`, `PSGlevel_count`, `I1level_avg`, `I1level_count`, `I2level_avg`, `I2level_count`, `GPlevel_avg`, `GPlevel_count`, `states` from `all` where `id` ='{$term}'");
any help is greatly appreciated.
I did not include everything you had in your SELECT statement, I just summarized it with ams.*. But the following links the all table to the jdetails table and then groups the designation into one field. Then I wrap the results in an outer query that pulls the rest of the fields you need in the all table (SQL Fiddle):
SELECT ams.*, am.Desigs
FROM
(
SELECT a.judge, GROUP_CONCAT(j.designation SEPARATOR ', ') AS Desigs
FROM `all` AS a
INNER JOIN jdetails AS j ON a.judge = j.name
GROUP BY a.judge
) AS am
INNER JOIN `all` AS ams ON am.judge = ams.judge
Here is an example that can help you:
`SELECT table1.column_name(s),table2.column_name(s) FROM table1
LEFT OUTER JOIN table2 ON table1.column_name=table2.column_name
AND table1.column_name='Parameter'`
Where table 1 is all and table 2 is jdetails

Categories