我是一个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
...
我该怎么做?
答案 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,这会更容易。现在,您的不同类别列形成重复组。
要完成此规范化,您需要另一个表来表示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
答案 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