将行更改为二进制字符串

Change rows into binary string

我想知道是否有比我已经使用 SQL 服务器所做的更好的解决方案。

我的table看起来像这样

RepID   ICD9_L1
----------------
1       AB
1       NJ
1       KL
2       TH
2       KL
2       EE
2       SR
3       AB
3       SR
....
95871   PY
95871   EE
95871   AB
95871   VX

我想要一个所有代码的列表和一个二进制字符串表示形式(如果它存在于该 RepID 中)

所以

AB : 1(表示 RepID 1 退出),0(表示 RepID 2 不存在),1(表示 RepID 3 退出),...,1(表示它退出 RepID 95871)

NJ  :  1, 0, 0, ..., 0

KL  :  1, 1, 0, ..., 0

TH :   0, 1, 0, ..., 0

我用 look 构建了它,但它非常非常慢

declare @T as table (ICD9_L1 varchar(100), StrExist varchar(max))
insert into @T (ICD9_L1)
select distinct ICD9_L1 FROM Diag


declare @i int = 0
declare @x varchar(max) = ''
declare @code varchar(10)

DECLARE db_cursor CURSOR FOR 
select ICD9_L1 FROM @T  

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @code  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    
    while @i < 70000
    begin
        set @i = @i + 1

        if exists(select top 1 * FROM Diag where RepID = @i AND  ICD9_L1 = @code)
        begin
            set @x = @x + ',1'
        end
        else
        begin
            set @x = @x + ',0'
        end
    end

    update @T set StrExist = @x where ICD9_L1 = @code
    set @x = ''
      FETCH NEXT FROM db_cursor INTO @code 
END 

CLOSE db_cursor  
DEALLOCATE db_cursor 

使用string_agg()连接01

使用 tally / number table 生成 ID 列表以左连接到 table。您也可以使用递归 CTE 动态生成一个。

查询:

with 
-- generate a list of IDs
numbers as
(
    select n = 1
    union all
    select n = n + 1
    from   numbers
    where  n < 70000
),
codes as
(
    select distinct code = ICD9_L1
    from   Diag
)
select c.code, 
       string_agg((case when d.RepID is not null then '1' else '0' end), ',') 
                  within group (order by n.n)
from   codes c
       cross join numbers n
       left join Diag d   on  c.code = d.ICD9_L1
                          and n.n    = d.RepID
group by c.code