Wednesday, March 7, 2012

Join Small Table to Big Table or Vice Versa, does it matter?

If I join Table1 to Table2 with a WHERE condition, is
it the same if I would join Table2 to Table1 considering
that the size of the tables are different.

Let's assume Table2 is much bigger than Table1.

I've never used MERGE, HASH JOINs etc, do any of
these help in this scenario?

Thank youserge (sergea@.nospam.ehmail.com) writes:
> If I join Table1 to Table2 with a WHERE condition, is
> it the same if I would join Table2 to Table1 considering
> that the size of the tables are different.
> Let's assume Table2 is much bigger than Table1.

For an inner join the order does not matter.

> I've never used MERGE, HASH JOINs etc, do any of
> these help in this scenario?

These are optimizer hints, and you should use them if you can get
good performance in any other way.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||> If I join Table1 to Table2 with a WHERE condition, is
> it the same if I would join Table2 to Table1 considering
> that the size of the tables are different.

Yes.

> I've never used MERGE, HASH JOINs etc, do any of
> these help in this scenario?

No.

--
David Portas
SQL Server MVP
--

"serge" <sergea@.nospam.ehmail.com> wrote in message
news:7_%te.82758$Jk6.1151808@.wagner.videotron.net. ..
> If I join Table1 to Table2 with a WHERE condition, is
> it the same if I would join Table2 to Table1 considering
> that the size of the tables are different.
> Let's assume Table2 is much bigger than Table1.
> I've never used MERGE, HASH JOINs etc, do any of
> these help in this scenario?
>
> Thank you|||On Tue, 21 Jun 2005 17:52:02 -0400, serge wrote:

> If I join Table1 to Table2 with a WHERE condition, is
> it the same if I would join Table2 to Table1 considering
> that the size of the tables are different.
> Let's assume Table2 is much bigger than Table1.

It doesn't matter because the query optimizer will go through thousands of
optimization iterations and choose the best plan it found so far in the
time frame it knows it should not spend any further.

> I've never used MERGE, HASH JOINs etc, do any of
> these help in this scenario?

no.. The query optimizer is smart enough to choose the best plan.

Tony
--
http://www.dotnet-hosting.com
Free web hosting with ASP.NET & SQL Server

Friday, February 24, 2012

join several fields to create new field

What would be the recommendation/approach in creating a seperate field in which joins several differate fields together.

I have a table with field name a, b, and c. I want the information in those fields to be populated in a seperate field, d.

So instead of:

a

122

b

joe

c

st

I would have:

d

122 joe st

Thanks!

You need to separate the storage of data from it's presentation. Generally you would store data at the lower level, then combine it when you retrieve it. You can do that either in the application that retrieves it, or in SQL. For instance in your example:

Select a + ' ' + b + ' ' + c as d

would give the result you are after

|||Could this be accomplished in a sql view?|||It could, but in my view you're still using the database to process data rather than storing it. You could also use a stored procedure|||I should clarify myself. I want the attribute data in fields

a,b,c to popluate a new field d. I've created field d in the

table with fields a,b,c. Now I just need to populate it.

Thanks.|||Possibley a better way of doing this is in the view because I

don't need to store the actual data. I just need a way to present

it in an application. So if there's a sql statement that I could

add to my existing view, that would work as well.

One caveaet in the current view is that I still want the a,b,c fields to present themselves in the view.

So ...

select a, b, c, d (as the virtual field which concatenates a,b,c)

from f

the presentation would be:

a b c d

123 joe st 123 joe st|||

The field 'd' is totally superfluous. There is no need to duplicate the data in storage.

Select a, b, c, a + ' ' + b + ' ' + c as d

Will produce exactly the output you want. You can put this select either in a stored proc, a view or in raw sql, it doesn't matter.

|||This works ... sort of.

If there are any null fields, it returns nothing. So is there a way around that.

Something can be built into the view that handles: if null then '' otherwise d + ' ' ?|||I've worked with the view and it is working well enough to return valid

