基于SQL结果将行添加到结果集

时间:2017-07-27 17:15:00

标签: sql sql-server tsql resultset

我有一个表格,其中包含多个项目的处理清单。我想根据当前序列号向结果中添加行,并在新行中添加相关的进程名称,例如:

项目代码序列流程

ABC-1 10 分散

ABC-1 15 等待

ABC-1 20 Grind

ABC-1 30 混合

每个当前结果行应创建3个附加行(在现有序列号之前1和2之后),例如:

商品顺序流程

ABC-1 09 分散 - 加载

ABC-1 10 分散 - 过程

ABC-1 11 分散 - 等待

ABC-1 12 分散 - 空

ABC-1 14 保留 - 加载

ABC-1 15 暂停 - 处理

ABC-1 16 保留 - 等待

ABC-1 17 保留 - 清空

ABC-1 19 研磨 - 加载

ABC-1 20 研磨 - 过程

ABC-1 21 研磨 - 等待

ABC-1 22 研磨 - 空

ABC-1 29 混合 - 加载

ABC-1 30 混合 - 过程

ABC-1 31 混合 - 等待

ABC-1 32 混合 - 空

如图所示,我还希望能够处理Process列的值(其中Load足以满足前一行,进程后缀为现有行,wait后缀为下一行,空后缀为后行)

这样的事情是否可以以优雅的方式进行?我是一个相对的新手。非常感谢任何提示。

M:)

3 个答案:

答案 0 :(得分:0)

是的,虽然需要分多步完成。我会在4点做。

首先,您需要进行更新,只需将“ - 处理”添加到现有的Process值。

然后我会做3次INSERT。每行要添加一个相关行。对于现在包含“ - Process”的每一行,请插入一个具有相同Item值的行,一个Sequence值,即当前值-1 / + 1 / + 2和当前{ {1}} value,REPLACE()' - 使用' - 加载'等处理'

编辑:我刚刚注意到您正在修改结果集而不是更改表中的数据。在这种情况下,您可以首先将当前结果集插入表变量,然后对表变量执行上述步骤,并以表变量中的SELECT结束。

如果你想要一个SELECT,你可以用4个CTE的UNION ALL替换所有上述步骤,但我怀疑它会带来很多性能上的好处,并且它会使更复杂的查询得以维护。

答案 1 :(得分:0)

生产并不算太糟糕。获取样本数据并将其转换为表变量是我们需要开始的地方。我将名称从Sequence更改为MySequence,因为最好不要为对象或列名使用保留字。

declare @Something table
(
    ItemCode varchar(10)
    , MySequence int
    , Process varchar(10)
)
insert @Something
values
('ABC-1', 10, 'Disperse')
,('ABC-1', 15, 'Hold')
,('ABC-1', 20, 'Grind')
,('ABC-1', 30, 'Mix')

现在我们有了一个包含数据的表,使用表值构造函数为您的值构建表非常容易。

select s.ItemCode
    , MySequence = s.MySequence + x.Multiplier
    , Process = s.Process + ' - ' + x.ProcessExtension
from @Something s
cross apply
(
    values
    (-1, 'Load')
    , (0, 'Process')
    , (1, 'Wait')
    , (2, 'Empty')
)x(Multiplier, ProcessExtension)

答案 2 :(得分:0)

这看起来好像产生了预期的效果......

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    ItemCode CHAR(5) NOT NULL,
    Sequense INT NOT NULL,
    Process VARCHAR(20) NOT NULL 
    );
INSERT #TestData (ItemCode, Sequense, Process) VALUES
    ('ABC-1', 10, 'Disperse'),
    ('ABC-1', 15, 'Hold'),
    ('ABC-1', 20, 'Grind'),
    ('ABC-1', 30, 'Mix');

--==================================================

SELECT 
    td.ItemCode, 
    s.Sequense, 
    Process = CONCAT(td.Process, ' - ', s.Process)
FROM
    #TestData td
    CROSS APPLY ( VALUES    
                        (td.Sequense - 1, 'Load'),
                        (td.Sequense, 'Process'),
                        (td.Sequense + 1, 'Wait')
                    ) s (Sequense, Process);