CASE表达式中的MSSQL Subselect

时间:2018-02-09 12:21:34

标签: sql sql-server reporting-services

我在这里挣扎了一下。

我有一个查询,根据参数返回一些值。参数按预期工作。它们由 MS SQL Reporting Services 提供。

这有意为:

SELECT 
T0.CardName
FROM OCRD T0 
WHERE
T0.[CardCode] IN (SELECT cardcode from USK_Codes_CR) -- <-- MSSQL View
ORDER BY 
T0.[CardName]

所以我想,也许尝试这样的事情:

SELECT 
T0.CardName
FROM OCRD T0 
WHERE
T0.[CardCode] IN (
CASE 
WHEN @VB = 'CR' THEN (SELECT cardcode from USK_Codes_CR)
WHEN @VB = 'GR' THEN (SELECT cardcode from USK_Codes_GR)
WHEN @VB = 'ZV' THEN (SELECT cardcode from USK_Codes_ZV)
END)
ORDER BY 
T0.[Cardname]

我试图提供命名参数,如&#39; CR&#39;,&#39; ZV&#39;&#39; GR&#39;然而,在后台,表达式应返回值列表。因此... Carcode IN(...)声明。

我已经知道SSRS级别的变通方法,比如提供带有复选框等的值列表但我想让用户只选择一个命名参数,这样他们就不必费力了数百个结果。

有什么想法吗?

修改 我选择this answer以满足我的需求,因为它有一个巧妙的解释和建议,我可以做得更好。

WHERE (@VB = 'CR' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_CR) ) OR
      (@VB = 'GR' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_GR) ) OR
      (@VB = 'ZV' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_ZV) )

4 个答案:

答案 0 :(得分:2)

WHERE (@VB = 'CR' and T0.[CardCode] IN (SELECT cardcode from USK_Codes_CR))
   OR (@VB = 'GR' and T0.[CardCode] IN (SELECT cardcode from USK_Codes_GR))
   OR (@VB = 'ZV' and T0.[CardCode] IN (SELECT cardcode from USK_Codes_ZV))

答案 1 :(得分:2)

SQL Server不支持布尔类型或布尔表达式作为单个值。相反,使用基本的布尔逻辑:

WHERE (@VB = 'CR' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_CR) ) OR
      (@VB = 'GR' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_GR) ) OR
      (@VB = 'ZV' AND T0.[CardCode] IN (SELECT cardcode from USK_Codes_ZV) )

然而,这可能不是最好的解决方案。您应该将所有代码存储在一个表中,并使用适当的&#34; VB&#34;值。然后逻辑就是:

T0.[CardCode] IN (SELECT cardcode FROM USK_Codes c WHERE c.vb = @vb) 

让多个表具有相同的列集通常表明数据模型存在问题。

答案 2 :(得分:1)

这可能是某些动态SQL的候选者,具体取决于您使用这些卡代码实际拥有多少个表:

DECLARE @CardCode sysname = 'CR';

DECLARE @SQL nvarchar(MAX);
SELECT @SQL = N'
SELECT OCRD.CardName
FROM OCRD
WHERE OCRD.CardCode IN (SELECT sq.CardCode FROM ' + QUOTENAME(v.[name]) + N' sq)
ORDER BY OCRD.ItemCode;' --You reference T2 alias here, however, that isn't in yoru query, so where is it from...?
FROM sys.views v
WHERE v.[name] = N'USK_Codes_' + @CardCode;

EXEC sp_executesql @SQL;

答案 3 :(得分:0)

您也可以将其写为CTE,并在卡代码表上使用联合查询。

WITH 
card_code_list  --you may want to make this a view
AS
(
  SELECT [VB] = 'CR', cardcode from USK_Codes_CR
  UNION SELECT [VB] = 'GR', cardcode from USK_Codes_GR
  UNION SELECT [VB] = 'ZV', cardcode from USK_Codes_ZV
)
SELECT 
  T0.CardName
FROM 
  OCRD T0 
  INNER JOIN card_code_list ccl ON T0.[CardCode] = ccl.[cardcode] AND ccl.[VB] = @VB
ORDER BY 
  T0.[Cardname]