我想编写一个按条件选择行的查询,但是如果没有对该条件的响应,则代码应该选择相同的列,但没有条件。
这样做的正确方法是什么?谢谢!
这是我的例子 - 选择此项:
select top 1 *
from tbl
where isActive = 1
但如果没有回复,请选择此选项:
select top 1 *
from tbl
请注意,查询很大且很复杂,所以我不想选择一个,然后选择第二个,如果第一个为null。另外因为我之后有一个union
,它会抛出这个语法的错误。
答案 0 :(得分:1)
假设您的查询是select top x ...
查询,我只会按照Peter的回答建议使用该订单。假设它不涉及top x
,因为您编写的实际查询很复杂,您可以使用公用表表达式。
我们的想法是将大而复杂的查询封装在cte中,但是如果条件为true或false,则使用case表达式返回1或0,而不是编写where子句来过滤掉记录。
然后从cte中选择case表达式结果为1或cte中没有记录,其中case表达式结果为1。
创建并填充样本表(请在将来的问题中保存此步骤)
DECLARE @T AS TABLE
(
Id int identity(1,1),
IsActive bit
)
INSERT INTO @T VALUES
(1),(1),(NULL),(1),(1),(NULL),
(1),(1),(NULL),(1),(1),(NULL),
(1),(1),(NULL),(1),(1),(NULL),
(1),(1),(NULL),(1),(1),(NULL)
公用表表达式:
;WITH CTE AS
(
SELECT Id, IsActive,
CASE WHEN IsActive = 1 THEN 1
ELSE 0
END As FoundRecords
FROM @T
)
查询:
SELECT Id, IsActive
FROM CTE
WHERE FoundRecords = 1
OR NOT EXISTS
(
SELECT 1
FROM CTE
WHERE FoundRecords = 1
)
结果:
Id IsActive
1 True
2 True
4 True
5 True
7 True
8 True
10 True
11 True
13 True
14 True
16 True
17 True
19 True
20 True
22 True
23 True
答案 1 :(得分:0)
最简单的方法是不使用where isActive = 1
,而是按isActive
按降序排序:
select top 1 *
from tbl
order by isActive desc
您甚至可能需要考虑添加其他排序字段(例如ID,名称,日期),因为如果没有这些字段,结果项可能无法预测。
答案 2 :(得分:0)
您可以使用IF-Else条件,对吗?
DECLARE @result INT
SET @result = CONVERT(INT, (SELECT COUNT(*) FROM tbl WHERE isActive = 1))
IF (@result > 0)
BEGIN
select top 1 * from tbl where isActive = 1;
END
ELSE
BEGIN
select top 1 * from tbl;
END