Unix Technical Forum

SELECT has different effect in a view

This is a discussion on SELECT has different effect in a view within the MySQL forums, part of the Database Server Software category; --> I was really suprised by something today. I have a SELECT query which works properly, returning a set of ...


Go Back   Unix Technical Forum > Database Server Software > MySQL

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-28-2008, 11:28 AM
Patrick Nolan
 
Posts: n/a
Default SELECT has different effect in a view

I was really suprised by something today. I have a SELECT query which
works properly, returning a set of values. When I used the same query
to create a view, the result is smaller. I believe the difference has
to do with the treatment of the AS keyword.

This is MySQL 5.0.22. The table, simplified, looks like this:
create table people (
userid varchar(20) primary key,
category varchar(20),
supervisor varchar(20),
active int unsigned,
foreign key (supervisor) references people (userid)
) engine = "innodb";

Here's my query:

mysql> select userid,supervisor as super,category from people
where active = true
and (category = "affiliated" or (select category from people
where userid = super) = "affiliated");

This finds every entry in the "people" table where the category is "affiliated"
or the person's supervisor has category "affiliated". When I make a view
like this:

mysql> create view affil_people as select userid,supervisor as super,category
from people where active = true and (category = "affiliated" or
(select category from people where userid = super) = "affiliated");

it doesn't get the ones with "affiliated" supervisors. When I look at "show
create table affil_people" the meat of it looks like this:

CREATE ALGORITHM=UNDEFINED DEFINER=`myself`@`localhost` SQL SECURITY DEFINER
VIEW `affil_people` AS select `people`.`userid` AS `userid`,
`people`.`supervisor` AS `super`,`people`.`category` AS `category`
from `people` where ((`people`.`active` = 1)
and ((`people`.`category` = _latin1'affiliated') or
((select `people`.`category` AS `category` from `people`
where (`people`.`userid` = `people`.`supervisor`)) = _latin1'affiliated')))

The interesting thing is that my "super" has been changed to
"`people`.`supervisor`" in the last line. Thus the last WHERE clause finds
rows where people are their own supervisors, rather than finding each person's
supervisor.

I wonder what to do about this. Is it a bug or a feature? Is there an obvious,
simple way around it?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-28-2008, 11:28 AM
Martijn Tonies
 
Posts: n/a
Default Re: SELECT has different effect in a view

Patrick,

> I was really suprised by something today. I have a SELECT query which
> works properly, returning a set of values. When I used the same query
> to create a view, the result is smaller. I believe the difference has
> to do with the treatment of the AS keyword.
>
> This is MySQL 5.0.22. The table, simplified, looks like this:
> create table people (
> userid varchar(20) primary key,
> category varchar(20),
> supervisor varchar(20),
> active int unsigned,
> foreign key (supervisor) references people (userid)
> ) engine = "innodb";
>
> Here's my query:
>
> mysql> select userid,supervisor as super,category from people
> where active = true
> and (category = "affiliated" or (select category from people
> where userid = super) = "affiliated");


Have you tried properly aliasses your tables in order to avoid
MySQL trying to replace table names?

eg:

select p.userid, p.supervisor, p.category
from people p
where p.active = true
and (p.category = 'affiliated' or (select p2.category
from people p2 where p2.userid = p.supervisor) = 'affiliated')

?


--
Martijn Tonies
Database Workbench - development tool for MySQL, and more!
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com

> This finds every entry in the "people" table where the category is

"affiliated"
> or the person's supervisor has category "affiliated". When I make a view
> like this:
>
> mysql> create view affil_people as select userid,supervisor as

super,category
> from people where active = true and (category = "affiliated" or
> (select category from people where userid = super) = "affiliated");
>
> it doesn't get the ones with "affiliated" supervisors. When I look at

"show
> create table affil_people" the meat of it looks like this:
>
> CREATE ALGORITHM=UNDEFINED DEFINER=`myself`@`localhost` SQL SECURITY

DEFINER
> VIEW `affil_people` AS select `people`.`userid` AS `userid`,
> `people`.`supervisor` AS `super`,`people`.`category` AS `category`
> from `people` where ((`people`.`active` = 1)
> and ((`people`.`category` = _latin1'affiliated') or
> ((select `people`.`category` AS `category` from `people`
> where (`people`.`userid` = `people`.`supervisor`)) =

_latin1'affiliated')))
>
> The interesting thing is that my "super" has been changed to
> "`people`.`supervisor`" in the last line. Thus the last WHERE clause

finds
> rows where people are their own supervisors, rather than finding each

person's
> supervisor.
>
> I wonder what to do about this. Is it a bug or a feature? Is there an

obvious,
> simple way around it?



Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-28-2008, 11:28 AM
Patrick Nolan
 
Posts: n/a
Default Re: SELECT has different effect in a view

On 2007-09-26, Martijn Tonies <m.tonies@upscene.removethis.com> wrote:
> Patrick,
>
>> I was really suprised by something today. I have a SELECT query which
>> works properly, returning a set of values. When I used the same query
>> to create a view, the result is smaller. I believe the difference has
>> to do with the treatment of the AS keyword.
>>
>> This is MySQL 5.0.22. The table, simplified, looks like this:
>> create table people (
>> userid varchar(20) primary key,
>> category varchar(20),
>> supervisor varchar(20),
>> active int unsigned,
>> foreign key (supervisor) references people (userid)
>> ) engine = "innodb";
>>
>> Here's my query:
>>
>> mysql> select userid,supervisor as super,category from people
>> where active = true
>> and (category = "affiliated" or (select category from people
>> where userid = super) = "affiliated");

