如果字段为空,如何使用列名构建分隔字符串?

How to build a delimited string using column names if the field is empty?

我做了一些搜索,大多数返回了 table 名称,或者对我的需求来说有点过头了(替换数据..if higher/lower..等)

我有一个现有的 table 我需要使用:

id | booth_100 | booth_101 | booth_102 | booth_103 | booth_105 | booth_121  | booth_200 | booth_201...etc.

如果其中没有值,我如何仅使用 'booth_' 列名称构建竖线 (|) 分隔字符串?

id | booth_100 | booth_101 | booth_102 | booth_103 | booth_105 | booth_121  | booth_200 | booth_201

1  |    1      |    0      |     0     |      0    |     0          1       |     1     |     0

我想弄清楚如何获得返回结果:

booth_100|booth_121|booth200

作为我返回的 query/string。

有没有简单的方法来做到这一点? (或者需要列出查询本身中的每个列名的很长的路?..如果那是唯一的途径,我仍然希望得到帮助)

SQL Fiddle 对于 table 例如:

另一个example/attempt:(但是这个要求列不是int?)..如果我使用int作为col类型。查询部分失败? (虽然不确定我做错了什么?)

http://sqlfiddle.com/#!18/f80c8/1/0

你的标题说“SQL 服务器”但是你的 sqlfiddle 使用 MySQL 所以我希望它是你想要的 SQL 服务器。您正在使用的 non-normalized table 实际上应该是“翻转”或“非旋转”,您可以使用交叉应用来完成,如下所示。一旦您的数据具有更规范化的形状,您就可以使用 STRING_AGG(),前提是您拥有 SQL Server 2017 或更高版本。

SQL Fiddle

SQL Server 2017 架构设置:

create table exhibitors_booth(
  id int primary key,
  booth_100 int,
  booth_101 int,
  booth_102 int,
  booth_103 int,
  booth_104 int,
  booth_200 int,
  booth_201 int,
  booth_202 int,
  booth_203 int
);

insert into exhibitors_booth values
('1', 1, 0, 1, 1, 0, 0, 0, 0, 1);

SELECT
    CrossApplied.*
into exhibitors
FROM exhibitors_booth
CROSS APPLY (
    VALUES 
                (1, 'booth_100', booth_100)
              , (2, 'booth_101', booth_101)
              , (3, 'booth_102', booth_102)
              , (4, 'booth_103', booth_103)
              , (5, 'booth_104', booth_104)
              , (6, 'booth_201', booth_200)
              , (7, 'booth_202', booth_201)
              , (8, 'booth_203', booth_202)
              , (9, 'booth_204', booth_203)
            ) AS CrossApplied(SeqNo, Booth, YesNo)
;

查询 1:

select * from exhibitors_booth

Results:

| id | booth_100 | booth_101 | booth_102 | booth_103 | booth_104 | booth_200 | booth_201 | booth_202 | booth_203 |
|----|-----------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|
|  1 |         1 |         0 |         1 |         1 |         0 |         0 |         0 |         0 |         1 |

查询 2:

select * from exhibitors

Results:

| SeqNo |     Booth | YesNo |
|-------|-----------|-------|
|     1 | booth_100 |     1 |
|     2 | booth_101 |     0 |
|     3 | booth_102 |     1 |
|     4 | booth_103 |     1 |
|     5 | booth_104 |     0 |
|     6 | booth_201 |     0 |
|     7 | booth_202 |     0 |
|     8 | booth_203 |     0 |
|     9 | booth_204 |     1 |

查询 3:

select
string_agg(booth,',') as booths
from exhibitors

Results:

|                                                                                    booths |
|-------------------------------------------------------------------------------------------|
| booth_100,booth_101,booth_102,booth_103,booth_104,booth_201,booth_202,booth_203,booth_204 |

我假设这是想要的结果。如果这不是真的,请修改您的问题以包含您正在寻找的结果。

如果您不想使用“翻转”table,只需将该代码放入 cte(或派生的 table)中,如下所示:

with cte as (
    SELECT
        CrossApplied.*
    FROM exhibitors_booth
    CROSS APPLY (
        VALUES 
                    (1, 'booth_100', booth_100)
                  , (2, 'booth_101', booth_101)
                  , (3, 'booth_102', booth_102)
                  , (4, 'booth_103', booth_103)
                  , (5, 'booth_104', booth_104)
                  , (6, 'booth_201', booth_200)
                  , (7, 'booth_202', booth_201)
                  , (8, 'booth_203', booth_202)
                  , (9, 'booth_204', booth_203)
                ) AS CrossApplied(SeqNo, Booth, YesNo)
      )
select
string_agg(booth,',') as booths
from cte
;