sql server programming:
Given a query of the form: SELECT <columns> FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> does anyone have an example/link where adding a predicate to ON concerning a column(s) from T1: SELECT <columns> FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> and T1.<column> (predicate) [value] (ie. T1.<column>=4) is 'meaningful'. In other words, an example where adding a predicate(s) concerning 'T1' solved a real problem. I'm not interested in the mechanics, ansi, optimizer or indexes:) Just how it was used to answer a 'real' logical question. Thanks, steve
Steve In your example it shows that you have already got all data from LEFT (T1) table , so adding a predicate to one of the columns from T1 won't show you an answer a 'real' logical question. Consider this example create table customers (customerid int primary key,custname varchar(50) not null) go insert into customers values (1,'John') insert into customers values(2,'Steve') insert into customers values(3,'Uri') go create table orders (orderrid int primary key,customerid int references customers(customerid)) go insert into orders values(1000,1) insert into orders values (2000,2) --usage select o.customerid,c.customerid from customers c left join orders o on c.customerid=o.customerid where o.customerid<>2 or o.customerid is null --filter out customerid=2 select o.customerid,c.customerid from customers c left join orders o on c.customerid=o.customerid and o.customerid<>2 --it was filterd out before join ,however , because it is NULL ,OUTER JOIN returns the value go drop table orders,customers [quoted text, click to view] "Steve Dassin" <rac4sqlnospam@net> wrote in message news:uzEuVJEFHHA.1816@TK2MSFTNGP06.phx.gbl... > Given a query of the form: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > does anyone have an example/link where adding a predicate > to ON concerning a column(s) from T1: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > and T1.<column> (predicate) [value] > (ie. T1.<column>=4) > > is 'meaningful'. In other words, an example where adding a predicate(s) > concerning 'T1' solved a real problem. > I'm not interested in the mechanics, ansi, optimizer or indexes:) > Just how it was used to answer a 'real' logical question. > > Thanks, > steve > >
I've only needed this functionality a small number of times so far, but here is an example based from memory; essentially i wanted a row to come out and was joining for stuff from the other table based on status declare @individual table ( id int not null identity, fullname varchar(100) ) declare @tasks table ( id int not null identity, individual_id int not null, is_complete char(1) not null ) set nocount on insert @individual ( fullname ) values ( 'tony rogerson' ) insert @individual ( fullname ) values ( 'trevor dwyer' ) insert @individual ( fullname ) values ( 'simon sabin' ) insert @tasks ( individual_id, is_complete ) values( 1, 'N' ) insert @tasks ( individual_id, is_complete ) values( 1, 'N' ) insert @tasks ( individual_id, is_complete ) values( 1, 'Y' ) insert @tasks ( individual_id, is_complete ) values( 1, 'Y' ) insert @tasks ( individual_id, is_complete ) values( 1, 'N' ) insert @tasks ( individual_id, is_complete ) values( 2, 'N' ) insert @tasks ( individual_id, is_complete ) values( 2, 'N' ) -- gives a row for each individual correctly. select i.id, i.fullname, task = coalesce( 'task id ' + cast( t.id as varchar(10) ) + ' needs doing', 'nothing todo' ) from @individual i left outer join @tasks t on t.individual_id = i.id and t.is_complete = 'N' -- this loses the row... select i.id, i.fullname, task = coalesce( 'task id ' + cast( t.id as varchar(10) ) + ' needs doing', 'nothing todo' ) from @individual i left outer join @tasks t on t.individual_id = i.id where t.is_complete = 'N' -- Tony Rogerson SQL Server MVP http://sqlblogcasts.com/blogs/tonyrogerson - technical commentary from a SQL Server Consultant http://sqlserverfaq.com - free video tutorials [quoted text, click to view] "Steve Dassin" <rac4sqlnospam@net> wrote in message news:uzEuVJEFHHA.1816@TK2MSFTNGP06.phx.gbl... > Given a query of the form: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > does anyone have an example/link where adding a predicate > to ON concerning a column(s) from T1: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > and T1.<column> (predicate) [value] > (ie. T1.<column>=4) > > is 'meaningful'. In other words, an example where adding a predicate(s) > concerning 'T1' solved a real problem. > I'm not interested in the mechanics, ansi, optimizer or indexes:) > Just how it was used to answer a 'real' logical question. > > Thanks, > steve > >
Hi Uri, My example wasn't really an example with data. It was just the general form of a query with outer join to which a predicate is added. Perhaps you can come up with something using any form of outer join where the predicate concerns the inner (1st table). Use your data any way you wish. Again I'm really interested in what question the query answers. thanks, steve [quoted text, click to view] "Uri Dimant" <urid@iscar.co.il> wrote in message news:u1nbJsEFHHA.1248@TK2MSFTNGP03.phx.gbl... > Steve > In your example it shows that you have already got all data from LEFT (T1) > table , so adding a predicate to one of the columns from T1 won't show you > an answer a 'real' logical question. > > Consider this example > > create table customers (customerid int primary key,custname varchar(50) not > null) > go > insert into customers values (1,'John') > insert into customers values(2,'Steve') > insert into customers values(3,'Uri') > go > create table orders (orderrid int primary key,customerid int references > customers(customerid)) > go > insert into orders values(1000,1) > insert into orders values (2000,2) > > --usage > select o.customerid,c.customerid from customers c left join orders o on > c.customerid=o.customerid > where o.customerid<>2 or o.customerid is null --filter out customerid=2 > > select o.customerid,c.customerid from customers c left join orders o on > c.customerid=o.customerid > and o.customerid<>2 --it was filterd out before join ,however , because it > is NULL ,OUTER JOIN returns the value > go > drop table orders,customers > > > > "Steve Dassin" <rac4sqlnospam@net> wrote in message > news:uzEuVJEFHHA.1816@TK2MSFTNGP06.phx.gbl... > > Given a query of the form: > > > > SELECT <columns> > > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > > > does anyone have an example/link where adding a predicate > > to ON concerning a column(s) from T1: > > > > SELECT <columns> > > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > and T1.<column> (predicate) [value] > > (ie. T1.<column>=4) > > > > is 'meaningful'. In other words, an example where adding a predicate(s) > > concerning 'T1' solved a real problem. > > I'm not interested in the mechanics, ansi, optimizer or indexes:) > > Just how it was used to answer a 'real' logical question. > > > > Thanks, > > steve > > > > > >
[quoted text, click to view] Steve Dassin wrote: > Given a query of the form: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > does anyone have an example/link where adding a predicate > to ON concerning a column(s) from T1: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > and T1.<column> (predicate) [value] > (ie. T1.<column>=4) > > is 'meaningful'. In other words, an example where adding a predicate(s) > concerning 'T1' solved a real problem. > I'm not interested in the mechanics, ansi, optimizer or indexes:) > Just how it was used to answer a 'real' logical question. > > Thanks, > steve
Steve, "I have a high priority task and I need to assign it ASAP. Show me all our developers. If the developer is already working on a hign priority ticket, show it as well." ----------------------- Alex Kuznetsov http://sqlserver-tips.blogspot.com/ http://sqlserver-puzzles.blogspot.com/
The answer is no/none. A predicate specific to the preserved table ( or the "left" table ) in the ON clause is the same as using it in the WHERE clause. One could however generate a "pseudo-problem" by using a correlated sub-query where the correlated column is compared to the non-preserved table in the outer query. For example: SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.x = t2.x AND t1.y = ( SELECT t3.y FROM t1 t3 WHERE t3.z = t2.z ) ; Vs. SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.x = t2.x WHERE t1.y = ( SELECT t3.y FROM t1 t3 WHERE t3.z = t2.z ) ; -- Anith
Hi Steve, Another example would be if you had a customer table and a table of orders. If some of the customers had never ordered any products from you and you wanted a report of all customers (including those who had never ordered) and the products they had ordered, that query would look something like: Select c.CustName, o.ProductID From Customers c Left Outer Join Orders o On c.CustID = o.CustID Order By c.CustName But if the products ordered by a customer was considered sensitive information and you wanted to suppress the products ordered if the customer had "opted out" and you also wanted to suppress the products ordered for anyone who is under 18, then you could use something like: Select c.CustName, o.ProductID From Customers c Left Outer Join Orders o On c.CustID = o.CustID And c.OptOut <> 1 And c.DateOfBirth <= DateAdd(yy, -18, GetDate()) Order By c.CustName which would show only customer information, but no order information for clients who opted out or were too young. Tom [quoted text, click to view] "Steve Dassin" <rac4sqlnospam@net> wrote in message news:uzEuVJEFHHA.1816@TK2MSFTNGP06.phx.gbl... > Given a query of the form: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > > does anyone have an example/link where adding a predicate > to ON concerning a column(s) from T1: > > SELECT <columns> > FROM T1 LEFT JOIN T2 ON T1.<column>=T2.<column> > and T1.<column> (predicate) [value] > (ie. T1.<column>=4) > > is 'meaningful'. In other words, an example where adding a predicate(s) > concerning 'T1' solved a real problem. > I'm not interested in the mechanics, ansi, optimizer or indexes:) > Just how it was used to answer a 'real' logical question. > > Thanks, > steve > >
[quoted text, click to view] Anith wrote: > A predicate specific to the preserved table ( or the "left" table ) in the > ON clause is the same as using it > in the WHERE clause.
Certainly the 'placement' of the predicate affects the querys evaluation. Modifying Tonys data some: create table #individual ( [id] int , fullname varchar(15), likeCelko char(1) ) create table #tasks ( [id] int , individual_id int not null, is_complete char(1) not null ) insert #individual values ( 1,'tony rogerson','N' ) insert #individual values ( 2,'trevor dwyer','Y' ) insert #individual values ( 3,'simon sabin','Y' ) insert #tasks values(1, 1, 'N' ) insert #tasks values(2, 1, 'N' ) insert #tasks values(3, 2, 'Y' ) insert #tasks values(4, 2, 'Y' ) Using likeCelko='Y' in on: select fullname,likeCelko,individual_id,is_complete from #individual A left join #tasks B on A.[id]=individual_id and likeCelko='Y' fullname likeCelko individual_id is_complete --------------- --------- ------------- ----------- tony rogerson N NULL NULL trevor dwyer Y 2 Y trevor dwyer Y 2 Y simon sabin Y NULL NULL Using likeCelko='Y' in where: select fullname,likeCelko,individual_id,is_complete from #individual A left join #tasks B on A.[id]=individual_id where likeCelko='Y' fullname likeCelko individual_id is_complete --------------- --------- ------------- ----------- trevor dwyer Y 2 Y trevor dwyer Y 2 Y simon sabin Y NULL NULL [quoted text, click to view] > The answer is no/none. A predicate specific to the preserved table ( or > the "left" table ) in the ON clause is the same as using it in the WHERE > clause.
"The answer is no/none". I agree. Of what 'logical' value is there using a predicate from the inner table in on? Surely the predicate in WHERE conveys the real intent of the query. Why would I want to include no information from #tasks and include a fullname I am explicitly asking it to exlude (likeCelko='Y') using the predicate in on? Who does such a thing?-:) If I had a million rows where only 2% liked Celko the logic seems even more compelling. In fact where else in the language can I include rows that I am attempting to eliminate? One wonders what is the real intent of this manifestion of the construct. Of course we can go even further. Using a predicate with the outer table (#tasks) will serve to eliminate its 'rows'. Which could be easily accomplished in a derived table with a restriction. Looking at it like this the predicate from the outer table in on is merely a shortcut, obviating the need to construct a preliminary derived table for the outer join. If using a predicate in on with an inner table is 'illogical' and the predicate is merely a shortcut when used with the outer table, it would appear it brings nothing new to the language. What have I missed? best, steve
Hi, I appreciate the response. Please see my reply to Anith.
Hi, I appreciate the reply. Please see my reply to Anith.
[quoted text, click to view] "Steve Dassin" <steve@nospamrac4sql.net> wrote in message news:udztLvMFHHA.5000@TK2MSFTNGP03.phx.gbl... > Anith wrote: >> A predicate specific to the preserved table ( or the "left" table ) in >> the ON clause is the same as using it >> in the WHERE clause. > > Certainly the 'placement' of the predicate affects the querys > evaluation. > > Modifying Tonys data some: > > create table #individual ( > [id] int , > fullname varchar(15), > likeCelko char(1) > ) > > create table #tasks ( > [id] int , > individual_id int not null, > is_complete char(1) not null > ) > > insert #individual values ( 1,'tony rogerson','N' ) > insert #individual values ( 2,'trevor dwyer','Y' ) > insert #individual values ( 3,'simon sabin','Y' ) > > insert #tasks values(1, 1, 'N' ) > insert #tasks values(2, 1, 'N' ) > insert #tasks values(3, 2, 'Y' ) > insert #tasks values(4, 2, 'Y' ) > > Using likeCelko='Y' in on: > > select fullname,likeCelko,individual_id,is_complete > from #individual A left join #tasks B > on A.[id]=individual_id and likeCelko='Y' > > fullname likeCelko individual_id is_complete > --------------- --------- ------------- ----------- > tony rogerson N NULL NULL > trevor dwyer Y 2 Y > trevor dwyer Y 2 Y > simon sabin Y NULL NULL > > Using likeCelko='Y' in where: > > select fullname,likeCelko,individual_id,is_complete > from #individual A left join #tasks B > on A.[id]=individual_id > where likeCelko='Y' > > fullname likeCelko individual_id is_complete > --------------- --------- ------------- ----------- > trevor dwyer Y 2 Y > trevor dwyer Y 2 Y > simon sabin Y NULL NULL > >> The answer is no/none. A predicate specific to the preserved table ( or >> the "left" table ) in the ON clause is the same as using it in the WHERE >> clause. > > "The answer is no/none". I agree. Of what 'logical' value is there using > a predicate from the inner table in on? Surely the predicate in WHERE > conveys the real intent of the query. Why would I want to include > no information from #tasks and include a fullname I am explicitly > asking it to exlude (likeCelko='Y') using the predicate in on? Who does > such a thing?-:) If I had a million rows where only 2% liked Celko the > logic seems even more compelling. In fact where else in the language > can I include rows that I am attempting to eliminate? One wonders what > is the real intent of this manifestion of the construct. > > Of course we can go even further. Using a predicate with the outer table > (#tasks) will serve to eliminate its 'rows'. Which could be easily > accomplished in a derived table with a restriction. Looking at it like > this the predicate from the outer table in on is merely a shortcut, > obviating the need to construct a preliminary derived table for the outer > join. If using a predicate in on with an inner table is 'illogical' and > the predicate is merely a shortcut when used with the outer table, > it would appear it brings nothing new to the language. What have > I missed?
I would agree that this construct is very rarely used. But it's not 'illogical' (IMHO). Anything that follows the rules of the language and produces the correct result is logical to me. Of course, it may not be the best possible code and I would encourage people to avoid unusual constructs simply because they can be more difficult for someone else to understand and therefore more difficult to maintain. However, in some cases unusual code is easier to understand and/or significantly more efficient. In those cases, I'm all for using unusual constructs, with, of course, adquate comments so the next person can figure out what is going on. I'm sure that anything that could be done with this construct could be done in some other manner. But that is true of almost anything you do in almost any computer language. By the same argument, there would be no need for INNER JOINs since anything that can be done with an INNER JOIN can be done with a CROSS JOIN by moving the ON clause into the WHERE clause, that is: SELECT * FROM TABLEA INNER JOIN TABLEB ON blahblah... is equivalent to SELECT * FROM TABLEA CROSS JOIN TABLEB WHERE blahblah... You say "the predicate from the outer table in on is merely a shortcut, obviating the need to construct a preliminary derived table for the outer join". Maybe so, but not necessarily relavent. By that argument, we don't need a multiply operator (*) since we have addition (+). Would you argue "multiply is merely a shortcut, obviating the need to construct a loop adding the value the correct number of times"? I think not. Tom [quoted text, click to view] > > best, > steve > > > > >
[quoted text, click to view] "Tom Cooper" <tomcooper@comcast.no.spam.please.net> wrote in message news:R6mdnWYKSaj8P_LYnZ2dnUVZ_oydnZ2d@comcast.com... >. > Would you argue multiply is merely a shortcut, obviating the need to construct a loop > adding the value the correct number of times"? I think not. >.
No and I wouldn't argue with Update replacing deletes/inserts or Case replacing characteristic functions. But here the situation is not so clear:) My guess is that the major consideration is for performance (outer table predicate) and they got left holding the bag for the predicate in the inner table. Interestingly, MS says so little on this subject I don't know how anyone could really know. BOL says little and what is said (see FROM) makes little or no sense. Perhaps you will find this article interesting (courtesy of Alex Kuznetsov): "Meet the experts: Terry Purcell on coding predicates in outer joins" http://www-128.ibm.com/developerworks/db2/library/techarticle/purcell/0112purcell.html but don't expect much when it comes to 'what does it really mean' -:) best, steve http://racster.blogspot.com
Don't see what you're looking for? Try a search.
|