patternsqlMinor
Database of students in a social network
Viewed 0 times
databasesocialnetworkstudents
Problem
This is sourced from the Stanford Coursera self study DB class SQL quizzes.
Students at your hometown high school have decided to organize their
social network using databases. So far, they have collected
information about sixteen students in four grades, 9-12. Here's the
schema:
English: There is a high school student
with unique ID and a given first name in a certain grade.
English: The student with ID1 is friends with the
student with ID2. Friendship is mutual, so if
Friend table, so is
English: The student with ID1 likes the student with
ID2. Liking someone is not necessarily mutual, so if
the Likes table, there is no guarantee that
present.
DB is here
Prompt: Find the number of students who are either friends with
Cassandra or are friends of friends of Cassandra. Do not count
Cassandra, even though technically she is a friend of a friend.
My answer (which works) is below, but I am wondering if there is a more succinct way of accomplishing the same results. Any feedback would be appreciated.
Students at your hometown high school have decided to organize their
social network using databases. So far, they have collected
information about sixteen students in four grades, 9-12. Here's the
schema:
Highschooler (ID, name, grade)English: There is a high school student
with unique ID and a given first name in a certain grade.
Friend (ID1, ID2)English: The student with ID1 is friends with the
student with ID2. Friendship is mutual, so if
(123, 456) is in theFriend table, so is
(456, 123).Likes (ID1, ID2)English: The student with ID1 likes the student with
ID2. Liking someone is not necessarily mutual, so if
(123, 456) is inthe Likes table, there is no guarantee that
(456, 123) is alsopresent.
DB is here
Prompt: Find the number of students who are either friends with
Cassandra or are friends of friends of Cassandra. Do not count
Cassandra, even though technically she is a friend of a friend.
My answer (which works) is below, but I am wondering if there is a more succinct way of accomplishing the same results. Any feedback would be appreciated.
select count(*)-1 from
(
select id2
from friend f, highschooler a
where a.name='Cassandra'
and a.id=f.id1
union
select id2
from friend f, highschooler a
where a.id=f.id1
and f.id1 in ( select id2
from friend f, highschooler a
where a.name='Cassandra'
and a.id=f.id1 ) )Solution
Style
Formulation
Here's how I would write it:
- Indentation would make your query more readable.
- Table names in MySQL may be case sensitive, depending on the underlying filesystem. Therefore, it is safest to write the query using identifiers with the same case as stated in the problem.
- SQL keywords are conventionally written in ALL CAPS, though some programmers object to that convention.
- Single-letter names for table aliases are cryptic. While I can somewhat understand
friend f, I have a harder time acceptinghighschooler a.
Formulation
UNION, short forUNION DISTINCT, automatically deduplicates the result set. If possible, preferUNION ALLfor efficiency. However, in this case, you do need deduplication for the correct answer.
- The two halves of the union seem repetitive.
- Subtracting one from the final count is weird and risky. I suggesting filtering out Cassandra herself from the result set.
Here's how I would write it:
SELECT count(Friend.ID1)
FROM Highschooler AS Cassandra, Friend
WHERE
Cassandra.name = 'Cassandra'
AND (
Friend.ID2 = Cassandra.ID
OR Friend.ID2 IN (
SELECT Friend.ID1
FROM Friend
WHERE Friend.ID2 = Cassandra.ID
)
)
AND Friend.ID1 <> Cassandra.ID;Code Snippets
SELECT count(Friend.ID1)
FROM Highschooler AS Cassandra, Friend
WHERE
Cassandra.name = 'Cassandra'
AND (
Friend.ID2 = Cassandra.ID
OR Friend.ID2 IN (
SELECT Friend.ID1
FROM Friend
WHERE Friend.ID2 = Cassandra.ID
)
)
AND Friend.ID1 <> Cassandra.ID;Context
StackExchange Code Review Q#62924, answer score: 3
Revisions (0)
No revisions yet.