SQL Server-将一列的值显示在具有新列的单行中

时间:2018-08-24 08:07:49

标签: 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

2 个答案:

答案 0 :(得分:1)

您为什么不尝试查看此中间选择?

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

rank值中有一个答案-每行都是1。这就是为什么仅在数据透视表中的组[1]中填充数据(注意,您定义的max值正确;注意,“字符串”中的最大值不是数字)。

partition by TestValues-partition重新开始对每个TestValues值的排序。 “分区”在这里是指“组”。每个组的排名,每个组的行号等等。如果将分区应用于唯一列,则每一行的rank / rk = 1-因为排名/ rn将针对每一行(每个分区)重新开始。

以下是应用于您的数据集的不同窗口函数的示例:http://sqlfiddle.com/#!18/9eecb/31103

其中之一将满足您的需求。

顺便说一句,“排名”功能有时会为分区中的不同行提供相同的结果。看看dup行的rankrn函数结果之间的区别(请参阅我在sqlfiddle上的评论)。

我会从dbo.Information中采取其他措施,以使测试结果保持正确的顺序。按名称(组中的每个测试都相同)或测试结果(与测试顺序无关)进行排序可能会每次都为相同的参数提供不同的输出,并且由于顺序错误而可能不正确。

答案 1 :(得分:1)

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

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;

别忘了,表中的数据存储在堆中。它没有“固有顺序”。