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
Related
I have 4 tables and I want to select the information from these tables using one query.
I have a table name
tbl_marketing
db_maid db_client db_status db_process
4 test done ddd
tbl_meeting
db_meetingid db_meetingsubject db_mid
1 test 4
tbl_phonecall
db_phid db_subject db_mid
1 ggg 4
2 fff 4
tbl_email
db_eid db_email db_mid
1 xxx 4
Remark: this is an example of my 4 tables. My tables contain more columns
db_mid is the id of tbl_marketing
I want to select all information without repetition
I use this query:
select
marketing.*,
meeting.db_meetingid,meeting.db_meetingsubject,meeting.db_sd,meeting.db_dd,meeting.db_duration as meetingDuration,meeting.db_place,meeting.db_mom,meeting.db_momattache,meeting.db_status as meetingStatus,meeting.db_nextmeeting,meeting.db_lastmeeting,meeting.db_attendees,meeting.db_note as meetingNote,meeting.db_mid,
phonecall.db_phid,phonecall.db_subject as phoneSubject,phonecall.db_desc as phoneDesc,phonecall.db_nextdate,phonecall.db_doc,phonecall.db_duration as phoneDuration,phonecall.db_phstatus,phonecall.db_pnote,phonecall.db_client as phoneClient,phonecall.db_crf,phonecall.db_callto,phonecall.db_phone as phonecallPhone,phonecall.db_logs as phoneLogs,phonecall.db_mid,phonecall.db_dateedit as phoneEdit,phonecall.db_phdate,
email.db_eid,email.db_edate,email.db_esubject,email.db_edesc,email.db_erf,email.db_emailto,email.db_email as eEmail,email.db_dos,email.db_dor,email.db_estatus,email.db_logs as eLogs,email.db_note as eNote,
location.db_location as location,
location.db_lid,
company.db_company as com,
company.db_coid,
subcompany.db_subid,
subcompany.db_subcompany as sub,
user.db_uid,
concat(user.db_fname,' ' ,user.db_lname) as tr,
subj.db_subjid,
subj.db_subject as s
from tbl_marketing as marketing
left join tbl_location as location
on
marketing.db_location=location.db_lid
left join tbl_meeting as meeting
on
marketing.db_maid=meeting.db_mid
left join tbl_phonecall as phonecall
on
marketing.db_maid=phonecall.db_mid
left join tbl_email as email
on
marketing.db_maid=email.db_mid
left join tbl_company as company
on
marketing.db_companyname=company.db_coid
left join tbl_subcompany as subcompany
on
marketing.db_subcompany=subcompany.db_subid
left join tbl_user as user
on
marketing.db_transfered=user.db_uid
left join tbl_subject as subj
on
phonecall.db_subject=subj.db_subjid
where
marketing.db_maid='$read'
and
meeting.db_mid='$read'
and
email.db_mid='$read'
and
phonecall.db_mid='$read'
I use this query to select the information but when I have 2 rows, the same db_mid as tbl_phonecall in the example, then the information is duplicated as follows:
table marketing
1 test 4
1 test 4
table phonecall
1 ggg 4
2 fff 4
table meeting
1 test 4
1 test 4
table email
1 xxx 4
1 xxx 4
As visible above all tables have a duplicate value without phonecall because he have 2 rows I want to show all the information without this repetition
if I use group by mid I don't receive the second information in tbl_phonecall
$rows=array();
while($rows=mysqli_fetch_array($sql)){
$row[]=$rows;}
<table>
foreach($rows as row){
<tr>
<td><?php echo $row['phID'];?></td>
</tr>
}
</table>
output
# subject mid
1 test 4
2 ggg 4
not like this
1,2 test,ggg 4,4
If you only have duplicates in the phonecall table, the following should work. If other left joined tables can have duplicates, just add GROUP_CONCAT as needed.
select
marketing.*,
meeting.db_meetingid,
meeting.db_meetingsubject,
meeting.db_sd,
meeting.db_dd,
meeting.db_duration as meetingDuration,
meeting.db_place,
meeting.db_mom,
meeting.db_momattache,
meeting.db_status as meetingStatus,
meeting.db_nextmeeting,
meeting.db_lastmeeting,
meeting.db_attendees,
meeting.db_note as meetingNote,
meeting.db_mid,
GROUP_CONCAT(phonecall.db_phid) as phID,
GROUP_CONCAT(phonecall.db_subject) as phoneSubject,
GROUP_CONCAT(phonecall.db_desc) as phoneDesc,
GROUP_CONCAT(phonecall.db_nextdate) as phNextDate,
GROUP_CONCAT(phonecall.db_doc) as phDoc,
GROUP_CONCAT(phonecall.db_duration) as phoneDuration,
GROUP_CONCAT(phonecall.db_phstatus) as phStatus,
GROUP_CONCAT(phonecall.db_pnote) as phPNote,
GROUP_CONCAT(phonecall.db_client) as phoneClient,
GROUP_CONCAT(phonecall.db_crf) as phCrf,
GROUP_CONCAT(phonecall.db_callto) as phCallTo,
GROUP_CONCAT(phonecall.db_phone) as phonecallPhone,
GROUP_CONCAT(phonecall.db_logs) as phoneLogs,
GROUP_CONCAT(phonecall.db_mid) as phMid,
GROUP_CONCAT(phonecall.db_dateedit) as phoneEdit,
GROUP_CONCAT(phonecall.db_phdate) as phdate,
email.db_eid,
email.db_edate,
email.db_esubject,
email.db_edesc,
email.db_erf,
email.db_emailto,
email.db_email as eEmail,
email.db_dos,
email.db_dor,
email.db_estatus,
email.db_logs as eLogs,
email.db_note as eNote,
location.db_location as location,
location.db_lid,
company.db_company as com,
company.db_coid,
subcompany.db_subid,
subcompany.db_subcompany as sub,
user.db_uid,
concat(user.db_fname,' ' ,user.db_lname) as tr,
subj.db_subjid,
subj.db_subject as s
from tbl_marketing as marketing
left join tbl_location as location
on marketing.db_location=location.db_lid
left join tbl_meeting as meeting
on marketing.db_maid=meeting.db_mid
left join tbl_phonecall as phonecall
on marketing.db_maid=phonecall.db_mid
left join tbl_email as email
on marketing.db_maid=email.db_mid
left join tbl_company as company
on marketing.db_companyname=company.db_coid
left join tbl_subcompany as subcompany
on marketing.db_subcompany=subcompany.db_subid
left join tbl_user as user
on marketing.db_transfered=user.db_uid
left join tbl_subject as subj
on phonecall.db_subject=subj.db_subjid
where marketing.db_maid='$read' and
meeting.db_mid='$read' and
email.db_mid='$read' and
phonecall.db_mid='$read'
GROUP BY meeting.db_mid
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?
I have 3 tables office, Computer and Maintain. Office just list of offices, computers belongs to office as well as has many Maintains.
I want to LEFT join all tables with just the latest entry from Maintain table. The code below works but it just group the oldest entry in the maintain.
SELECT `Computer`.`id`, `Computer`.`control`, `Computer`.`operator`, `Computer`.`datePurchased`, `Computer`.`type`, `Computer`.`property`, `Computer`.`printer`, `Computer`.`scanner`, `Computer`.`osx`, `Computer`.`applications`, `Computer`.`licence`, `Computer`.`isStandAlone`, `Computer`.`isInternet`, `Computer`.`isNetwork`, `Computer`.`generalStatus`, `Computer`.`ip_address`, `Computer`.`mac_address`, `Computer`.`user_id`, `Computer`.`office_id`, `Computer`.`created`, `Computer`.`modified`, `Computer`.`deleted`, `Office`.`id`, `Office`.`description`, `Office`.`main_office`, `Maintain`.`id`, `Maintain`.`dateEncoded`, `Maintain`.`findings`, `Maintain`.`checkedBy`, `Maintain`.`remarks`, `Maintain`.`computer_id`, `Maintain`.`created`, `Maintain`.`modified`, `Maintain`.`user_id` FROM `computers`.`computer` AS `Computer`
LEFT JOIN `computers`.`office` AS `Office`
ON (`Office`.`id` = `Computer`.`office_id`)
LEFT JOIN `computers`.`maintain` AS `Maintain`
ON (`Computer`.`id` = `Maintain`.`computer_id`)
LEFT JOIN (SELECT MAX(dateEncoded) maxDate, findings FROM maintain GROUP BY computer_id) AS `P2`
ON (`Maintain`.`dateEncoded` = `p2`.`maxDate`)
WHERE `Office`.`main_office` LIKE '%CVPH MON%'
GROUP BY `Computer`.`id`
ORDER BY `Office`.`description` ASC
SAMPLE
OFFICE
1 AAAA
2 BBBB
COMPUTER
id name office_id
1 CP1 1
2 CP2 1
3 CP3 2
Maintain
id description date computer_id
1 Fix 06/20/2014 1
2 Fix 06/11/2014 1
3 Fix 06/12/2014 2
4 Fix 06/15/2014 2
Result if query on computer=CP1 should be
Office Computer_name Maintain_desc Date
AAA CP1 Fix 06/20/2014 <- Latest entry in maintain
You can do so
SELECT `c`.`id`,
`c`.`name`,
`c`.`office_id` ,
`o`.`name` office_name,
`m`.`date`,
`m`.`description`
FROM `computer` AS c
LEFT JOIN `office` AS `o`
ON (`o`.`id` = `c`.`office_id`)
LEFT JOIN `maintain` AS m
ON (`c`.`id` = `m`.`computer_id`)
INNER JOIN
(SELECT computer_id,MAX(`date`) maxdate
FROM maintain
GROUP BY computer_id ) t
ON(m.`date`=t.maxdate AND m.computer_id= t.computer_id)
WHERE `c`.`name` ='CP1' ... more conditions
Demo
I have a table ('names') which includes data related with other data in other tables relying on ids. For example:
*Names table
id | name | predecessor | successor | house | birthplace
-----------------------------------------------------------------
10 Bayezid II 9 11 4 NULL
11 Selim I 10 12 4 5
12 Suleiman 11 13 4 61
*Houses table
id | house
--------------
4 House of Osman
*Places table
id | place
--------------
5 Amasya
61 Trabzon
What I'm trying to accomplish is to construct a query which results in returning whole information depending on the id, like:
{"result":[{
"id":"11",
"name":"Selim I",
"predecessor": "Bayezid II",
"successor": "Suleiman",
"house":"House of Osman",
"birthplace":"Amasya"
}]}
So, the name of the house and the birthplace are brought from other tables ('houses', 'places') whereas the predecessor and the successor are from the same table. I need help constructing this query. Thank you.
Just self-join a couple times, once to get the predecessor's row (aliased n0 below), and once more for the successor's (n2):
SELECT n1.id, n1.name, n0.name AS predecessor, n2.name AS successor
FROM names n1
LEFT JOIN names n0 ON n1.predecessor = n0.id
LEFT JOIN names n2 ON n1.successor = n2.id
SQL Fiddle demo
Joining to get the house and birthplace are left as an exercise for the reader.
Try this:
select n.id,
n.name,
n1.name as predecessor,
n2.name as successor,
h.house,
p.place
from names n
inner join names n1 on n.id = n1.predecessor
inner join names n2 on n.id = n2.successor
left join Houses h on n.house = h.id
left join Place p on n.birthplace = p.id
where n.id = 11
I need to combine 2 tables and display a table.
I already did it in PHP, but I want to do it in SQL itself.
Table 1:venki
code subject
10 english
11 tamil
12 history
Table 2:venki2
num opt1 opt2 opt3 allot
f41 12 11 10 12
I need to display a table with columns of num.venki2, opt1, opt2, opt3, allot (5 columns). For the last 4 column values must be taken from table 1, for example: f41 , history. tamil, english, history.
SELECT t2.num
,J1.[Subject] AS Opt1
,J2.[Subject] AS Opt2
,J3.[Subject] AS Opt3
,J4.[Subject] AS allot
FROM venki2 t2 LEFT JOIN venki J1
ON t2.opt1 = J1.Code
LEFT JOIN venki J2
ON t2.opt2 = J2.Code
LEFT JOIN venki J3
ON t2.opt3 = J3.Code
LEFT JOIN venki J4
ON t2.allot = J4.Code
Use Square brackets around Subject as it is a key word in sql server.
Working SQL FIDDLE
select venky2.num, TBLOPT1.[subject],
TBLOPT2.[subject], TBLOP3.[subject],
TBLALLOT.[subject]
from venky2, venky as TBLOPT1, venky as TBLOPT2, venky as TBLOP3, venky as TBLALLOT
left join TBLOPT1 on venky2.opt1=TBLOPT1.code
left join TBLOPT2 on venky.opt2=TBLOPT2.code
left join TBLOP3 on venky2.opt3=TBLOP3.code
left join TBLALLOT on venky2.allot=TBLALLOT.code