我想在结果中包括一个布尔值标志列,以表示对于任何给定的客户端都存在“ IN ##”备忘录。例如,在下表中,BOB在SEC表中有2个备忘录。我想为两行都返回INFlag = 1,因为他的一个备忘录包含“ IN”(我只关心“ IN”备忘录,因此CASE语句使其他所有内容都为NULL)。
我已经尝试在选择的情况下进行计数,并嵌套子查询,但是我能管理的最好办法是仅标记带有“ IN”备忘录的行。我要标记所有特定客户端的所有行,只要它们具有“ IN”备忘录即可。
两个表:
dbo.BASE
id name image
== ==== =====
1 BOB 001
2 RICK 002
3 JOE 003
4 BILL 004
5 KEVIN 005
dbo.SEC
id memo date
== ==== ======
1 IN20 4/1/19
1 ME 1/1/18
2 MO 1/1/18
3 IN18 6/1/17
3 MO 5/1/19
4 ME 1/1/16
5 ME 1/1/17
5 MO 8/1/17
5 MI 2/1/18
SELECT
b.name as [PName],
COUNT(s.memo) as [Memos],
CASE
WHEN s.memo like 'IN[0-9][0-9]'
THEN s.memo
ELSE NULL END
as [INID],
CASE
WHEN s.memo like 'IN[0-9][0-9]'
THEN s.date
ELSE NULL END
as [INDate],
<<<FLAG Column [INFlag]>>>
FROM
dbo.BASE b
join dbo.SEC s on b.id = s.id
...
预期输出:
PName Memos INID INDate INFlag
===== ===== ==== ====== ======
BOB 2 IN20 4/1/19 1
BOB 2 NULL NULL 1
RICK 1 NULL NULL 0
JOE 2 IN18 6/1/17 1
JOE 2 NULL NULL 1
BILL 1 NULL NULL 0
KEVIN 3 NULL NULL 0
KEVIN 3 NULL NULL 0
KEVIN 3 NULL NULL 0
客户RICK,BILL和KEVIN没有“ IN”备忘,因此我想用INFlag = 0标记所有结果。客户BOB和JOE确实有一个“ IN”备忘录,因此任何名称相同的行都将获得INFlag = 1。
答案 0 :(得分:2)
要获得所需的结果,请使用窗口功能:
select b.name, count(*) over (partition by id) as num_memos,
(case when memo like 'IN%' then memo end) as INmemo,
(case when memo like 'IN%' then date end) as INdate,
max(case when memo like 'IN%' then 1 else 0 end) over (partition by name) as INlag
from base b join
sec s
on b.id = s.id
您还可以使用base
将信息添加到EXISTS
中的每一行:
select b.*,
(case when exists (select 1
from sec s
where s.id = b.id and
s.memo like 'IN%'
)
then 1 else 0
end) as INflag
from base b;