如果字段为空,如何使用列名构建分隔字符串?
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.
- 我目前的理解(没有造成这个奇怪的 table)是只有“1”行
- 'booth_xxx' 列中只有“1”列有值。
如果其中没有值,我如何仅使用 '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类型。查询部分失败? (虽然不确定我做错了什么?)
你的标题说“SQL 服务器”但是你的 sqlfiddle 使用 MySQL 所以我希望它是你想要的 SQL 服务器。您正在使用的 non-normalized table 实际上应该是“翻转”或“非旋转”,您可以使用交叉应用来完成,如下所示。一旦您的数据具有更规范化的形状,您就可以使用 STRING_AGG(),前提是您拥有 SQL Server 2017 或更高版本。
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
| 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
| 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
| 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
;
我做了一些搜索,大多数返回了 table 名称,或者对我的需求来说有点过头了(替换数据..if higher/lower..等)
我有一个现有的 table 我需要使用:
id | booth_100 | booth_101 | booth_102 | booth_103 | booth_105 | booth_121 | booth_200 | booth_201...etc.
- 我目前的理解(没有造成这个奇怪的 table)是只有“1”行
- 'booth_xxx' 列中只有“1”列有值。
如果其中没有值,我如何仅使用 '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类型。查询部分失败? (虽然不确定我做错了什么?)
你的标题说“SQL 服务器”但是你的 sqlfiddle 使用 MySQL 所以我希望它是你想要的 SQL 服务器。您正在使用的 non-normalized table 实际上应该是“翻转”或“非旋转”,您可以使用交叉应用来完成,如下所示。一旦您的数据具有更规范化的形状,您就可以使用 STRING_AGG(),前提是您拥有 SQL Server 2017 或更高版本。
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
| 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
| 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
| 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
;