我正在寻求简化下面的查询,而我无法绕过另一种解决方案,但我认为必须有一个可用。
目标是从Col_C中检索Col_D。 如果Col_D返回NULL,我想从Col_B获得Col_D。 如果返回NULL,则再次上升阶梯并从Col_A获取Col_D。但只有在Col_B和Col_C为NULL的情况下。
表
a = MyModule
a.function()
查询
Table_A
Col_A Col_B Col_C Col_X
L000 3200 3220 0000
Table_B
Col_A Col_B Col_C Col_D
L000 NULL NULL 3256
L000 3200 NULL 6483
L000 3200 3210 7213
L000 3200 3220 NULL
L000 3200 3230 9462
预期产出
DECLARE @X nvarchar(4) = '0000'
DECLARE @A nvarchar(4), @B nvarchar(4), @C nvarchar(4)
SELECT @A = Col_A, @B = Col_B, @C = Col_C FROM [Table_A]
WHERE [Col_X] = @X
SELECT COALESCE(
(SELECT [Col_D] FROM [Table_B] WHERE Col_C = @C AND Col_B = @B AND Col_A = @A),
(SELECT [Col_D] FROM [Table_B] WHERE Col_C IS NULL AND Col_B = @B AND Col_A = @A),
(SELECT [Col_D] FROM [Table_B] WHERE Col_C IS NULL AND Col_B IS NULL AND Col_A = @A)
) AS Col_D
编辑:添加了Table_A和预期输出
答案 0 :(得分:1)
SQL Server在排序降序时排序最后的空值。因此,您所要做的就是获取所有可能的候选记录,即:col_d不能为null,col_a必须匹配,col_b和col_c必须匹配或为null。订单下降并占据最上一行。
select col_d
from table_b
where col_d is not null
and col_a = @a
and (col_b = @b or col_b is null)
and (col_c = @c or col_c is null)
order by col_b desc, col_c desc;
完整查询,包括table_a:
select b.col_d
from (select * from table_a where col_x = @x) a
join table_b b on b.col_d is not null
and b.col_a = a.col_a
and (b.col_b = a.col_b or b.col_b is null)
and (b.col_c = a.col_c or b.col_c is null)
order by b.col_b desc, b.col_c desc;
答案 1 :(得分:0)
你想要一行,优先考虑。所以:
Select cold
From t
Where (cold = @a or colc is null) and
(Colb = @b or colb is null)
Order by (case when colc is not null then 1 else 2 end),
(Case when colc is not null then 1 else 2 end)
Fetch first 1 row only;
根据数据库的不同,您可以使用limit或top来获取一行。
答案 2 :(得分:0)
Col_A = @A
所在的最小空行。例如,您的查询将排除Col_C和Col_A具有值的结果,但Col_B为空,此查询不会。此外,如果没有行Col_A = @A
,则它将返回空结果集而不是NULL值。
如果新查询在逻辑上必须与原始查询完全相同,那么我不确定它是否可以简化为更容易阅读,尽管可能有一个更“复杂”的解决方案表现更好。 / p>
SELECT TOP 1 Col_D
FROM Table_B
WHERE Col_A = @A
ORDER BY CASE WHEN Col_B IS NOT NULL -- Sort null Col_B values to the bottom
THEN 1
ELSE 0
END,
CASE WHEN Col_C IS NOT NULL -- Sort null Col_C values to the bottom
THEN 1
ELSE 0
END,
CASE WHEN Col_D IS NOT NULL -- Sort null Col_D values to the bottom
THEN 1
ELSE 0
END