我遇到一种情况,我需要创建一个查询,其中查询的过滤器需要从 2 个可能位置中的 1 个位置开始的结果集。
我开始在网上搜索,看看是否有办法使用这样的CASE
语句:
A.Column IN (CASE EXISTS()...THEN (SELECT...)... END)
并且找不到任何明确的答案,所以我尝试自己制作这样的东西,但我收到以下错误,我不明白为什么:
子查询返回了 1 个以上的值。当子查询跟在 =、!=、<、<= 、>、>= 后面或子查询用作表达式时,不允许这样做。
用简单的英语来说,我希望我的查询只过滤出包裹在基于报告类型的名为Contracts
的驱动程序表中包含合同的宗地。有些报表在驱动程序表中有许多协定,有些报表则没有协定。如果报表类型在驱动程序表中没有协定,请使用所有可能的协定。我的约束是不使用动态 SQL,因此可以将此查询放入表值函数中
我的查询如下所示:
SELECT DISTINCT
IDNum, PName, County, CountyDescription,
DATENAME(MONTH, ptn) AS ptn_mt_char,
YEAR(ptn) AS ptn_yr,
MONTH(ptn) AS ptn_mt,
ptn
FROM
(SELECT
A.ID AS IDNum,
A.PName, A.County, A.CountyDescpription,
dbo.udf_getPtn(A.ID,
CAST(@ReportType AS VARCHAR),
CAST(@DataDate AS VARCHAR),
CAST(@montha AS VARCHAR),
CAST(@monthb AS VARCHAR),
CAST(@total_fa AS VARCHAR),
CAST(@total_fb AS VARCHAR)) AS ptn
FROM
DB.dbo.PData A
LEFT JOIN
DB.dbo.FData B ON A.ID = B.ID
WHERE
A.Contract IN (CASE WHEN EXISTS(SELECT cnt FROM dbo.Contracts WHERE ReportType = @ReportType AND SubReportType = @SubReportType)
THEN (SELECT cnt FROM dbo.Contracts WHERE ReportType = @ReportType AND SubReportType = @SubReportType)
ELSE (SELECT DISTINCT ConC FROM DB.dbo.PData)
END)) A
WHERE
ptn IS NOT NULL
ORDER BY
ptn, IDNum
CASE
表达式不能返回大量值,因此您不能将其与IN
思维方式结合使用。您可以像这样重写WHERE
子句:
WHERE (
A.Contract IN (SELECT cnt
FROM dbo.Contracts
WHERE ReportType = @ReportType AND
SubReportType = @SubReportType)
)
OR
(
NOT EXISTS (SELECT 1
FROM dbo.Contracts
WHERE ReportType = @ReportType AND
SubReportType = @SubReportType)
AND
A.Contract IN (SELECT DISTINCT ConC FROM DB.dbo.PData)
)
我建议您创建两个视图来规范两个表之间的列选择(并使用查询分析器独立优化它们),然后在 sproc 中将它们合并并过滤新的"组合"列。