Selecting columns from different tables - sql

I need to display two columns from my attendance table (MEMBER_ID & MEETING_ID) and one column from my meeting table and finally two columns from my member table which displays the names that match with MEETING_ID.
The attendance table has a composite key (MEMBER_ID*, MEETING_ID*)
The member table's primary key is MEMBER_ID
Meeting table's primary key is MEETING_ID
My attempt is not working, can someone please help?
SELECT MEMBER_ID, MEETING_ID, MEETING_NAME MEMBER_FIRSTNAME, MEMBER_LASTNAME
FROM ATTENDANCE, MEMBER, MEETING
WHERE MEETING.MEMBER_ID = MEETING.MEMBER_ID;
End result needs to be:
MEMBER_ID MEETING_ID MEETING_NAME FIRSTNAME LASTNAME
0001 MEET0004 SPORTS DAY JOHN SMITH

May be you need this.
SELECT A.MEMBER_ID, A.MEETING_ID, M2.MEETING_NAME, M1.MEMBER_FIRSTNAME, M1.MEMBER_LASTNAME
FROM ATTENDANCE A, MEMBER M1, MEETING M2
WHERE M1.MEMBER_ID = A.MEMBER_ID
AND A.MEETING_ID = M2.MEETING_ID;

SELECT
a.MEMBER_ID
,a.MEETING_ID
,mt.MEETING_NAME
,mb.MEMBER_FIRSTNAME
,mb.MEMBER_LASTNAME
FROM
ATTENDANCE a
INNER JOIN MEMBER mb
ON a.MEMBER_ID = mb.MEMBER_ID
INNER JOIN MEETING mt
ON a.MEETING_ID = mt.MEETING_ID
;
Use Explicit Join Syntax and then setup your relationships using the ON conditions and the keys between the tables. Note I also used table aliases to shorten typying.

Related

Create a additional row from join sql?

I have 2 tables: Person and House with 1-n relation.
I want to the result return as picture below:
Row always have a Person column with a null House column.
Thanks.
you can use unionall to join the result set with person table something like
select p.name,h.name as housename from person p join house h on p.id=h.personid
union all (select name,null from person)
order by name,housename

Updating fields with indirectly related data

I have four tables:
student table with id_student, firstname and lastname fields
rent table with id_student and id_book
book table with id_book, book_name, author_name
booking table with id_book, current_student
The rent table only has IDs and links between student and book tables.
How can I update the booking.current_student field with a concatenation of firstname and lastname fields from student table (like 'john doe' ) - for each id_book in booking table, update booking.curent_student from student.firstname and student.lastname.
Since the booking table has no id_student column, how can I update booking.current_student from the student table?
You need a correlated update, which uses a subquery to get the new value to use in the set clause for each row; and that subquery needs to join the rent and student tables:
update booking b
set current_student = (
select s.firstname || ' ' || s.lastname
from rent r
join student s on s.id_student = r.id_student
where r.id_book = b.id_book
);
The 'correlation' part is that the subquery filters on r.id_book = b.id_book, so it correlates with the outer booking (b) table which is being updated.
If there are any rows in booking which don't have a matching rent row then they will be set to null. And if you have multiple booking rows for the same book ID then they will all be updated to the same student name; and if you have multiple rent rows for the same book ID it will error as the subquery will return multiple rows.
It's generally not a good idea to duplicate data like this. It would require less maintenance if you used a view instead:
create view booking (id_book, current_name) as
select r.id_book, s.firstname || ' ' || s.lastname
from rent r
join student s on s.id_student = r.id_student;
Then as rows are added to or removed from the rent table, or if a student changes their name, the view will automatically reflect the changes without you having to do anything.

Condition for finding rows with same value in one colum and null in another column

I have a table with columns student ID, subject, Enrolled. I have a row for each subject against a student. I am inserting this data to a temp table for reporting. I have another column named reporting in this temp table. I need to update reporting false when enrolled is null for all the rows imported for a student.
Here is the approach:
Select from all students
Left outer join to student-course (outer join is important here)
Group by student ID, and get min course ID
Use rows with null course ID to decide what temp rows to update
In SQL this query would look like this:
SELECT StudentId, MIN(CourseId)
FROM Student s
LEFT OUTER JOIN StudentCourse sc
ON s.StudentId=sc.StudentId
GROUP BY s.StudentId
HAVING MIN(CourseId) IS NULL

Update multiple row values to same row and different columns

I was trying to update table columns from another table.
In person table, there can be multiple contact persons with same inst_id.
I have a firm table, which will have latest 2 contact details from person table.
I am expecting the firm tables as below:
If there is only one contact person, update person1 and email1. If there are 2, update both. If there is 3, discard the 3rd one.
Can someone help me on this?
This should work:
;with cte (rn, id, inst_id, person_name, email) as (
select row_number() over (partition by inst_id order by id) rn, *
from person
)
update f
set
person1 = cte1.person_name,
email1 = cte1.email,
person2 = cte2.person_name,
email2 = cte2.email
from firm f
left join cte cte1 on f.inst_id = cte1.inst_id and cte1.rn = 1
left join cte cte2 on f.inst_id = cte2.inst_id and cte2.rn = 2
The common table expression (cte) used as a source for the update numbers rows in the person table, partitioned by inst_id, and then the update joins the cte twice (for top 1 and top 2).
Sample SQL Fiddle
I think you don't have to bother yourself with this update, if you rethink your database structure. One great advantage of relational databases is, that you don't need to store the same data several times in several tables, but have one single table for one kind of data (like the person's table in your case) and then reference it (by relationships or foreign keys for example).
So what does this mean for your example? I suggest, to create a institution's table where you insert two attributes like contactperson1 and contactperson2: but dont't insert all the contact details (like email and name), just the primary key of the person and make it a foreign key.
So you got a table 'Person', that should look something like this:
ID INSTITUTION_ID NAME EMAIL
1 100 abc abc#inst.com
2 101 efg efg#xym.com
3 101 ijk ijk#fg.com
4 101 rtw rtw#rtw.com
...
And a table "Institution" like:
ID CONTACTPERSON1 CONTACTPERSON2
100 1 NULL
101 2 3
...
If you now want to change the email adress, just update the person's table. You don't need to update the firm's table.
And how do you get your desired "table" with the two contact persons' details? Just make a query:
SELECT i.id, p1.name, p1.email, p2.name, p2.email
FROM institution i LEFT OUTER JOIN person p1 ON (i.contactperson1 = p1.id)
LEFT OUTER JOIN person p2 ON (i.contactperson2 = p2.id)
If you need this query often and access it like a "table" just store it as a view.

sql select based on column in another table

Ok I have two tables.
One table is called Persons and just has columns Pname and Age. (A person's name and their age).
Another table is called Giving and has donor, receiver, and giftname. (donor and receiver have foreign key constraints referencing persons.pname).
I need to find the names of all people who donated a gift to someone with a different age.
SELECT
Giving.donor
FROM Giving
INNER JOIN Persons AS donor ON Giving.donor=donor.Pname
INNER JOIN Persons AS receiver ON Giving.receiver=receiver.Pname
WHERE donor.Age<>receiver.Age
If you mean the donor age has to be different then the receiver age, then try this:
SELECT pd.pname
FROM Persons pd
INNER JOIN giving g
ON pd.pname = g.donor
INNER JOIN persons pr
ON pr.pname = g.receiver AND pr.age != pd.age