将所有列与其中的列名连接起来,每行一个字符串

Posted

技术标签:

【中文标题】将所有列与其中的列名连接起来,每行一个字符串【英文标题】:concatenate all columns from with names of columns also in it, one string for every row 【发布时间】:2021-12-24 04:58:32 【问题描述】:
CREATE TABLE myTable 
(
    COL1 int, 
    COL2 varchar(10), 
    COL3 float
)

INSERT INTO myTable
VALUES (1, 'c2r1', NULL), (2, 'c2r2', 2.335)

我想要为表的每一行输出一个包含所有列和名称的字符串。

类似:

COL1=1|COL2=c2r1|COL3=NULL
COL1=2|COL2=c2r2|COL3=2.3335

我有一个包含很多列的表,所以它必须是动态的(它也会在不同的表上使用它),是否有一个简单的解决方案,我可以这样做并选择分隔符和类似的东西......(它还必须处理 NULL 值和数值。)

我正在使用 SQL Server 2019。

【问题讨论】:

你到底为什么想要这样的输出?它违反了关于数据库的一切。 日期怎么样?和日期时间值?如果您想要一个不需要 40 次迭代来捕捉所有问题的可靠答案,您将不得不展示所有潜在的边缘情况。 (但老实说,您应该使用客户端应用程序语言,而不是 T-SQL。) 这个用例是什么?什么会消耗这个单一的连接字符串? 我有来自不同表(人工智能模型,模型不时更改)的数据,我想在使用该特定行时保存这些数据。但之后数据可能会发生一些变化,我想要一种简单的方法来存储数据,以便在必要时检查存储的行是否为最新版本。我不想要一个完美的数据库,我想要一个简单的解决方案。我不在乎违反数据库规则。 COL2'#|COL42=||''NULL' 时的预期结果是什么?您可能想考虑使用 XML 而不是管道分隔的混淆。 【参考方案1】:

既然你是 2019 年,string_agg() 带一点 if JSON

示例

 Select NewVal
  From  MyTable A
  Cross Apply ( Select NewVal = string_agg([key]+'='+isnull(value,'null'),'|')
                 From OpenJson((Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES  )) 
             ) B

结果

NewVal
COL1=1|COL2=c2r1|COL3=null
COL1=2|COL2=c2r2|COL3=2.335000000000000e+000   -- Don't like the float

编辑以捕获浮点数

Select NewVal
  From  MyTable A
  Cross Apply ( Select NewVal = string_agg([key]+'='+isnull(case when value like '%0e+0%' then concat('',convert(decimal(15,3),convert(float,value))) else value end,'null'),'|')
                 From OpenJson((Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES  )) 
             ) B

结果

NewVal
COL1=1|COL2=c2r1|COL3=null
COL1=2|COL2=c2r2|COL3=2.335

【讨论】:

几乎正是我想要的,谢谢!只有浮点有点问题,因为我有很多,所以我会看看如果我能做点什么。但其余的都是完美的,f.e.日期解析得很好,NULL,... @gilberke 您可以嵌入一个案例,其中像 '%0e+0%' 这样的值并转换为小数 @gilberke 请参阅编辑以捕获浮动 我将 '%0e+0%' 更改为 '%e[-+]0%' 以在 e 之后查找 + & -,并删除了第一个 0 以查找所有浮动值细绳。谢谢,现在它就像我想要的那样工作。 (sql server 2019 上的 compatible_level 中的数据库给出了一个错误,这是我遇到的问题。) @gilberke 干得好!【参考方案2】:

有人敢为此滥用json吗?

SELECT REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (ca.js,'":','='), ',"','|'), '"',''), '[','') ,']','') AS data
FROM (SELECT col1 as id FROM myTable) AS list
CROSS APPLY
(
  SELECT t.col1
  , t.col2
  , cast(t.col3 as decimal(16,3)) as col3
  FROM myTable t
  WHERE t.col1 = list.id
  FOR JSON AUTO, INCLUDE_NULL_VALUES
) ca(js)

它可以在交叉应用中使用简单的SELECT t.*。 但是花车往往有点太长了。

【讨论】:

以上是关于将所有列与其中的列名连接起来,每行一个字符串的主要内容,如果未能解决你的问题,请参考以下文章

您可以将一个表中具有另一个表的列名的列与第二个表链接吗

如果字符串数组中的列名在字符串数组中具有匹配的值,则获取DataRow

Python Pandas:将数据框的列与列名合并为一列

MySQL外键+唯一索引

如何用仅包含所有标记的引理的字符串替换列? [关闭]

列名中的特殊字符