Why are double nested NOT EXISTS statements unavoidable in SQL

天涯浪子 提交于 2019-12-11 01:06:27

问题


This is more out of curiosity/scientific interest, than based on a real problem and I once asked my databases lecturer about this, but he could not answer/understand my question. So I decided to come over here.

A programming language is supposed to be a tool and tools are made to make working easier, right? So why is it that you can find all entries in a one table by simply doing SELECT * FROM foo WHERE bar=42;. But as soon as there are multiple tables involved, there is no easy/intuitive way to say "find all tuple meeting this criteria"?

The given example in the script is something like this (this is translated from German, so the naming might be a bit confusing):

For Table of the folowing format:

  • component(CNR,Cname,Color,Weight,City)
  • project(PNR,Pname,City)
  • scp(SNR,CNR,PNR,Quantity)

Primary keys in bold. The example is about components which are shipped to different projects in different cities.

The task is to write a query to find all components that are/were shipped to all projects in one specific city.

The given solution looks like this:

SELECT CNR
FROM components
WHERE NOT EXISTS ( SELECT 1
                  FROM project
                  WHERE project.city = 'Foobar Town'
                  AND NOT EXISTS ( SELECT 1
                                 FROM scp
                                 WHERE scp.PNR = projekt.PNR
                                 AND scp.CNR = components.CNR ));

I mean yes it is correct, makes sense and even works. But it is not intuitive and certainly does not make life easier! So where is the reason for this I wonder? Since we were told that it is crucial for the exams, that we are able to write such queries I there is no way around learning it.

I haven't been able to find a simpler solution to this yet. Neither by googling nor trying by myself. There must be a better reason to this than "everybody is too lazy to fix this". Any one any ideas?

The example and all the material given to the students in our course is based on SQL92.

Thank you for your answers


回答1:


Your question is: "Find all components that are/were shipped to all projects in one specific city." You are rephrasing this as "Find all components where there is no project in a given city that doesn't have the component."

I'd be more inclined to answer this directly:

select scp.component
from scp join
     projects p
     on scp.pnr = p.pnr
where p.city = 'Foobar Town'
group scp.component
having count(distinct scp.pnr) = (select count(distinct pnr)
                                  from projects
                                  where city = 'Foobar Town'
                                 );

This counts the number of distinct projects in the city and compares them to the number of projects in the city (the distinct id probably not necessary in the subquery.

First, I'm not sure if this is simpler. Second, I'm the first to admit that the NOT EXISTS method may be more efficient, although the nesting of NOT EXISTS in subqueries may be detrimental to performance. I do, however, think that this is easier to follow.



来源:https://stackoverflow.com/questions/27722404/why-are-double-nested-not-exists-statements-unavoidable-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!