连接条件取决于参数

时间:2010-05-10 04:21:10

标签: sql sql-server-2005 tsql stored-procedures

我是一个sql新手,我使用的是mssql2005

我喜欢在输入参数上加入Action depnding。

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

...


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

在sql之上。
如果@CATEGORY_LEVEL = 'L',那么我想加入CAS.LCATEGORY

否则,如果@CATEGORY_LEVEL = 'M',那么我想加入CAS.MCATEGORY

否则,如果@CATEGORY_LEVEL = 'S',那么我想加入CAS.SCATEGORY

...

我该怎么做?

3 个答案:

答案 0 :(得分:5)

您可以使用CASE表达式,例如:

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

我不确定在JOIN的{​​{1}}条件下有多快(取决于查询优化器对它的敏感程度,当然,所以你最好检查一下使用实际数据进行测量) - 如果结果表明性能不可接受,我猜您可以使用完全不同的ON语句,具体取决于SELECT作为最后的手段。

答案 1 :(得分:2)

如果您将表格规范化为First Normal Form,这会更容易。现在,您的不同类别列形成重复组

要完成此规范化,您需要另一个表来表示CASCA之间的多对多关系。

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

答案 2 :(得分:1)

如果你不能像Bill Karwin所说的那样修复架构,那么使用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