SQL "Where not exists" (nested loops)

  • Thread starter Thread starter whitehorsey
  • Start date Start date
  • Tags Tags
    Loops Sql
Click For Summary

Discussion Overview

The discussion revolves around understanding the SQL query structure, specifically focusing on the use of nested loops and the "NOT EXISTS" clause to find individuals who like all hobbies listed in a database. Participants explore the logic behind the query and its components, including subqueries and derived tables.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested

Main Points Raised

  • Some participants express confusion about how nested loops operate in SQL and the overall logic of the provided query.
  • One participant suggests starting the evaluation from the innermost subquery and working outward, comparing it to mathematical expressions.
  • Another participant emphasizes the importance of understanding that "NOT EXISTS" returns false when the subquery has results, while "EXISTS" returns true under the same condition.
  • Concerns are raised about naming conventions in SQL, with suggestions to avoid using the same name for columns and tables, and to clarify the relationship between the Hobby and Person tables.
  • One participant advises against thinking in terms of "NOT IN" and instead encourages viewing the logic as an attribute-based approach, explaining the role of each "NOT EXISTS" in the context of the query.

Areas of Agreement / Disagreement

Participants generally agree on the confusion surrounding the query structure and the use of "NOT EXISTS," but there are differing opinions on naming conventions and the expected relationships between the tables. The discussion remains unresolved regarding the best practices for structuring such queries.

Contextual Notes

There are limitations in the discussion regarding assumptions about table structures and relationships, as well as the clarity of the intended logic behind the query. Participants have not reached a consensus on the optimal naming conventions or the exact nature of the relationships between the tables involved.

whitehorsey
Messages
188
Reaction score
0
I'm having a hard time understanding how nested loops work in SQL.

Find all the people who likes all the hobbies.

Code:
select p.name 
from person p 
where not exists (select *
			      from (select distinct h.hobby
					    from hobby h) as h1
	              where not exists (select *
									from hobby as h2
									where h2.hobby = h1.hobby and h2.id = p.id))

My logic:
In the first not exists it gets all the columns in hobby. The second not exists it gets all the hobbies but this time checks to see if the hobby are equal and the ids. But how does this all come together?
 
Technology news on Phys.org
whitehorsey said:
I'm having a hard time understanding how nested loops work in SQL.

Find all the people who likes all the hobbies.

Code:
select p.name 
from person p 
where not exists (select *
			      from (select distinct h.hobby
					    from hobby h) as h1
	              where not exists (select *
									from hobby as h2
									where h2.hobby = h1.hobby and h2.id = p.id))

My logic:
In the first not exists it gets all the columns in hobby. The second not exists it gets all the hobbies but this time checks to see if the hobby are equal and the ids. But how does this all come together?

You want to start your evaluation with the inner most subquery and work your way back. Kind of like mathematics where you have a situation like a(b(c*d)).Start with:
(select * from (select distinct h.hobby from hobby h) as h1
where not exists (select * from hobby as h2 where h2.hobby = h1.hobby and h2.id = p.id))

So here you have a derived table before the where not exists and a sub query afterwards.

Look at the sub query first.

exists is true when a subquery returns results. Not exists means its false when it returns results.

Now it's just a matter of walking this backwards till we evaluate the outermost statement.
 
Last edited:
An unsolicited piece of advice: write Sql keywords in caps, variable and table names in lower case. Like this:

SELECT p.name
FROM person p
WHERE NOT EXISTS (...
 
whitehorsey said:
I'm having a hard time understanding how nested loops work in SQL.

Find all the people who likes all the hobbies.

Code:
select p.name 
from person p 
where not exists (
    select * from (
         select distinct h.hobby from hobby h) as h1
	 where not exists (
               select * from hobby as h2 
               where h2.hobby = h1.hobby and h2.id = p.id))

My logic:
In the first not exists it gets all the columns in hobby. The second not exists it gets all the hobbies but this time checks to see if the hobby are equal and the ids. But how does this all come together?

Just to be clear. Are you trying to list the names of people who like every type of hobby in the Hobby table?

What are the column names in those two tables? Your Hobby table has a column named hobby. It's not a good idea to name columns in your table with the same exact name as your table. You should either rename the table HOBBIES or change the name of the column to HOBBY_NAME.

Also, I wouldn't expect the Hobby table IDs have anything to do with the Person table IDs (i.e., h2.id = p.id). Based on the way that you're trying to construct the query, I would expect the Hobby table to have a column named something like PERSON_ID (i.e., h2.person_id = p.id).
 
whitehorsey said:
I'm having a hard time understanding how nested loops work in SQL.

Find all the people who likes all the hobbies.

Code:
select p.name
from person p
where not exists (select *
                  from (select distinct h.hobby
                        from hobby h) as h1
                  where not exists (select *
                                    from hobby as h2
                                    where h2.hobby = h1.hobby and h2.id = p.id))

My logic:
In the first not exists it gets all the columns in hobby. The second not exists it gets all the hobbies but this time checks to see if the hobby are equal and the ids. But how does this all come together?

DO NOT THINK in the normal "NOT IN" way, I consider it as an "attribute" way

Think of it in this way.

1. For each person you try to find, his/her hobbies are listed in the innermost connected table, and this person needs to have another attribute which is he/she don't have all the hobbies in the hobbies table. That is the first NOT EXIST.

select *
from (select distinct h.hobby
from hobby h) as h1
where not exists (select *
from hobby as h2
where h2.hobby = h1.hobby and h2.id = p.id)
means that pick hobbies out from the hobby table that does not belong to this person.

2. But we don't want this person.

3. So we used second NOT exist.

So, in short, Start with the innermost combined table in your mind. and You don't want those person whose hobbies (think as his/her attribute) does not match all the hobbies from the derived hobbies table..
 
Last edited:
harborsparrow said:
An unsolicited piece of advice: write Sql keywords in caps, variable and table names in lower case. Like this:

SELECT p.name
FROM person p
WHERE NOT EXISTS (...
Thank you!

My previous company had the complete opposite standard:
select P.NAME
from PERSON P
where not exists(...
That irked me so badly.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 35 ·
2
Replies
35
Views
3K
  • · Replies 3 ·
Replies
3
Views
4K
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 5 ·
Replies
5
Views
1K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K