условие соединения зависит от параметра - PullRequest
1 голос
/ 10 мая 2010

Я новичок в SQL, я использую mssql2005

Мне нравится выполнять присоединение к действию в зависимости от входного параметра.

CREATE PROCEDURE SelectPeriodicLargeCategoryData 
    @CATEGORY_LEVEL CHAR(1),
    @CATEGORY_CODE VARCHAR(9)
AS

...


JOIN CATEGORY_AD_SYS CAS WITH(NOLOCK)
ON CA.CATEGORY_ID = [[[[[   HERE      ]]]]

выше кв.
если @CATEGORY_LEVEL = 'L', то я хотел бы присоединиться к CAS.LCATEGORY

еще, если @CATEGORY_LEVEL = 'M', тогда я хотел бы присоединиться к CAS.MCATEGORY

иначе, если @CATEGORY_LEVEL = 'S', тогда я хотел бы присоединиться к CAS.SCATEGORY

...

как я могу это сделать?

Ответы [ 3 ]

5 голосов
/ 10 мая 2010

Вы можете использовать выражение CASE, например:

CASE @CATEGORY_LEVEL  
     WHEN 'L' THEN CAS.LCATEGORY
     WHEN 'M' THEN CAS.MCATEGORY
     WHEN 'S' THEN CAS.SCATEGORY
END

Я не уверен, насколько быстро это было бы в JOIN х ON условии (конечно, зависит от того, насколько умен умный оптимизатор запросов, поэтому вам лучше проверить, сравнив с реальными данными ) - если оказывается, что он имеет неприемлемую производительность, я думаю, вы могли бы использовать совершенно разные операторы SELECT в зависимости от @CATEGORY_LEVEL в качестве крайней меры.

2 голосов
/ 10 мая 2010

Это было бы проще, если бы вы нормализовали свои таблицы в Первая нормальная форма . Прямо сейчас столбцы вашей другой категории образуют повторяющуюся группу .

Чтобы выполнить эту нормализацию, вам нужна другая таблица для представления отношения «многие ко многим» между CAS и CA.

CREATE TABLE HasCategory (
  CATEGORY_ID    INTEGER,
  CAS_ID         INTEGER,
  CATEGORY_LEVEL CHAR(1), -- 'L' or 'M' or 'S'
  PRIMARY KEY (CATEGORY_ID, CAS_ID, CATEGORY_LEVEL),
  FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORIES,
  FOREIGN KEY (CAS_ID) REFERENCES CATEGORY_AD_SYS
); 

Тогда вы можете написать свои условия соединения гораздо более простым способом:

SELECT ...
FROM CATEGORIES CA
JOIN HasCategory H ON (H.CATEGORY_ID = CA.CATEGORY_ID)
JOIN CATEGORY_AD_SYS CAS ON (H.CAS_ID = CAS.CAS_ID)
WHERE H.CATEGORY_LEVEL = @CATEGORY_LEVEL
1 голос
/ 10 мая 2010

Если вы не можете исправить схему, как сказал Билл Карвин, тогда используйте IF для переключения запросов.

Использование оператора CASE снизит производительность (я полагаю, вы указали индексы для столбцов)

IF @CATEGORY_LEVEL = 'L'
    SELECT
    ...
    JOIN CATEGORY_AD_SYS CAS WITH(NOLOCK) ON CA.CATEGORY_ID = CAS.LCATEGORY

ELSE IF @CATEGORY_LEVEL = 'M'
    SELECT
    ...
    JOIN CATEGORY_AD_SYS CAS WITH(NOLOCK) ON CA.CATEGORY_ID = CAS.MCATEGORY 

ELSE IF @CATEGORY_LEVEL = 'M'
    SELECT
    ...
    JOIN CATEGORY_AD_SYS CAS WITH(NOLOCK) ON CA.CATEGORY_ID = CAS.SCATEGORY 
...