Оператор T-SQL в предложении JOIN ON - PullRequest
6 голосов
/ 02 декабря 2011

Я пытаюсь построить оператор case / if в предложении JOIN ON.

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

Проблема в том, что столбец [Statuses].[STRID] содержит текст и цифры. Столбец, который я сравниваю с [CTE].[F61], является целым числом.

Есть ли способ определить, есть ли в столбце [Statuses].[STRID] символ или число, а затем установить его на 0, если это символ?

Вот псевдопросмотр в помощь:

LEFT JOIN [CTSTRC] [Statuses] ON RIGHT((CASE [Statuses].[STRID] WHEN TEXT THEN 0 ELSE CAST([Statuses].[STRID] AS INT) END), 3) = [CTE].[F61]

Может ли кто-нибудь указать мне правильное направление?

Спасибо!

Ответы [ 6 ]

16 голосов
/ 02 декабря 2011

Вы ищете IsNumeric, но он не всегда работает (+, - и. Являются числовыми), поэтому вам нужно использовать решение , описанное GBN , которое должно добавить .0e0 к вашему 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] 
4 голосов
/ 02 декабря 2011

создать постоянный вычисляемый столбец и добавить к нему индекс.

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

Теперь вы можете просто присоединиться к новому столбцу NewIntID, как если бы это был правильный числовой идентификатор.

3 голосов
/ 02 декабря 2011

Вы можете попытаться создать столбец выражения в таблице «Состояния», который преобразует три правильных символа в число, а затем попытаться объединить столбец выражения.

1 голос
/ 03 декабря 2011

Не понравилось бы что-то подобное:

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

Все, что вас действительно волнует, это совпадение, так почему бы не преобразовать числовое значение в varchar? Вам нужно проверить обе идеи, чтобы понять, какая из них быстрее.

Я согласен с @KM, поэтому исправление плохого дизайна - это лучшее решение. Наличие функций и операторов Case в объединении является показателем того, что ваш дизайн имеет серьезные недостатки и должен быть исправлен.

0 голосов
/ 02 декабря 2011

Возможно, вы захотите попробовать что-то вроде этого

select ...
from CTE
inner join
(
    select ...
    from [Statuses]
    where ISNUMERIC(STRID + '.0e0') = 1
) rsNumeric on CTE.F61 = rsNumeric.STRID
0 голосов
/ 02 декабря 2011

Вы ищете функцию ISNUMERIC (я полагаю, она была введена в SQL 2005):

LEFT JOIN [CTSTRC] [Statuses] ON 
    (CASE ISNUMERIC(RIGHT([Statuses].[STRID], 3)) WHEN 0 THEN 0 ELSE CAST(RIGHT([Statuses].[STRID], 3) AS INT) END) = [CTE].[F61] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...