SQL - 如何在 where 子句中使用逗号分隔的列值
SQL - How to use Comma separated column values in a where clause
我有一个 table 称为配置。它包含如下值,
Id SourceColumns TargetColumns SourceTable TargetTable
1 Name, Age CName, CAge STable TTable
2 EId EmplId EmpTable TTable
在存储过程中,我必须从上面的 table 中获取列名,并且我必须比较源 table 和目标 table。
我可以轻松地为第二条记录做到这一点,因为它只有一个列名,所以在 where 子句中我可以写 sourcecolumn = targetcolumn like,
SELECT
EId
, EmplId
FROM
EmpTable E
JOIN TTable T ON E.Eid = T.EmplId
table 中的第一条记录有 2 列,用逗号 (,) 分隔。
我要这样比较,
SELECT
Name
, Age
FROM
STable S
JOIN TTable T ON S.Name = T.CName AND S.Age = T.CAge
在某些情况下,源列和目标列可能有更多列名,用逗号 (,) 分隔
请帮我解决这个问题。
不知您是否完全理解我在请求评论中建议的数据模型,为了正确回答问题:
您的 table 未规范化,因为列 SourceColumns
和 TargetColumns
中的数据不是原子的。甚至必须解释数据(分隔符是逗号,一列中的第 n 个元素与另一列中的第 n 个元素相关)。
你的 table 应该是这样的(创建语句是伪代码):
create table configuration_tables
(
id_configuration_tables int,
source_table text,
target_table text,
primary key (id_configuration_tables),
unique key (source_table),
unique key (target_table) -- or not? in your sample two souce table map to the same target table
);
create table configuration_columns
(
id_configuration_columns int,
id_configuration_tables int,
source_column text,
target_column text,
primary key (id_configuration_columns),
foreign key (id_configuration_tables) references configuration_tables (id_configuration_tables)
);
您的示例数据将变为
configuration_tables
id_configuration_tables | source_table | target_table
------------------------+--------------+-------------
1 | STable | TTable
2 | EmpTable | TTable
configuration_columns
id_configuration_columns | id_configuration_tables | source_column | target_column
-------------------------+-------------------------+---------------+--------------
1 | 1 | Name | CName
2 | 1 | Age | CAge
3 | 2 | EId | EmplId
从 SQL Server 2017 开始,您可以使用 STRING_AGG
创建您的查询。在早期版本中,这也可以通过一些 STRING_AGG
仿真来实现,你会很容易地找到机智 Google 或 SO。
select
'select s.' + string_agg (c.source_column + ', t.' + c.target_column, ', ') +
' from ' + t.source_table + ' s' +
' join ' + t.target_table + ' t' +
' on ' + string_agg('t.' + c.target_column + ' = s.' + c.source_column, ' and ') +
';' as query
from configuration_tables t
join configuration_columns c on c.id_configuration_tables = t.id_configuration_tables
group by t.source_table, t.target_table
order by t.source_table, t.target_table;
演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=8866b2485ba9bba92c2391c67bb8cae0
我有一个 table 称为配置。它包含如下值,
Id SourceColumns TargetColumns SourceTable TargetTable
1 Name, Age CName, CAge STable TTable
2 EId EmplId EmpTable TTable
在存储过程中,我必须从上面的 table 中获取列名,并且我必须比较源 table 和目标 table。
我可以轻松地为第二条记录做到这一点,因为它只有一个列名,所以在 where 子句中我可以写 sourcecolumn = targetcolumn like,
SELECT
EId
, EmplId
FROM
EmpTable E
JOIN TTable T ON E.Eid = T.EmplId
table 中的第一条记录有 2 列,用逗号 (,) 分隔。
我要这样比较,
SELECT
Name
, Age
FROM
STable S
JOIN TTable T ON S.Name = T.CName AND S.Age = T.CAge
在某些情况下,源列和目标列可能有更多列名,用逗号 (,) 分隔
请帮我解决这个问题。
不知您是否完全理解我在请求评论中建议的数据模型,为了正确回答问题:
您的 table 未规范化,因为列 SourceColumns
和 TargetColumns
中的数据不是原子的。甚至必须解释数据(分隔符是逗号,一列中的第 n 个元素与另一列中的第 n 个元素相关)。
你的 table 应该是这样的(创建语句是伪代码):
create table configuration_tables
(
id_configuration_tables int,
source_table text,
target_table text,
primary key (id_configuration_tables),
unique key (source_table),
unique key (target_table) -- or not? in your sample two souce table map to the same target table
);
create table configuration_columns
(
id_configuration_columns int,
id_configuration_tables int,
source_column text,
target_column text,
primary key (id_configuration_columns),
foreign key (id_configuration_tables) references configuration_tables (id_configuration_tables)
);
您的示例数据将变为
configuration_tables
id_configuration_tables | source_table | target_table ------------------------+--------------+------------- 1 | STable | TTable 2 | EmpTable | TTable
configuration_columns
id_configuration_columns | id_configuration_tables | source_column | target_column -------------------------+-------------------------+---------------+-------------- 1 | 1 | Name | CName 2 | 1 | Age | CAge 3 | 2 | EId | EmplId
从 SQL Server 2017 开始,您可以使用 STRING_AGG
创建您的查询。在早期版本中,这也可以通过一些 STRING_AGG
仿真来实现,你会很容易地找到机智 Google 或 SO。
select
'select s.' + string_agg (c.source_column + ', t.' + c.target_column, ', ') +
' from ' + t.source_table + ' s' +
' join ' + t.target_table + ' t' +
' on ' + string_agg('t.' + c.target_column + ' = s.' + c.source_column, ' and ') +
';' as query
from configuration_tables t
join configuration_columns c on c.id_configuration_tables = t.id_configuration_tables
group by t.source_table, t.target_table
order by t.source_table, t.target_table;
演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=8866b2485ba9bba92c2391c67bb8cae0