我坚持使用左下表结构(SQL Server 2012)来创建一个视图或函数,它将在屏幕截图中输出正确的表:
TestOutput 表包含每个 ID 以 RowNumber 10 (Step0_Name1)开头的数据。在真实场景中,有比我在此处列出的步骤更多的步骤。
我希望有一些逻辑可以通过名称/数字识别或行编号将所有对写成lke Step0_Name1 和 Step0_Name1_Status 。
我猜测将需要游标来创建某种循环逻辑。
不幸的是,sqlfiddle.com抛出错误,所以我在这里粘贴了架构:
创建测试:
CREATE TABLE [dbo].[Test](
[ID] [nchar](5) NOT NULL,
[Version] [smallint] NOT NULL,
[RowNumber] [int] NOT NULL,
[COLUMN1] [nvarchar](max) NULL,
[COLUMN2] [nvarchar](max) NULL,
[COLUMN3] [nvarchar](max) NULL,
[COLUMN4] [numeric](15, 3) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
( [ID] ASC,
[RowNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
插入测试:
INSERT INTO [dbo].[Test]
([ID] ,[Version] ,[RowNumber],[COLUMN1],[COLUMN2],[COLUMN3],[COLUMN4])
Values
('00010',1, 1, 'Sheet', 'Part', 'A', NULL),
('00010',1, 2, 'Sheet', 'Name', 'PartName', NULL),
('00010',1, 3, 'Sheet', 'Price', NULL, 1.470),
('00010',1, 4, 'Sheet', 'Step0_SOP', '2015 CW 09', NULL),
('00010',1, 5, 'Sheet', 'Step1_SOP', '2015 CW 10', NULL),
('00010',1, 6, 'Sheet', 'Step2_SOP', '2015 CW 11', NULL),
('00010',1, 7, 'Sheet', 'Step0_Status', 'pending', NULL),
('00010',1, 8, 'Sheet', 'Step1_Status', 'frozen', NULL),
('00010',1, 9, 'Sheet', 'Step2_Status', 'released', NULL),
('00010',1, 10,'Sheet', 'Step0_Name1', 'Auser', NULL),
('00010',1, 11,'Sheet', 'Step0_Name2', NULL, NULL),
('00010',1, 12,'Sheet', 'Step0_Name3', 'Buser', NULL),
('00010',1, 13,'Sheet', 'Step0_Name1_Status','started', NULL),
('00010',1, 14,'Sheet', 'Step0_Name2_Status',NULL, NULL),
('00010',1, 15,'Sheet', 'Step0_Name3_Status','pending', NULL),
('00010',1, 16,'Sheet', 'Step1_Name1', 'Wuser', NULL),
('00010',1, 17,'Sheet', 'Step1_Name2', 'Cuser', NULL),
('00010',1, 18,'Sheet', 'Step1_Name3', 'Duser', NULL),
('00010',1, 19,'Sheet', 'Step1_Name1_Status','released', NULL),
('00010',1, 20,'Sheet', 'Step1_Name2_Status','pending', NULL),
('00010',1, 21,'Sheet', 'Step1_Name3_Status','released', NULL),
('00020',1, 1, 'Sheet', 'Part', 'B', NULL),
('00020',1, 2, 'Sheet', 'Name', 'PartName', NULL),
('00020',1, 3, 'Sheet', 'Price', NULL, 2.190),
('00020',1, 4, 'Sheet', 'Step0_SOP', '2016 CW 19', NULL),
('00020',1, 5, 'Sheet', 'Step1_SOP', '2016 CW 20', NULL),
('00020',1, 6, 'Sheet', 'Step2_SOP', '2015 CW 21', NULL),
('00020',1, 7, 'Sheet', 'Step0_Status', 'released', NULL),
('00020',1, 8, 'Sheet', 'Step1_Status', 'frozen', NULL),
('00020',1, 9, 'Sheet', 'Step2_Status', 'pending', NULL),
('00020',1, 10,'Sheet', 'Step0_Name1', 'Xuser', NULL),
('00020',1, 11,'Sheet', 'Step0_Name2', NULL, NULL),
('00020',1, 12,'Sheet', 'Step0_Name3', 'Wuser', NULL),
('00020',1, 13,'Sheet', 'Step0_Name1_Status','started', NULL),
('00020',1, 14,'Sheet', 'Step0_Name2_Status',NULL, NULL),
('00020',1, 15,'Sheet', 'Step0_Name3_Status','pending', NULL),
('00020',1, 16,'Sheet', 'Step1_Name1', 'Auser', NULL),
('00020',1, 17,'Sheet', 'Step1_Name2', 'Cuser', NULL),
('00020',1, 18,'Sheet', 'Step1_Name3', 'Buser', NULL),
('00020',1, 19,'Sheet', 'Step1_Name1_Status','frozen', NULL),
('00020',1, 20,'Sheet', 'Step1_Name2_Status','pending', NULL),
('00020',1, 21,'Sheet', 'Step1_Name3_Status','released', NULL)
创建TestOutput:
CREATE TABLE [dbo].[TestOutput](
[ID] [nchar](5) NOT NULL,
[StepCount] [int] NULL
[StepNo] [int] NULL,
[Name] [nvarchar](max) NULL,
[Status] [nvarchar](max) NULL
)
插入TestOutput:
INSERT INTO [dbo].[TestOutput] ([ID] ,[StepCount] ,[StepNo],[Name],[Status])
Values
('00010',1, 0, 'Auser', 'started'),
('00010',2, 0, NULL, NULL),
('00010',3, 0, 'Buser', 'pending'),
('00010',1, 1, 'Wuser', 'released'),
('00010',2, 1, 'Cuser', 'pending'),
('00010',3, 1, 'Duser', 'released'),
('00020',1, 0, 'Xuser', 'started'),
('00020',2, 0, NULL, NULL),
('00020',3, 0, 'Wuser', 'pending'),
('00020',1, 1, 'Auser', 'frozen'),
('00020',2, 1, 'Cuser', 'pending'),
('00020',3, 1, 'Buser', 'released')
我希望你能告诉我如何解决这个问题。
非常感谢。
答案 0 :(得分:1)
试试这个:
select
t.id
,row_number() over(
partition by t.id,
substring(t.column2, 1, charindex('_', t.column2))
order by t.column2
) StepCount
,substring(t.column2, 5, charindex('_', t.column2) - 5) [StepNo]
,t.column3 [Name]
,(
select
t1.column3
from
@test t1
where
t.column2 + '_Status' = t1.column2
and t1.id = t.id
) [Status]
from
@test t
where
t.column2 like 'step[0-9]_name[0-9]'
;
答案 1 :(得分:1)
不需要光标。
您可以先获取StepNo
,然后使用窗口函数计算StepCount
并加入结果:
SELECT s1.ID,
s1.StepCount,
s1.StepNo,
[Name] = s1.Column3,
[Status] = s2.Column3
FROM (SELECT *,
[StepCount] = ROW_NUMBER() OVER (PARTITION BY ID, StepNo ORDER BY RowNumber)
FROM (SELECT *,
[StepNo] = SUBSTRING(Column2, 5, CHARINDEX('_', Column2)-5)
FROM Test
WHERE Column2 LIKE 'Step%_Name%'
AND Column2 NOT LIKE '%Status') AS sub) AS s1
JOIN (SELECT *,
[StepCount] = ROW_NUMBER() OVER (PARTITION BY ID, StepNo ORDER BY RowNumber)
FROM (SELECT *,
[StepNo] = SUBSTRING(Column2, 5, CHARINDEX('_', Column2)-5)
FROM Test
WHERE Column2 LIKE 'Step%_Name%_Status') AS sub) AS s2
ON s1.ID = s2.ID
AND s1.StepCount = s2.StepCount
AND s1.StepNo = s2.StepNo
ORDER BY ID, StepNo, StepCount;
的 LiveDemo
强>
输出:
╔═══════╦═══════════╦════════╦═══════╦══════════╗
║ ID ║ StepCount ║ StepNo ║ Name ║ Status ║
╠═══════╬═══════════╬════════╬═══════╬══════════╣
║ 00010 ║ 1 ║ 0 ║ Auser ║ started ║
║ 00010 ║ 2 ║ 0 ║ ║ ║
║ 00010 ║ 3 ║ 0 ║ Buser ║ pending ║
║ 00010 ║ 1 ║ 1 ║ Wuser ║ released ║
║ 00010 ║ 2 ║ 1 ║ Cuser ║ pending ║
║ 00010 ║ 3 ║ 1 ║ Duser ║ released ║
║ 00020 ║ 1 ║ 0 ║ Xuser ║ started ║
║ 00020 ║ 2 ║ 0 ║ ║ ║
║ 00020 ║ 3 ║ 0 ║ Wuser ║ pending ║
║ 00020 ║ 1 ║ 1 ║ Auser ║ frozen ║
║ 00020 ║ 2 ║ 1 ║ Cuser ║ pending ║
║ 00020 ║ 3 ║ 1 ║ Buser ║ released ║
╚═══════╩═══════════╩════════╩═══════╩══════════╝
与CTE相同:
;WITH cte_name AS
(
SELECT *,
[StepCount] = ROW_NUMBER() OVER (PARTITION BY ID, StepNo ORDER BY RowNumber)
FROM (SELECT *,
[StepNo] = SUBSTRING(Column2, 5, CHARINDEX('_', Column2)-5)
FROM #Test
WHERE Column2 LIKE 'Step%_Name%'
AND Column2 NOT LIKE '%Status') AS sub
), cte_status AS
(
SELECT *,
[StepCount] = ROW_NUMBER() OVER (PARTITION BY ID, StepNo ORDER BY RowNumber)
FROM (SELECT *,
[StepNo] = SUBSTRING(Column2, 5, CHARINDEX('_', Column2)-5)
FROM #Test
WHERE Column2 LIKE 'Step%_Name%_Status') AS sub
)
SELECT s1.ID,
s1.StepCount,
s1.StepNo,
[Name] = s1.Column3,
[Status] = s2.Column3
FROM cte_name s1
JOIN cte_status s2
ON s1.ID = s2.ID
AND s1.StepCount = s2.StepCount
AND s1.StepNo = s2.StepNo
ORDER BY ID, StepNo, StepCount;