条件 where 子句
conditional where clause
我需要两个表之间的连接查询的筛选结果,但我没有 "where clause" 的条件。
我需要的是根据id_project过滤,像这样:
如果 id_project 等于 24 (24 是默认项目) 那么它应该 return 只有行
id_project =24。 此处将选择第 1,3...10 行
如果 id_project 等于 25,那么我需要那些具有 id_project=25 的行加上那些具有 " id_project=24 而不是id_project 25,因此将选择第 2 到 11 行
使用此查询:
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
//
where tl.id_level=69 and tp.node_level=1
我得到这个结果:
如何更改我的查询以执行此操作?
所以根据用户是否请求 ID 24,有两个不同的查询要执行。
这是 ID 24 的查询:
select *
from tag_project
where id_project = 24;
这里是@OTHERID 的查询。我们使用 UNION ALL 将 24 条记录与@OTHER 记录组合起来。为了避免某些记录,我们使用 NOT EXISTS。
select *
from tag_project
where id_project = @OTHERID
union all
select *
from tag_project tp
where id_project = 24
and not exists
(
select *
from tag_project tp2
where tp2.id_tag = tp.id_tag
and tp2.id_project = @OTHERID
);
仔细考虑一下您的请求,它可以归结为:对于每个 id_tag,请给我请求的 ID,如果不可用,请提供 24。这可以在一个查询中完成,您可以在其中使用 ROW_NUMBER 的排名,其中您更喜欢请求的 ID 而不是 24.
select *
from
(
select
tp.*,
row_number() over(partition by id_tag
order by case when id_project = 24 then 2 else 1 end) as rn
from tag_project tp
where id_project in (24, @REQUESTED_ID)
) ranked
where rn = 1;
这是您的原始查询,相应更改:
SELECT id_tag, id_project, NJTagName, node_level, id_level
FROM
(
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
, row_number() over (partition by tp.id_tag order by case when tp.id_project = 24 then 2 else 1 end) as rn
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl ON tl.id_tag=tp.id_tag
WHERE tl.id_level=69 AND tp.node_level=1
AND tp.id_project in (24, @REQUESTED_ID)
) ranked
WHERE rn = 1;
使用in
:
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
//
where tl.id_level=69 and tp.node_level=1
and tp.id_project in (24, @OTHERID)
更新:
如果你只想要一个 id_project 而不是,也可以使用聚合方法。
SELECT tp.id_tag, tp.NJTagName, tp.node_level , tl.id_level
case when count(distinct tp.id_project) = 2 then @OTHERID
else 24 end as id_project
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
WHERE tl.id_level=69 and tp.node_level=1
AND tp.id_project in (24, @OTHERID)
GROUP BY tp.id_tag, tp.NJTagName, tp.node_level , tl.id_level
对于默认情况,您可以像这样写 pass @otherId as NULL
.
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
where tl.id_level=69 and tp.node_level=1 AND tp.id_project = ISnull(@otherId, 24)
我需要两个表之间的连接查询的筛选结果,但我没有 "where clause" 的条件。
我需要的是根据id_project过滤,像这样:
如果 id_project 等于 24 (24 是默认项目) 那么它应该 return 只有行 id_project =24。 此处将选择第 1,3...10 行
如果 id_project 等于 25,那么我需要那些具有 id_project=25 的行加上那些具有 " id_project=24 而不是id_project 25,因此将选择第 2 到 11 行
使用此查询:
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
//
where tl.id_level=69 and tp.node_level=1
我得到这个结果:
如何更改我的查询以执行此操作?
所以根据用户是否请求 ID 24,有两个不同的查询要执行。
这是 ID 24 的查询:
select *
from tag_project
where id_project = 24;
这里是@OTHERID 的查询。我们使用 UNION ALL 将 24 条记录与@OTHER 记录组合起来。为了避免某些记录,我们使用 NOT EXISTS。
select *
from tag_project
where id_project = @OTHERID
union all
select *
from tag_project tp
where id_project = 24
and not exists
(
select *
from tag_project tp2
where tp2.id_tag = tp.id_tag
and tp2.id_project = @OTHERID
);
仔细考虑一下您的请求,它可以归结为:对于每个 id_tag,请给我请求的 ID,如果不可用,请提供 24。这可以在一个查询中完成,您可以在其中使用 ROW_NUMBER 的排名,其中您更喜欢请求的 ID 而不是 24.
select *
from
(
select
tp.*,
row_number() over(partition by id_tag
order by case when id_project = 24 then 2 else 1 end) as rn
from tag_project tp
where id_project in (24, @REQUESTED_ID)
) ranked
where rn = 1;
这是您的原始查询,相应更改:
SELECT id_tag, id_project, NJTagName, node_level, id_level
FROM
(
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
, row_number() over (partition by tp.id_tag order by case when tp.id_project = 24 then 2 else 1 end) as rn
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl ON tl.id_tag=tp.id_tag
WHERE tl.id_level=69 AND tp.node_level=1
AND tp.id_project in (24, @REQUESTED_ID)
) ranked
WHERE rn = 1;
使用in
:
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
//
where tl.id_level=69 and tp.node_level=1
and tp.id_project in (24, @OTHERID)
更新: 如果你只想要一个 id_project 而不是,也可以使用聚合方法。
SELECT tp.id_tag, tp.NJTagName, tp.node_level , tl.id_level
case when count(distinct tp.id_project) = 2 then @OTHERID
else 24 end as id_project
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
WHERE tl.id_level=69 and tp.node_level=1
AND tp.id_project in (24, @OTHERID)
GROUP BY tp.id_tag, tp.NJTagName, tp.node_level , tl.id_level
对于默认情况,您可以像这样写 pass @otherId as NULL
.
SELECT tp.id_tag, tp.id_project, tp.NJTagName, tp.node_level , tl.id_level
FROM instrumentation.dbo.tag_project tp
INNER JOIN instrumentation.dbo.tag_level tl
ON tl.id_tag=tp.id_tag
where tl.id_level=69 and tp.node_level=1 AND tp.id_project = ISnull(@otherId, 24)