条件 where 子句

conditional where clause

我需要两个表之间的连接查询的筛选结果,但我没有 "where clause" 的条件。

我需要的是根据id_project过滤,像这样:

  1. 如果 id_project 等于 24 (24 是默认项目) 那么它应该 return 只有行 id_project =24。 此处将选择第 1,3...10 行

  2. 如果 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)