results. I can't use it for the application however. I need

to actually store the data in a seperate field.

If there are thoughts on how to make this happen, I would appreciate it.

The problems I see are:

the new field must have spaces - example 122 joe st

there may be a direction but not in all cases - example 122 N joe st

Thanks.|||Depending on how complex you want your logic to be, you could either use Computed Columns (for simple logic. See http://msdn2.microsoft.com/en-us/library/ms191250.aspx) or DML triggers (for more complex logic. See http://msdn2.microsoft.com/en-us/library/ms191524.aspx).

join several fields to create new field

What would be the recommendation/approach in creating a seperate field in which joins several differate fields together.

I have a table with field name a, b, and c. I want the information in those fields to be populated in a seperate field, d.

So instead of:

a

122

b

joe

c

st

I would have:

d

122 joe st

Thanks!

You need to separate the storage of data from it's presentation. Generally you would store data at the lower level, then combine it when you retrieve it. You can do that either in the application that retrieves it, or in SQL. For instance in your example:

Select a + ' ' + b + ' ' + c as d

would give the result you are after

|||Could this be accomplished in a sql view?|||It could, but in my view you're still using the database to process data rather than storing it. You could also use a stored procedure|||I should clarify myself. I want the attribute data in fields

a,b,c to popluate a new field d. I've created field d in the

table with fields a,b,c. Now I just need to populate it.

Thanks.|||Possibley a better way of doing this is in the view because I

don't need to store the actual data. I just need a way to present

it in an application. So if there's a sql statement that I could

add to my existing view, that would work as well.

One caveaet in the current view is that I still want the a,b,c fields to present themselves in the view.

So ...

select a, b, c, d (as the virtual field which concatenates a,b,c)

from f

the presentation would be:

a b c d

123 joe st 123 joe st|||

The field 'd' is totally superfluous. There is no need to duplicate the data in storage.

Select a, b, c, a + ' ' + b + ' ' + c as d

Will produce exactly the output you want. You can put this select either in a stored proc, a view or in raw sql, it doesn't matter.

|||This works ... sort of.

If there are any null fields, it returns nothing. So is there a way around that.

Something can be built into the view that handles: if null then '' otherwise d + ' ' ?|||I've worked with the view and it is working well enough to return valid

results. I can't use it for the application however. I need

to actually store the data in a seperate field.

If there are thoughts on how to make this happen, I would appreciate it.

The problems I see are:

the new field must have spaces - example 122 joe st

there may be a direction but not in all cases - example 122 N joe st

Thanks.|||Depending on how complex you want your logic to be, you could either use Computed Columns (for simple logic. See http://msdn2.microsoft.com/en-us/library/ms191250.aspx) or DML triggers (for more complex logic. See http://msdn2.microsoft.com/en-us/library/ms191524.aspx).

Join Sequence Priority

Hi,
I have a select statement like this:
SELECT *
FROM
T1
INNER JOIN T2 ON T1.ID=T2.ID
LEFT OUTER JOIN T3 ON T2.ID=T3.ID
The problem is I need the query processor LEFT JOIN T2 and T3, then, INNER
JOIN the result with T1.
I tried to use bracket like this:
SELECT *
FROM
T1
(
INNER JOIN T2 ON T1.ID=T2.ID
LEFT OUTER JOIN T3 ON T1.ID=T2.ID
)
But it gives me error. Is there any way that I enforce the sequence of the
join priority?
Any help would be appreciated,
AlanMove the ON belonging to the INNER JOIN to after the complete LEFT OUTER
JOIN:
SELECT *
FROM
T1
INNER JOIN T2
LEFT OUTER JOIN T3 ON T2.ID=T3.ID
ON T1.ID=T2.ID
Jacco Schalkwijk
SQL Server MVP
"A.M-SG" <alanalan@.newsgroup.nospam> wrote in message
news:unMnD0M0FHA.736@.tk2msftngp13.phx.gbl...
> Hi,
>
> I have a select statement like this:
>
> SELECT *
> FROM
> T1
> INNER JOIN T2 ON T1.ID=T2.ID
> LEFT OUTER JOIN T3 ON T2.ID=T3.ID
>
> The problem is I need the query processor LEFT JOIN T2 and T3, then, INNER
> JOIN the result with T1.
>
> I tried to use bracket like this:
>
> SELECT *
> FROM
> T1
> (
> INNER JOIN T2 ON T1.ID=T2.ID
> LEFT OUTER JOIN T3 ON T1.ID=T2.ID
> )
> But it gives me error. Is there any way that I enforce the sequence of the
> join priority?
>
> Any help would be appreciated,
> Alan
>|||You'll need to use a subquery to achieve the results you are looking
for. The statement below should get you on your way:
SELECT * FROM T1 INNER JOIN (
SELECT * FROM T2 LEFT OUTER JOIN T3 ON T1.ID=T2.ID) X
ON T1.ID = X.ID
HTH
Jason Strate|||This wont work if T2 and T3 have the same coloum names.
Use:-
SELECT *
FROM
T1
INNER JOIN T2
LEFT OUTER JOIN T3 ON T2.ID = T3.ID
ON T1.ID = T2.ID
The t1->t2 ON clause is after the t2->t3 ON clause and so it is processed
after.
You dont need parenthesis, just move the ON clause.
"j strate" <jason.strate@.digineer.com> wrote in message
news:1129301301.659027.3430@.g43g2000cwa.googlegroups.com...
> You'll need to use a subquery to achieve the results you are looking
> for. The statement below should get you on your way:
> SELECT * FROM T1 INNER JOIN (
> SELECT * FROM T2 LEFT OUTER JOIN T3 ON T1.ID=T2.ID) X
> ON T1.ID = X.ID
> HTH
> Jason Strate
>|||Why?
Either order will give you same result, according to the query posted.
A.M-SG wrote:

>Hi,
>
>I have a select statement like this:
>
>SELECT *
>FROM
>T1
>INNER JOIN T2 ON T1.ID=T2.ID
>LEFT OUTER JOIN T3 ON T2.ID=T3.ID
>
>The problem is I need the query processor LEFT JOIN T2 and T3, then, INNER
>JOIN the result with T1.
>
>I tried to use bracket like this:
>
>SELECT *
>FROM
>T1
>(
>INNER JOIN T2 ON T1.ID=T2.ID
>LEFT OUTER JOIN T3 ON T1.ID=T2.ID
> )
>But it gives me error. Is there any way that I enforce the sequence of the
>join priority?
>
>Any help would be appreciated,
>Alan
>
>|||I don't know what the other posters are thinking, because unless you force
the order using hints or FORCEPLAN, the query optimizer ignores the order of
the joins and chooses the best plan based on available indexes, statistics,
etc. Look up SET FORCEPLAN, and OPTION(FORCE ORDER) in Books Online if you
want to coerce the optimizer to use a specific order. In that case, the
suggestions by the other posters may have merit.
"A.M-SG" <alanalan@.newsgroup.nospam> wrote in message
news:unMnD0M0FHA.736@.tk2msftngp13.phx.gbl...
> Hi,
>
> I have a select statement like this:
>
> SELECT *
> FROM
> T1
> INNER JOIN T2 ON T1.ID=T2.ID
> LEFT OUTER JOIN T3 ON T2.ID=T3.ID
>
> The problem is I need the query processor LEFT JOIN T2 and T3, then, INNER
> JOIN the result with T1.
>
> I tried to use bracket like this:
>
> SELECT *
> FROM
> T1
> (
> INNER JOIN T2 ON T1.ID=T2.ID
> LEFT OUTER JOIN T3 ON T1.ID=T2.ID
> )
> But it gives me error. Is there any way that I enforce the sequence of the
> join priority?
>
> Any help would be appreciated,
> Alan
>|||On Fri, 14 Oct 2005 13:03:42 -0400, Brian Selzer wrote:

>I don't know what the other posters are thinking, because unless you force
>the order using hints or FORCEPLAN, the query optimizer ignores the order o
f
>the joins and chooses the best plan based on available indexes, statistics,
>etc.
Brian, Trey,
What the other posters were thinking, is that though the evaluation
order of INNER JOINs does not matter, this can change when OUTER JOINs
are involved.
In the give example, both orders of evaluation will produce the same
results. But the OP said "I have a select statement *like* this"
(emphasis is mine). His real statement is probably more complex, and
*will* probably return wrong results if the joins are performed in the
wrong order.
Best, Hugo
--
(Remove _NO_ and _SPAM_ to get my e-mail address)|||On Fri, 14 Oct 2005 10:38:57 -0400, A.M-SG wrote:

>I tried to use bracket like this:
(snip)
>But it gives me error. Is there any way that I enforce the sequence of the
>join priority?
Hi Alan,
Jacco's answer is correct. But it might be easier to understand if you
return to this query in a year or so if you include some parentheses to
clarify (they are optional in this case):
SELECT *
FROM T1
INNER JOIN (T2 LEFT OUTER JOIN T3
ON T2.ID=T3.ID)
ON T1.ID=T2.ID
Best, Hugo
--
(Remove _NO_ and _SPAM_ to get my e-mail address)|||I'm not sure that's right. The evaluation order is immaterial. Although
I'm not privy to the internals of the relational engine within SQL Server,
in a typical evaluator, an expression is compiled into an execution tree.
For any given node in the tree, the order in which each immediately
subordinate node is executed is immaterial, so long as all are executed
prior to the execution of the given node. The join expression can be
written in several different ways to produce an equivalent execution tree.
While it is true that changing the order of tables in the FROM clause may
require a left join to change to a right join, the expressions are
equivalent with respect to the number and type (inner or outer) of joins,
produce equivalent execution trees, and most important, produce the same
results.
"Hugo Kornelis" <hugo@.pe_NO_rFact.in_SPAM_fo> wrote in message
news:vac0l19i21rv81n5itu6fk0b0brvuu4e9a@.
4ax.com...
> On Fri, 14 Oct 2005 13:03:42 -0400, Brian Selzer wrote:
>
> Brian, Trey,
> What the other posters were thinking, is that though the evaluation
> order of INNER JOINs does not matter, this can change when OUTER JOINs
> are involved.
> In the give example, both orders of evaluation will produce the same
> results. But the OP said "I have a select statement *like* this"
> (emphasis is mine). His real statement is probably more complex, and
> *will* probably return wrong results if the joins are performed in the
> wrong order.
> Best, Hugo
> --
> (Remove _NO_ and _SPAM_ to get my e-mail address)|||The rules in SQL-92 are that the JOINs are done in left-to-right order,
with the usual exceptions for parens. Your parens are wrong if you
wrote this:
Your parens are wrong if you wrote this:
SELECT *
FROM T1
INNER JOIN
T2
ON T1.id = T2.id
LEFT OUTER JOIN
T3
ON T1.id = T2.id;
It would done as:
SELECT *
FROM (T1
INNER JOIN
T2
ON T1.id = T2.id) -- makes sense
LEFT OUTER JOIN
T3
ON T1.id = T2.id; -- where is T3?
Hey! that is a serious CROSS JOIN problems
Try this:
SELECT *
FROM T1
INNER JOIN
(T2
LEFT OUTER JOIN
T3
ON T2.id = T3.id)
ON T1.id = T2.id);
You also need to research the scoping rules when you use a derived
table name. It is logical and follows the pattern you would expect
from block-structures languages. But you need to think about it.

Join Returns too many rows

Hi

I'm sure this is a real noob question and it may be something I have know the answer to in the past but I can't remember and its been driving me mad for hours. If anyone can tell me how to do this it would make my day!

I have simplified the problem for the purpose of clarity and have attached a sript to create a simple example table.

the table looks like this:

id cMatch cData
1 A A1
2 B B1
3 C C1
4 B B2
5 A A2
6 B B3

I want to be able to do a join on the two table that only returns the following:

t1.cData t2.cData
A1 A2
B1 B2
B1 B3

The Closest I can get is with the following qry:

SELECT t1.cdata, t2.cdata from tmp_Table1 t1
JOIN tmp_Table1 t2 ON t1.cMatch=t2.cMatch AND t1.cdata<>t2.cdata
WHERE t1.cdata<t2.cdata
ORDER BY t1.cdata, t2.cdata

Which returns:

t1.cData t2.cData
A1 A2
B1 B2
B1 B3
B2 B3Not sure if I attached the script last time so I thought I'd make sure.

thanks in advance for all your help!

Andy|||Hi

while not knowing your specific database, this will work with the example you provided:

SELECT MIN(cdata1), cdata2 FROM
(
SELECT t1.cdata AS cdata1, t2.cdata AS cdata2 FROM tmp_Table1 t1
INNER JOIN tmp_Table1 t2 ON t1.cMatch=t2.cMatch
AND t1.cData <> t2.cData
AND t1.id < t2.id)
AS subtable
GROUP BY cdata2

you may have to change the aggragation function that evaluates the correct value to choose.

join results from multiple EXEC calls

I would like to make inner join with results from different exec %procedureName% calls.

thanks.

insert into #temp
exec Proc1

insert into #temp2
exec Proc2

insert into #temp3
exec Proc3

Then join or union the tables (depending on the data)
If the reultsets are the same you can insert into 1 table instead of multiple tables

Denis the SQL Menace

http://sqlservercode.blogspot.com/

|||

You might also consider rewriting the procedures as functions if it is possible, then the join of the sets would be very natural.

select *
from function (parm) as set1
join function2(parm) as set2
on set1.value = set2.value

join reducing selected data in undesired way

Platform: SQL Server 2000 (8.00.2040, SP4, Enterprise edition)

I've got a complex query I'm trying to build, which will select all requests that have a status_code of 1, and who's related incident has a manager_id of the specified value.

SELECT (columns desired)
FROM recipient p
JOIN requests r ON p.recipient_id=r.recipient_id
JOIN incident i ON r.request_id=i.request_id
WHERE i.manager_id='value' AND r.status_code = 1

manager_id is a clumn in incident, and status_code is a column in requests

Run this way, the query selects 6 records, which I would expect.

Complication:

I need additional data from 2 more tables. This is intended give me the user who performed the insert action on the incident, and their first and last name.

table actions (a) has:user_id which is FK to users tablerequest_id which is FK to requests table already in queryaction_type which will need to be constrained to a value of 1 when a.request_id=r.request_id
table users (u) has columns with user name (which will replace user_id in display)

When I add these tables to the join in the following manner, my result set goes down to 1 record.

SELECT (columns desired)
FROM recipient p
JOIN requests r ON p.recipient_id=r.recipient_id
JOIN incident i ON r.request_id=i.request_id
JOIN actions a ON a.request_id=i.request_id
JOIN users u ON a.user_id=u.user_id
WHERE manager_id='value' AND status_code = 1

While I believe I need to be specific that I want the user_id from actions that performed the action_type=1, I don't believe that's what's hindering the operation (I'd have expected to get some duplicate results).

Any thoughts?The join on the actions table or the users table is causing the result set to shrink. Try doing a join on actions and request to see if you get the right number of results.|||try this

SELECT (columns desired)
FROM recipient p
JOIN requests r ON p.recipient_id=r.recipient_id
JOIN incident i ON r.request_id=i.request_id
left outer JOIN actions a ON a.request_id=i.request_id
JOIN users u ON a.user_id=u.user_id
WHERE manager_id='value' AND status_code = 1|||Left join worked, thanks.