在结果中包含布尔值标志列

时间:2019-05-20 18:43:05

标签: sql sql-server

我想在结果中包括一个布尔值标志列,以表示对于任何给定的客户端都存在“ 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。

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;