sql-server - SQL Server - 将一列的值显示为带有新列的单行

标签 sql-server

我想在单行中显示来自 6 行的特定列的值,6 列用于 6 个值..

实际上,我们有一个列 (TestValues),我们在其中存储 6 个由“##@##”分隔的值。但是我们希望它在 UI 上显示在不同的文本框中,但我们只能在 SQL Server 存储过程中将它们拆分。

使用此查询的当前输出:

SELECT Code,Reason, 
LTRIM(RTRIM(m.n.value('.[1]','varchar(500)'))) AS TestValues
FROM
(
SELECT Code,Reason, CAST('<XMLRoot><RowData>' + REPLACE(TestValues,'##@##','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM dbo.Information where Logged_ID = 1001
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)

enter image description here

期望的输出:

enter image description here

我试过下面的查询,但它不起作用......请让我知道我哪里错了。

select * from 
(   
    select *, rank() over (partition by TestValues order by code) rank from
    (
        SELECT Code,Reason, 
        LTRIM(RTRIM(m.n.value('.[1]','varchar(500)'))) AS TestValues
        FROM
        (
        SELECT Code,Reason, CAST('<XMLRoot><RowData>' + REPLACE(TestValues,'##@##','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
        FROM dbo.Information where Logged_ID = 1001
        )t
        CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)
    ) r
)tab1
pivot
(
max([TestValues]) for rank in ([1],[2],[3],[4],[5],[6])) pv

enter image description here

最佳答案

正如我在评论中所说,目前,由于缺乏标识、排序和标签,您将获得的顺序完全是随机的。因此,您可以使用它,但每次运行查询时结果都会改变:

USE Sandbox;
GO

CREATE TABLE dbo.SampleData(Code varchar(15),
                            Reason varchar(4),
                            testValues varchar(7));
GO
INSERT INTO dbo.SampleData (Code,
                            Reason,
                            testValues)
VALUES ('Phlebotomist','test','12345'),
       ('Phlebotomist','test','23456'),
       ('Phlebotomist','test',''),
       ('Phlebotomist','test','123456'),
       ('Phlebotomist','test','1234567'),
       ('Phlebotomist','test','12345');
GO
WITH RNs AS(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY Code, Reason ORDER BY NEWID()) AS RN --PARTITION BY is a guess, NEWID as order is random as currently stands 
    FROM dbo.SampleData)
SELECT Code, Reason,
       MAX(CASE RN WHEN 1 THEN RNs.testValues END) AS BusinessUnit,
       MAX(CASE RN WHEN 2 THEN RNs.testValues END) AS MainUnit,
       MAX(CASE RN WHEN 3 THEN RNs.testValues END) AS [Location],
       MAX(CASE RN WHEN 4 THEN RNs.testValues END) AS CustID
FROM RNs
GROUP BY Code, Reason;
GO

GO
DROP TABLE dbo.SampleData;

只要条目的顺序始终相同,这很容易修复。添加一个 IDENTITY 列(您可以使用其他内容,但您需要 一些内容 才能确定顺序):

CREATE TABLE dbo.SampleData(SomeID int IDENTITY(1,1), --Something to ORDER BY!
                            Code varchar(15),
                            Reason varchar(4),
                            testValues varchar(7));
GO
INSERT INTO dbo.SampleData (Code,
                            Reason,
                            testValues)
VALUES ('Phlebotomist','test','12345'),
       ('Phlebotomist','test','23456'),
       ('Phlebotomist','test',''),
       ('Phlebotomist','test','123456'),
       ('Phlebotomist','test','1234567'),
       ('Phlebotomist','test','12345');
GO
WITH RNs AS(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY Code, Reason ORDER BY SomeID ASC) AS RN --NOw we have an order we can rely on!
    FROM dbo.SampleData)
SELECT Code, Reason,
       MAX(CASE RN WHEN 1 THEN RNs.testValues END) AS BusinessUnit,
       MAX(CASE RN WHEN 2 THEN RNs.testValues END) AS MainUnit,
       MAX(CASE RN WHEN 3 THEN RNs.testValues END) AS [Location],
       MAX(CASE RN WHEN 4 THEN RNs.testValues END) AS CustID
FROM RNs
GROUP BY Code, Reason;

GO
DROP TABLE dbo.SampleData;

不要忘记,表中的数据存储在堆中。它没有“内在顺序”。

关于sql-server - SQL Server - 将一列的值显示为带有新列的单行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52000066/

相关文章:

c# - 使用 SQL 更新特定行

c# - 通过 SQLCLR 使用 Rest API 并通过 SqlPipe 发送结果

sql-server - SQL Server单元级别加密

sql - 如何返回结果集以及删除

sql-server - SQL 选择两列相等但第三列不同的行

c# - smo 恢复数据库

sql-server - SQL Server 中的 IGNORE_DUP_KEY 选项

sql - 设置AVG结果AS列

sql-server - 通过 ODBC dbWriteTable 上传到 SQL Server 2012 - 错误 "String data, right truncation"列类型 chr 与 nvarchar(50)

c# - 使用用户名和密码连接到 SQL Server