Using EXCEPT with NOT EXISTS












0














enter image description here



SELECT DISTINCT cname
FROM account AS cust_account
WHERE NOT EXISTS ( SELECT type
FROM account
EXCEPT
SELECT type
FROM account
WHERE account.cname = cust_account.cname )


Can someone please explain step-by-step how the query produces the result required by the question? I am just learning about NOT EXISTS and am not sure what values it takes from the parenthesis and where the WHERE clause belongs with.



This is sample table account
enter image description here










share|improve this question









New contributor




Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    0














    enter image description here



    SELECT DISTINCT cname
    FROM account AS cust_account
    WHERE NOT EXISTS ( SELECT type
    FROM account
    EXCEPT
    SELECT type
    FROM account
    WHERE account.cname = cust_account.cname )


    Can someone please explain step-by-step how the query produces the result required by the question? I am just learning about NOT EXISTS and am not sure what values it takes from the parenthesis and where the WHERE clause belongs with.



    This is sample table account
    enter image description here










    share|improve this question









    New contributor




    Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      0












      0








      0







      enter image description here



      SELECT DISTINCT cname
      FROM account AS cust_account
      WHERE NOT EXISTS ( SELECT type
      FROM account
      EXCEPT
      SELECT type
      FROM account
      WHERE account.cname = cust_account.cname )


      Can someone please explain step-by-step how the query produces the result required by the question? I am just learning about NOT EXISTS and am not sure what values it takes from the parenthesis and where the WHERE clause belongs with.



      This is sample table account
      enter image description here










      share|improve this question









      New contributor




      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      enter image description here



      SELECT DISTINCT cname
      FROM account AS cust_account
      WHERE NOT EXISTS ( SELECT type
      FROM account
      EXCEPT
      SELECT type
      FROM account
      WHERE account.cname = cust_account.cname )


      Can someone please explain step-by-step how the query produces the result required by the question? I am just learning about NOT EXISTS and am not sure what values it takes from the parenthesis and where the WHERE clause belongs with.



      This is sample table account
      enter image description here







      query relational-division






      share|improve this question









      New contributor




      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 1 hour ago









      Paul White

      49.1k14260414




      49.1k14260414






      New contributor




      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 9 hours ago









      BhargBharg

      11




      11




      New contributor




      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Bharg is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          2 Answers
          2






          active

          oldest

          votes


















          1














          There are three separate parts to the query. I'll label them so I can reference each more clearly:



          SELECT DISTINCT cname             -- Part A
          FROM account AS cust_account
          WHERE NOT EXISTS ( SELECT type -- Part B
          FROM account
          EXCEPT
          SELECT type -- Part C
          FROM account
          WHERE account.cname = cust_account.cname )


          First the inner query. Part C lists all type values for account rows owned by the customer currently being considered by the outer query (Part A). Conceptually you can think of the DBMS reading all rows that match the outer query then stepping through them one at a time. For each outer row it executes the inner query. (In reality likely something more time-efficient happens but it will be logically equivalent to this.)



          Part C is sometimes called a correlated sub-query because it is matched (correlated) with a value coming from the outer query. In this case it is matching on cname. It is the WHERE clause that tells the DBMS to match Part C to Part A. cust_account is an alias defined in the outer query. Because a single table - account - is used three times in the statement the alias allows us to specify exactly which of these three we want to reference. It is the alias which allows us to say "match Part C to Part A."



          Part B lists all type values from table account. This part has no WHERE so it lists all accounts for all users, not just the one currently being considered by the outer query. This part is not correlated.



          The EXCEPT takes the results of the query above it (Part B) and removes those rows which occur in the query below it (Part C). Since Part B is "all types that are in the database" and Part C is "all types the current cname owns" then "B except C" is "all types except those which the current cname owns." If we have a list of all types, and we remove those which the cname owns, what is left is those types which the cname does not own. So if the inner query has any rows (for the current cname) we know there is at least one type of account that cname does not own.



          EXISTS() returns true if the inner query has row(s). So NOT EXISTS() returns true if the inner query is empty. As we have just shown, it will be empty if the current cname owns all types of accounts. So the outer query lists all cname which have all types of account - as requested in the problem.






          share|improve this answer





























            0














            You have two tables in this



            customers(cname)
            accounts(cname,type)


            I think you want this. You want to SELECT all cusotmers that have a matching account. It doesn't make sense to negate everything. And it doesn't make sense to say "every type of account." Because types here are values, and




            • it doesn't make sense to have a customer with more than one value.

            • it the question means any account, it's easier to select on the join condition itself in the exists,


            I think it's a bad question.



            SELECT cname
            FROM customers AS c
            WHERE EXISTS (
            SELECT 1
            FROM accounts AS a
            WHERE a.cname = c.cname
            );


            It also doesn't make sense to use DISTINCT cname there unless you know that there can be duplicate names AND if there were duplicate names and you used DISTINCT then you're no longer talking about customers -- just the values of their names in a (unique) set.






            share|improve this answer























            • I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
              – Bharg
              8 hours ago













            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "182"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            Bharg is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226626%2fusing-except-with-not-exists%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            There are three separate parts to the query. I'll label them so I can reference each more clearly:



            SELECT DISTINCT cname             -- Part A
            FROM account AS cust_account
            WHERE NOT EXISTS ( SELECT type -- Part B
            FROM account
            EXCEPT
            SELECT type -- Part C
            FROM account
            WHERE account.cname = cust_account.cname )


            First the inner query. Part C lists all type values for account rows owned by the customer currently being considered by the outer query (Part A). Conceptually you can think of the DBMS reading all rows that match the outer query then stepping through them one at a time. For each outer row it executes the inner query. (In reality likely something more time-efficient happens but it will be logically equivalent to this.)



            Part C is sometimes called a correlated sub-query because it is matched (correlated) with a value coming from the outer query. In this case it is matching on cname. It is the WHERE clause that tells the DBMS to match Part C to Part A. cust_account is an alias defined in the outer query. Because a single table - account - is used three times in the statement the alias allows us to specify exactly which of these three we want to reference. It is the alias which allows us to say "match Part C to Part A."



            Part B lists all type values from table account. This part has no WHERE so it lists all accounts for all users, not just the one currently being considered by the outer query. This part is not correlated.



            The EXCEPT takes the results of the query above it (Part B) and removes those rows which occur in the query below it (Part C). Since Part B is "all types that are in the database" and Part C is "all types the current cname owns" then "B except C" is "all types except those which the current cname owns." If we have a list of all types, and we remove those which the cname owns, what is left is those types which the cname does not own. So if the inner query has any rows (for the current cname) we know there is at least one type of account that cname does not own.



            EXISTS() returns true if the inner query has row(s). So NOT EXISTS() returns true if the inner query is empty. As we have just shown, it will be empty if the current cname owns all types of accounts. So the outer query lists all cname which have all types of account - as requested in the problem.






            share|improve this answer


























              1














              There are three separate parts to the query. I'll label them so I can reference each more clearly:



              SELECT DISTINCT cname             -- Part A
              FROM account AS cust_account
              WHERE NOT EXISTS ( SELECT type -- Part B
              FROM account
              EXCEPT
              SELECT type -- Part C
              FROM account
              WHERE account.cname = cust_account.cname )


              First the inner query. Part C lists all type values for account rows owned by the customer currently being considered by the outer query (Part A). Conceptually you can think of the DBMS reading all rows that match the outer query then stepping through them one at a time. For each outer row it executes the inner query. (In reality likely something more time-efficient happens but it will be logically equivalent to this.)



              Part C is sometimes called a correlated sub-query because it is matched (correlated) with a value coming from the outer query. In this case it is matching on cname. It is the WHERE clause that tells the DBMS to match Part C to Part A. cust_account is an alias defined in the outer query. Because a single table - account - is used three times in the statement the alias allows us to specify exactly which of these three we want to reference. It is the alias which allows us to say "match Part C to Part A."



              Part B lists all type values from table account. This part has no WHERE so it lists all accounts for all users, not just the one currently being considered by the outer query. This part is not correlated.



              The EXCEPT takes the results of the query above it (Part B) and removes those rows which occur in the query below it (Part C). Since Part B is "all types that are in the database" and Part C is "all types the current cname owns" then "B except C" is "all types except those which the current cname owns." If we have a list of all types, and we remove those which the cname owns, what is left is those types which the cname does not own. So if the inner query has any rows (for the current cname) we know there is at least one type of account that cname does not own.



              EXISTS() returns true if the inner query has row(s). So NOT EXISTS() returns true if the inner query is empty. As we have just shown, it will be empty if the current cname owns all types of accounts. So the outer query lists all cname which have all types of account - as requested in the problem.






              share|improve this answer
























                1












                1








                1






                There are three separate parts to the query. I'll label them so I can reference each more clearly:



                SELECT DISTINCT cname             -- Part A
                FROM account AS cust_account
                WHERE NOT EXISTS ( SELECT type -- Part B
                FROM account
                EXCEPT
                SELECT type -- Part C
                FROM account
                WHERE account.cname = cust_account.cname )


                First the inner query. Part C lists all type values for account rows owned by the customer currently being considered by the outer query (Part A). Conceptually you can think of the DBMS reading all rows that match the outer query then stepping through them one at a time. For each outer row it executes the inner query. (In reality likely something more time-efficient happens but it will be logically equivalent to this.)



                Part C is sometimes called a correlated sub-query because it is matched (correlated) with a value coming from the outer query. In this case it is matching on cname. It is the WHERE clause that tells the DBMS to match Part C to Part A. cust_account is an alias defined in the outer query. Because a single table - account - is used three times in the statement the alias allows us to specify exactly which of these three we want to reference. It is the alias which allows us to say "match Part C to Part A."



                Part B lists all type values from table account. This part has no WHERE so it lists all accounts for all users, not just the one currently being considered by the outer query. This part is not correlated.



                The EXCEPT takes the results of the query above it (Part B) and removes those rows which occur in the query below it (Part C). Since Part B is "all types that are in the database" and Part C is "all types the current cname owns" then "B except C" is "all types except those which the current cname owns." If we have a list of all types, and we remove those which the cname owns, what is left is those types which the cname does not own. So if the inner query has any rows (for the current cname) we know there is at least one type of account that cname does not own.



                EXISTS() returns true if the inner query has row(s). So NOT EXISTS() returns true if the inner query is empty. As we have just shown, it will be empty if the current cname owns all types of accounts. So the outer query lists all cname which have all types of account - as requested in the problem.






                share|improve this answer












                There are three separate parts to the query. I'll label them so I can reference each more clearly:



                SELECT DISTINCT cname             -- Part A
                FROM account AS cust_account
                WHERE NOT EXISTS ( SELECT type -- Part B
                FROM account
                EXCEPT
                SELECT type -- Part C
                FROM account
                WHERE account.cname = cust_account.cname )


                First the inner query. Part C lists all type values for account rows owned by the customer currently being considered by the outer query (Part A). Conceptually you can think of the DBMS reading all rows that match the outer query then stepping through them one at a time. For each outer row it executes the inner query. (In reality likely something more time-efficient happens but it will be logically equivalent to this.)



                Part C is sometimes called a correlated sub-query because it is matched (correlated) with a value coming from the outer query. In this case it is matching on cname. It is the WHERE clause that tells the DBMS to match Part C to Part A. cust_account is an alias defined in the outer query. Because a single table - account - is used three times in the statement the alias allows us to specify exactly which of these three we want to reference. It is the alias which allows us to say "match Part C to Part A."



                Part B lists all type values from table account. This part has no WHERE so it lists all accounts for all users, not just the one currently being considered by the outer query. This part is not correlated.



                The EXCEPT takes the results of the query above it (Part B) and removes those rows which occur in the query below it (Part C). Since Part B is "all types that are in the database" and Part C is "all types the current cname owns" then "B except C" is "all types except those which the current cname owns." If we have a list of all types, and we remove those which the cname owns, what is left is those types which the cname does not own. So if the inner query has any rows (for the current cname) we know there is at least one type of account that cname does not own.



                EXISTS() returns true if the inner query has row(s). So NOT EXISTS() returns true if the inner query is empty. As we have just shown, it will be empty if the current cname owns all types of accounts. So the outer query lists all cname which have all types of account - as requested in the problem.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 3 hours ago









                Michael GreenMichael Green

                14.2k82959




                14.2k82959

























                    0














                    You have two tables in this



                    customers(cname)
                    accounts(cname,type)


                    I think you want this. You want to SELECT all cusotmers that have a matching account. It doesn't make sense to negate everything. And it doesn't make sense to say "every type of account." Because types here are values, and




                    • it doesn't make sense to have a customer with more than one value.

                    • it the question means any account, it's easier to select on the join condition itself in the exists,


                    I think it's a bad question.



                    SELECT cname
                    FROM customers AS c
                    WHERE EXISTS (
                    SELECT 1
                    FROM accounts AS a
                    WHERE a.cname = c.cname
                    );


                    It also doesn't make sense to use DISTINCT cname there unless you know that there can be duplicate names AND if there were duplicate names and you used DISTINCT then you're no longer talking about customers -- just the values of their names in a (unique) set.






                    share|improve this answer























                    • I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                      – Bharg
                      8 hours ago


















                    0














                    You have two tables in this



                    customers(cname)
                    accounts(cname,type)


                    I think you want this. You want to SELECT all cusotmers that have a matching account. It doesn't make sense to negate everything. And it doesn't make sense to say "every type of account." Because types here are values, and




                    • it doesn't make sense to have a customer with more than one value.

                    • it the question means any account, it's easier to select on the join condition itself in the exists,


                    I think it's a bad question.



                    SELECT cname
                    FROM customers AS c
                    WHERE EXISTS (
                    SELECT 1
                    FROM accounts AS a
                    WHERE a.cname = c.cname
                    );


                    It also doesn't make sense to use DISTINCT cname there unless you know that there can be duplicate names AND if there were duplicate names and you used DISTINCT then you're no longer talking about customers -- just the values of their names in a (unique) set.






                    share|improve this answer























                    • I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                      – Bharg
                      8 hours ago
















                    0












                    0








                    0






                    You have two tables in this



                    customers(cname)
                    accounts(cname,type)


                    I think you want this. You want to SELECT all cusotmers that have a matching account. It doesn't make sense to negate everything. And it doesn't make sense to say "every type of account." Because types here are values, and




                    • it doesn't make sense to have a customer with more than one value.

                    • it the question means any account, it's easier to select on the join condition itself in the exists,


                    I think it's a bad question.



                    SELECT cname
                    FROM customers AS c
                    WHERE EXISTS (
                    SELECT 1
                    FROM accounts AS a
                    WHERE a.cname = c.cname
                    );


                    It also doesn't make sense to use DISTINCT cname there unless you know that there can be duplicate names AND if there were duplicate names and you used DISTINCT then you're no longer talking about customers -- just the values of their names in a (unique) set.






                    share|improve this answer














                    You have two tables in this



                    customers(cname)
                    accounts(cname,type)


                    I think you want this. You want to SELECT all cusotmers that have a matching account. It doesn't make sense to negate everything. And it doesn't make sense to say "every type of account." Because types here are values, and




                    • it doesn't make sense to have a customer with more than one value.

                    • it the question means any account, it's easier to select on the join condition itself in the exists,


                    I think it's a bad question.



                    SELECT cname
                    FROM customers AS c
                    WHERE EXISTS (
                    SELECT 1
                    FROM accounts AS a
                    WHERE a.cname = c.cname
                    );


                    It also doesn't make sense to use DISTINCT cname there unless you know that there can be duplicate names AND if there were duplicate names and you used DISTINCT then you're no longer talking about customers -- just the values of their names in a (unique) set.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 8 hours ago

























                    answered 8 hours ago









                    Evan CarrollEvan Carroll

                    31.1k865206




                    31.1k865206












                    • I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                      – Bharg
                      8 hours ago




















                    • I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                      – Bharg
                      8 hours ago


















                    I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                    – Bharg
                    8 hours ago






                    I've added the table 'account' now. And the expected answer is 'McBrien P.', 'Poulovassilis A.' as they have both deposit and current account.
                    – Bharg
                    8 hours ago












                    Bharg is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    Bharg is a new contributor. Be nice, and check out our Code of Conduct.













                    Bharg is a new contributor. Be nice, and check out our Code of Conduct.












                    Bharg is a new contributor. Be nice, and check out our Code of Conduct.
















                    Thanks for contributing an answer to Database Administrators Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226626%2fusing-except-with-not-exists%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Liste der Baudenkmale in Friedland (Mecklenburg)

                    Single-Malt-Whisky

                    Czorneboh