views:

26

answers:

2

I dynamically select a string built using another string. So, if string1='David Banner', then MyDynamicString should be 'DBanne'

Select 
...
, Left(
    left((select top 1 strval from dbo.SPLIT(string1,' ')) //first word
    ,1) //first character
    + (select top 1 strval from dbo.SPLIT(string1,' ') 
        //second word
        where strval not in (select top 1 strval from dbo.SPLIT(string1,' '))) 
,6) //1st character of 1st word, followed by up to 5 characters of second word
[MyDynamicString]
,...
From table1 Join table2 on table1pkey=table2fkey
Where MyDynamicString <> table2.someotherfield

I know table2.someotherfield is not equal to the dynamic string. However, when I replace MyDynamicString in the Where clause with the full left(left(etc.. function, it works as expected.

Can I not reference this string later in the query? Do I have to build it using the left(left(etc.. function each time in the where clause?

+3  A: 

If you do it as you have it above, then the answer is yes, you have to recreate it again in the where clause.

As an alternative, you could use an inline view:

    Select 
    ...
    , X.theString
    ,...
    From table1 Join table2 on table1pkey=table2fkey
       , (SELECT 
          string1
         ,Left(
            left((select top 1 strval from dbo.SPLIT(string1,' ')) //first word
                 ,1) //first character
            + (select top 1 strval from dbo.SPLIT(string1,' ') 
            //second word
            where strval not in (select top 1 strval from dbo.SPLIT(string1,' '))) 
           ,6) theString //1st character of 1st word, followed by up to 5 characters of second word
         FROM table1
       ) X
    Where X.theString <> table2.someotherfield
      AND X.string1 = <whatever you need to join it to>
dcp
+1 slickness, testing now
David
It's untested, so you might have to tweak the syntax a bit but I think the idea should work. Also, see my latest edit. Be sure to add the column alias in the inline view (i.e. the "theString" part).
dcp
How can I reference table1.string1 in this inline view? The inline view's FROM clause is unclear to me. I can use `FROM table1 JOIN table2 ON table1pkey=table2fkey` but do I have to repeat the Where clause? In my actual code, the Where clause has another 5 or 6 conditions
David
I don't think I can repeat the where clause since X.theString is **in** the where clause. The scope is what's confusing me here. Can your query still work for this?
David
The idea of the inline view is that you are building the calculated string, but you aren't filtering anything yet. In other words, you don't do the table2.someotherfield join in the inline view, you do that in the outer SQL statement. As for how to get string1 into the inline view, you just add it (and any other columns you need). See my latest edit. You can also join to the inline view on whatever additional columns you need also. An inline view is basically a "table you are creating on the fly". You can join to it just like any other table, as long as the columns are there.
dcp
I think I have to add an index to the inline view to compare to the actual record in question.
David
+1  A: 

In SQL 2008 you can use the alias in the ORDER BY CLAUSE, but not in the where clause.

Why not wrap the calculation up into a user defined function (UDF) to avoid violating DRY and also to make the query more readable?

If it matters, here is an article that explains why you can't use a column alias in a HAVING, WHERE, or GROUP BY.

JohnFx
@JohnFx - If this is the only query in which he's using that calculation, I think a UDF is overkill and it's better to just factor the query out into an inline view. Personally, I'd much rather see it in the query itself so I don't have to go track down the UDF to figure out what's happening. But if it's code that will be used by many queries, I agree with you 100% that UDF is the way to go.
dcp
I like this--I think I have to repeat myself in the inline view's FROM clause in dcp's answer.
David
@David - You shouldn't have to repeat the calculation, it should only be in the inline view. Or maybe I misunderstood?
dcp
Agreed. This is the only place I make this calculation.
David
Why not use CTE instead of function for it?
IMHO
+1 for the article, thanks.
David
Just thought it would be more readable to insert something like getloginFromName(string1) instead of the whole embedded function. Makes it more self documenting. I do like the CTE idea though. Plus, if he has to do it in this query. Chances are he will use that calculation again.
JohnFx