我有一张包含交易记录的表Tran
。
我有两个表Parameters1
和Parameters2
,用于在从Tran
表格中选择时过滤结果:
SELECT *
FROM
Tran t JOIN
Parameters1 p1 ON T.code1 = p1.code1
Parameters2 p2 ON T.code2 = p2.code2
WHERE p1.code1 is not null AND
p2.code2 is not null
有时Parameters1
或Parameters2
为空。
我想要的是仅当Parameters
表有记录时才进行过滤。换句话说,如果Parameters1
为空,请不要使用它来过滤,反之亦然。同样适用于Parameters2
。
我很难过。
答案 0 :(得分:3)
您通常使用dynamic SQL执行此操作,因为使用静态SQL编写动态搜索条件通常是个hackish。如果您对这种方法感兴趣,我强烈推荐Erland Sommarskog的页面dynamic SQL for SQL Server 2005。他有一个很好的案例研究,里面有很多关于如何完全满足你所要求的示例代码。
无论您使用动态SQL还是静态SQL,都应首先确定哪些过滤器适用:
DECLARE @p1_filter BIT;
DECLARE @p2_filter BIT;
SET @p1_filter = 0;
SET @p2_filter = 0;
IF EXISTS (SELECT TOP (1) * FROM Parameters1)
BEGIN
SET @p1_filter = 1;
END;
IF EXISTS (SELECT TOP (1) * FROM Parameters2)
BEGIN
SET @p2_filter = 1;
END;
如果您要使用动态SQL路由,则可以执行以下操作:
DECLARE @sql NVARCHAR(MAX);
SET @sql = 'SELECT * FROM Tran T ';
IF (@p1_filter = 1)
BEGIN
SET @sql = @sql + 'INNER JOIN Parameters1 p1 ON T.code1 = p1.code1 ';
END;
IF (@p2_filter = 1)
BEGIN
SET @sql = @sql + 'INNER JOIN Parameters2 p2 ON T.code2 = p2.code2 ';
END;
EXECUTE sp_executesql
@statement = @sql
;
否则,你将继续使用这个丑陋的(可能表现不佳)静态SQL:
SELECT *
FROM Tran T
WHERE
(
T.code1 IN (SELECT code1 FROM Parameters1)
OR (@p1_filter = 0)
)
AND
(
T.code2 IN (SELECT code2 FROM Parameters2)
OR (@p2_filter = 0)
)
;
Erland还提出了我之前提到的that same page上的静态SQL方法。你可能会在那里找到更好的方法。
你也可以采用这种方法,你在这个答案的评论中提出了这个方法:
SELECT *
FROM
Tran T
LEFT OUTER JOIN Parameters1 p1
ON T.code1 = p1.code1
LEFT OUTER JOIN Parameters2 p2
ON T.code2 = p2.code2
WHERE
T.code1 =
CASE
WHEN @p1_filter = 1
THEN p1.code1
ELSE T.code1
END
AND T.code2 =
CASE
WHEN @p2_filter = 1
THEN p2.code2
ELSE T.code2
END
;
答案 1 :(得分:0)
尝试使用RIGHT JOIN
:
SELECT * FROM Tran T
RIGHT JOIN Parameters1 p1 ON T.code1 = p1.code1
JOIN Parameters2 p2 ON T.code2 = p2.code2
WHERE p1.code1 is not null AND p2.code2 is not null
答案 2 :(得分:0)
exists
select * from Tran t
where exists(select 1 from Parameters1 p1 where t.code1 = p.code1)
and exists(select 1 from Parameters2 p2 where t.code2 = p.code2)
答案 3 :(得分:0)
我不确定我是否完全理解你想要实现的目标。如果BOTH有结果,你只想要结果吗?另外,我猜测你的连接中引用的p应该是参数1(p1)和参数2(p2)的表别名,而不仅仅是你问题中的(p)。
如果是这样,那么只需选择t。*和LEFT JOIN两个参数表,例如;
SELECT t.*
FROM
Tran t
LEFT JOIN Parameters1 p1 ON T.code1 = p1.code1
LEFT JOIN Parameters2 p2 ON T.code2 = p2.code2
WHERE p1.code1 is not null AND
p2.code2 is not null