Thread: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

<> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
Richard Broersma Jr
Date:
I expect that my intuition is incorrect about the use of ALL() and ANY(), but I found my result to
be reverse from what I expected.

Can anyone explain why <> ANY() behaves that way it does?

Here are two test case examples that do what I expect:

-- find all parent that only have boys
SELECT *
  FROM Parents AS P
 WHERE 'boy' = ALL ( SELECT gender
                       FROM Children AS C1
                      WHERE C1.parentid = P.parentid );

-- find all parent that only have girls
SELECT *
  FROM Parents AS P
 WHERE 'girl' = ALL ( SELECT gender
                        FROM Children AS C1
                       WHERE C1.parentid = P.parentid );


Here is the example that doesn't do what I expect:

--find all parents that have a mixture of boys and girls.
--but this doesn't return anything
SELECT *
  FROM Parents AS P
 WHERE 'girl' <> ALL ( SELECT gender
                         FROM Children AS C1
                        WHERE C1.parentid = P.parentid )
   AND 'boy' <> ALL (  SELECT gender
                         FROM Children AS C1
                        WHERE C1.parentid = P.parentid );

--This query gets what I want
--but I believe that it shouldn't return anything

SELECT *
  FROM Parents AS P
 WHERE 'girl' <> ANY ( SELECT gender
                         FROM Children AS C1
                        WHERE C1.parentid = P.parentid )
   AND 'boy' <> ANY (  SELECT gender
                         FROM Children AS C1
                        WHERE C1.parentid = P.parentid );

Regards,
Richard Broersma Jr.

Re: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
"John D. Burger"
Date:
Richard Broersma Jr wrote:

> Here is the example that doesn't do what I expect:
>
> --find all parents that have a mixture of boys and girls.
> --but this doesn't return anything
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ALL ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ALL (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

I read this as: Find all parents such that none of their kids are
girls and none of their kids are boys.  That is, ALL of their genders
are <> 'girl', AND ALL of their genders are <> 'boy'.  Under the
obvious assumptions about gender, the result is of course empty -
except it's not clear to me what should happen for childless people ...

> --This query gets what I want
> --but I believe that it shouldn't return anything
>
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ANY ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ANY (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

I read this as:  Find all parents such that at least one of their
kids is not a girl, and at least one of their kids is not a boy.  Of
course, this could also be written with =.

- John Burger
   MITRE


Re: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
Richard Huxton
Date:
Richard Broersma Jr wrote:
> Here is the example that doesn't do what I expect:

I'm guessing you're just stood too close to the problem.

> --find all parents that have a mixture of boys and girls.
> --but this doesn't return anything
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ALL ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ALL (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

This translates to
WHERE <none of the children are girls>
AND   <none of the children are boys>
Assuming you have a two-state gender then that's nothing.

For 'girl' <> ALL (...) then all the values you test must be not girls.

> --This query gets what I want
> --but I believe that it shouldn't return anything
>
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ANY ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ANY (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

Translates to:
WHERE <any child is not a girl> AND <any child is not a boy>
So - at least one of each.

--
   Richard Huxton
   Archonet Ltd

Re: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
Erik Jones
Date:
On Oct 10, 2007, at 12:38 PM, Richard Broersma Jr wrote:

> I expect that my intuition is incorrect about the use of ALL() and
> ANY(), but I found my result to
> be reverse from what I expected.
>
> Can anyone explain why <> ANY() behaves that way it does?
>
> Here are two test case examples that do what I expect:
>
> -- find all parent that only have boys
> SELECT *
>   FROM Parents AS P
>  WHERE 'boy' = ALL ( SELECT gender
>                        FROM Children AS C1
>                       WHERE C1.parentid = P.parentid );
>
> -- find all parent that only have girls
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' = ALL ( SELECT gender
>                         FROM Children AS C1
>                        WHERE C1.parentid = P.parentid );
>
>
> Here is the example that doesn't do what I expect:
>
> --find all parents that have a mixture of boys and girls.
> --but this doesn't return anything
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ALL ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ALL (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

This says "Give me all parents for which it is true that all of their
children are not girls and all children are not boys" which will only
be true for parents with no children.  Add a record to your Parents
table without any corresponding Children record(s) and you'll get a
result.

>
> --This query gets what I want
> --but I believe that it shouldn't return anything
>
> SELECT *
>   FROM Parents AS P
>  WHERE 'girl' <> ANY ( SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid )
>    AND 'boy' <> ANY (  SELECT gender
>                          FROM Children AS C1
>                         WHERE C1.parentid = P.parentid );

This is correct.  It reads "Give me all parents for whom any of their
children is not a girl AND any of their children is not a boy."  So,
for a parent with both a boy and a girl, the boy is not a girl and
the girl is not a boy.  You could replace the <> ANY with a simple IN
as then it would be "Give me all parents who have both a boy and a
girl."

Erik Jones

Software Developer | Emma®
erik@myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com



Re: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
Tom Lane
Date:
Richard Broersma Jr <rabroersma@yahoo.com> writes:
> Can anyone explain why <> ANY() behaves that way it does?

Aside from the responses already given, I'm wondering whether you have
any NULL entries in Children.gender.  NULL rows within a NOT IN
subselect tend to produce confusing results ...

            regards, tom lane

Re: <> ALL( ... ) and <> ANY ( ... ) didn't behave as expected

From
Richard Broersma Jr
Date:
--- "John D. Burger" <john@mitre.org> wrote:
> I read this as: Find all parents such that none of their kids are
> girls and none of their kids are boys.  That is, ALL of their genders
> are <> 'girl', AND ALL of their genders are <> 'boy'.  Under the
> obvious assumptions about gender, the result is of course empty -
> except it's not clear to me what should happen for childless people ...

Thanks everyone that makes sense!

Regards,
Richard Broersma Jr.