Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL Case Statement in a JOIN ON Clause

I am trying to build a case/if statement in a JOIN ON clause.

LEFT JOIN [CTSTRC] [Statuses] ON RIGHT([Statuses].[STRID], 3) = [CTE].[F61]

The problem is that the column [Statuses].[STRID] contains text and numbers. The column I am comparing it to [CTE].[F61] is an integer.

Is there a way to detect if column [Statuses].[STRID] has a character or a number and THEN set it to 0 if it is a character?

Here is a pseudo query to help:

LEFT JOIN [CTSTRC] [Statuses] 
    ON RIGHT((
        CASE [Statuses].[STRID] 
            WHEN TEXT THEN 0 
            ELSE CAST([Statuses].[STRID] AS INT) END), 3) = [CTE].[F61]
like image 574
Jared Avatar asked Dec 02 '11 18:12

Jared


People also ask

Can you do a case statement on a join?

There are plenty of ways to resolve for this: a subquery with a CASE statement in the join statement for the table you are joining in, a CASE statement in a temp table where all values are changed to match, or this handy little trick of using a CASE statement in the JOIN's ON clause.

Can you use case when in a WHERE clause?

CASE can be used in any statement or clause that allows a valid expression. For example, you can use CASE in statements such as SELECT, UPDATE, DELETE and SET, and in clauses such as select_list, IN, WHERE, ORDER BY, and HAVING.

Can we write CASE statement in FROM clause?

Another way to use the Case Statement is within the WHERE clause. There, it may be utilized to alter the data fetched by a query based on a condition. Within that context, the Case Statement is ideally suited to both static queries, as well as dynamic ones, such as those that you would find inside a stored procedure.

Can we use joins in with clause?

How to create a join with the USING clause in Oracle? Use the USING clause to specify the columns for the equijoin where several columns have the same names but not same data types. Use the USING clause to match only one column when more than one column matches.


2 Answers

You're looking for IsNumeric but it doesn't always work (+,- and . are numeric) so you need to use the solution described by GBN which is to add .0e0 to your varchar

LEFT JOIN [CTSTRC] [Statuses] ON 
    (CASE WHEN ISNUMERIC(RIGHT([Statuses].[STRID], 3) + '.0e0) = 1 
          THEN  CAST(RIGHT([Statuses].[STRID], 3) AS INT) 
          ELSE 0  END) = [CTE].[F61] 
like image 191
Conrad Frix Avatar answered Sep 28 '22 02:09

Conrad Frix


create a persisted computed column and add an index on it.

ALTER TABLE YourTable ADD
    NewIntID AS (CASE ISNUMERIC(RIGHT([Statuses].[STRID], 3) + '.0e0)
                     WHEN 1 THEN CAST(RIGHT([Statuses].[STRID], 3) AS INT) 
                     ELSE 0
                 END) PERSISTED
GO

CREATE INDEX IX_YourTable_NewIntID 
ON YourTable (NewIntID ); 
GO

you can now just join to the new NewIntID column as if it were the proper numeric ID now.

like image 37
KM. Avatar answered Sep 28 '22 01:09

KM.