views:

101

answers:

3

Hi. I have a Name table with the columns NameID Name TypeID

With the following SQL

SELECT[NameID]
FROM[Name]
WHERE[TypeID] = @TypeID
AND NameID >= (SELECT MIN([NameID]) 
            FROM [Name] 
            WHERE [Name]='Billy' AND [TypeID]=@TypeID)

Ive been asked to convert this to an Inner Join without using any nested select but not sure how to. thanks for your help!

+1  A: 

Originally I didn't think you needed a join at all,

;WITH n AS 
(
    SELECT
      NameID,
      rn = ROW_NUMBER() OVER (ORDER BY NameID)
    FROM [Name]
    WHERE TypeID = @TypeID
    AND [Name] = 'Billy'
)
SELECT NameID
    FROM n
    WHERE rn > 1;

Then again, maybe I do not have the requirements clear. What is the purpose of this query?

SELECT n1.NameID 
FROM [Name] AS n1
    INNER JOIN
(
    SELECT NameID = MIN(NameID) 
    FROM [Name]
    WHERE TypeID = @TypeID
    AND [Name] = 'Billy'
) AS n2
ON n1.NameID >= n2.NameID
WHERE n1.TypeID = @TypeID;

I agree with Lukas, I am not sure why the person who is telling you to change this thinks an inner join will be better than your original.

Aaron Bertrand
Not really an equivalent, the original query will return more rows than where Name='Billy'.
Lukáš Lalinský
Yeah I am trying to understand the purpose of the original query.
Aaron Bertrand
Ive been asked to do it for performance reasons, I've been instructed that Iner Join is faster.
Gribbler
You should compare them. Since every query, data set etc. is different, nobody can possibly "instruct" you that INNER JOINs are always faster, because that simply isn't true.
Aaron Bertrand
Plus, I meant the purpose of the query in the first place. What question does this query answer?
Aaron Bertrand
Hi Aaron,Ive changed the names of the parameters as in our database they refer to names that would be meaningless unless you know the jargon for what they refer to.
Gribbler
A: 

You could remove the nested part via: -

declare @NameID int

select @NameID = (SELECT MIN([NameID]) FROM [Name] WHERE [Name]='Billy' AND [TypeID]=@TypeID)

SELECT [NameID] FROM [Name] WHERE [TypeID] = @TypeID AND NameID >= @NameID

But as stated already, this does not provide any performance benefit as the subquery would only be evaluated once in your version, the same as in this.

Andy Jones
A: 

Well, it looks like just moving the condition [Name]='Billy' should produce the same result for this specific query. So convert your original:

SELECT[NameID]
FROM[Name]
WHERE[TypeID] = @TypeID
AND NameID >= (SELECT MIN([NameID]) 
                   FROM [Name] 
                   WHERE [Name]='Billy' AND [TypeID]=@TypeID)

to:

SELECT[NameID]
FROM[Name]
WHERE[TypeID] = @TypeID
AND[Name]='Billy'
van
Would those that rate the answer down (or others that did not) be so kind to point out where the logic is flawed and/or does not answer the question? Cheers.
van
I tested this.If I have a tableNameID TypeID Name------ ------ ----1 1 Billy2 1 John 3 1 Billy4 1 Billy
Gribbler
Then the nested select returns 1 as the value (when @TypeID is 1)The query would then return ID's 1,2,3,4 (ie Billys and John)whereas your query would only return 1,3,4 (just Billys)
Gribbler
ps apologies for the formatting, and Van thanks for the input, as I say, I'm learning SQL so even checking why your SQL didn't work was a worthwhile excercise for me :)
Gribbler
good point, fair enough, thanks. I assumed that there can be just one "Name" for each "NameID".
van