>
> Have you tried properly aliasses your tables in order to avoid
> MySQL trying to replace table names?
>
> eg:
>
> select p.userid, p.supervisor, p.category
> from people p
> where p.active = true
> and (p.category = 'affiliated' or (select p2.category
> from people p2 where p2.userid = p.supervisor) = 'affiliated')
>


Thanks. That fixes the problem. I should have known that it was
something simple. I recently upgraded from version 3.x to 5.0,
and now I am learning about all the new features. The lesson
for today is subqueries.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-28-2008, 11:28 AM
Captain Paralytic
 
Posts: n/a
Default Re: SELECT has different effect in a view

On 26 Sep, 23:47, Patrick Nolan <p...@glast2.Stanford.EDU> wrote:
> On 2007-09-26, Martijn Tonies <m.ton...@upscene.removethis.com> wrote:
>
>
>
>
>
> > Patrick,

>
> >> I was really suprised by something today. I have a SELECT query which
> >> works properly, returning a set of values. When I used the same query
> >> to create a view, the result is smaller. I believe the difference has
> >> to do with the treatment of the AS keyword.

>
> >> This is MySQL 5.0.22. The table, simplified, looks like this:
> >> create table people (
> >> userid varchar(20) primary key,
> >> category varchar(20),
> >> supervisor varchar(20),
> >> active int unsigned,
> >> foreign key (supervisor) references people (userid)
> >> ) engine = "innodb";

>
> >> Here's my query:

>
> >> mysql> select userid,supervisor as super,category from people
> >> where active = true
> >> and (category = "affiliated" or (select category from people
> >> where userid = super) = "affiliated");

>
> > Have you tried properly aliasses your tables in order to avoid
> > MySQL trying to replace table names?

>
> > eg:

>
> > select p.userid, p.supervisor, p.category
> > from people p
> > where p.active = true
> > and (p.category = 'affiliated' or (select p2.category
> > from people p2 where p2.userid = p.supervisor) = 'affiliated')

>
> Thanks. That fixes the problem. I should have known that it was
> something simple. I recently upgraded from version 3.x to 5.0,
> and now I am learning about all the new features. The lesson
> for today is subqueries.- Hide quoted text -
>
> - Show quoted text -


I would also replace your subselect with a LEFT JOIN

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-28-2008, 11:28 AM
Patrick Nolan
 
Posts: n/a
Default Re: SELECT has different effect in a view

On 2007-09-27, Captain Paralytic <paul_lautman@yahoo.com> wrote:
>
> I would also replace your subselect with a LEFT JOIN
>

Thanks. I have always been a bit frightened of LEFT JOINs, but I
decided to give it a try. I was able to come up with a query that
works and looks simpler:

mysql> select p.* from people p left join people s
on s.userid = p.supervisor where (p.category = "affiliated" or
s.category = "affiliated") and p.active = true;

Meanwhile, I also decided to learn about embedded functions.
I produced one which also simplifies the query:

CREATE FUNCTION super_cat (id varchar(20)) RETURNS varchar(20)
begin
declare x,y varchar(20);
select supervisor into x from people where userid = id;
if x is null then
return null;
else
select category into y from people where userid = x;
return y;
end if;
end

The query looks like
select * from people where active = true and (category = "affiliated"
or super_cat(userid) = "affiliated");

The query is quite simple, at the expense of making a specialized
function. Is either approach to be preferred for efficiency?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-28-2008, 11:28 AM
Martijn Tonies
 
Posts: n/a
Default Re: SELECT has different effect in a view

Patrick,

> CREATE FUNCTION super_cat (id varchar(20)) RETURNS varchar(20)
> begin
> declare x,y varchar(20);
> select supervisor into x from people where userid = id;
> if x is null then
> return null;
> else
> select category into y from people where userid = x;
> return y;
> end if;
> end


You might want to take a loko at that first part there --

if there's no resultset, what does X become? If you initialize X with
something, eg:

declare x, y varchar(20);

x = 'test';
select supervisor into x from people where userid = id;

is X NULL or 'test'?

I'm wondering, cause I don't think the SELECT will put anything
into X if there's no resultset.


--
Martijn Tonies
Database Workbench - development tool for MySQL, and more!
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 02-28-2008, 11:28 AM
Patrick Nolan
 
Posts: n/a
Default Re: SELECT has different effect in a view

On 2007-09-28, Martijn Tonies <m.tonies@upscene.removethis.com> wrote:
> Patrick,
>
>> CREATE FUNCTION super_cat (id varchar(20)) RETURNS varchar(20)
>> begin
>> declare x,y varchar(20);
>> select supervisor into x from people where userid = id;
>> if x is null then
>> return null;
>> else
>> select category into y from people where userid = x;
>> return y;
>> end if;
>> end

>
> You might want to take a loko at that first part there --
>
> if there's no resultset, what does X become? If you initialize X with
> something, eg:
>
> declare x, y varchar(20);
>
> x = 'test';
> select supervisor into x from people where userid = id;
>
> is X NULL or 'test'?
>
> I'm wondering, cause I don't think the SELECT will put anything
> into X if there's no resultset.
>

According to the online manual, the default value is NULL if there
is no DEFAULT clause. I assumed that if there is no result set
it would continue to be NULL. I also assumed that y will continue
to be NULL if category is NULL. If this behavior is not guaranteed,
then a few more tests would be justified.

My first version didn't have the "if x is null" test. It returned
the correct results, but it generated warnings in the "select
category" line when x was NULL.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 05:11 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
www.UnixAdminTalk.com