Return 基于当前值的序列中的上一个和下一个值
Return Previous and Next Value in Sequence Based on Current Value
我有以下 table:
CREATE TABLE [opTest]
(
[name] varchar(50),
[task] varchar(50),
[desc] varchar(100),
[seq] varchar(5)
)
INSERT INTO [opTest] VALUES
('Yale', 'Paint', 'Prime Part', '100'),
('Yale', 'Paint', 'Paint Part', '200'),
('Yale', 'Assembly', 'Front Wheel Assembly', '100'),
('Yale', 'Assembly', 'Rear Wheel Assembly', '200'),
('Yale', 'Assembly', 'Chain Assembly', '300'),
('Yale', 'Assembly', 'HUB Assembly', '400'),
('Yale', 'Assembly', 'Final Assembly', '500'),
('Yale', 'CNC Inspection', 'CNC Machine Inspection', '100')
+------+----------------+------------------------+-----+
| name | task | desc | seq |
+------+----------------+------------------------+-----+
| Yale | Paint | Prime Part | 100 |
| Yale | Paint | Paint Part | 200 |
| Yale | Assembly | Front Wheel Assembly | 100 |
| Yale | Assembly | Rear Wheel Assembly | 200 |
| Yale | Assembly | Chain Assembly | 300 |
| Yale | Assembly | HUB Assembly | 400 |
| Yale | Assembly | Final Assembly | 500 |
| Yale | CNC Inspection | CNC Machine Inspection | 100 |
+------+----------------+------------------------+-----+
我想输出序列中上一个、当前和下一个任务的数据。我希望它看起来像这样:
+------+----------------+------------------------+-----------+-----------+-----------+
| Name | Task | Description | Prev Task | Curr Task | Next Task |
+------+----------------+------------------------+-----------+-----------+-----------+
| Yale | Assembly | Front Wheel Assembly | NULL | 100 | 200 |
| Yale | Assembly | Rear Wheel Assembly | 100 | 200 | 300 |
| Yale | Assembly | Chain Assembly | 200 | 300 | 400 |
| Yale | Assembly | HUB Assembly | 300 | 400 | 500 |
| Yale | Assembly | Final Assembly | 400 | 500 | NULL |
| Yale | CNC Inspection | CNC Machine Inspection | NULL | 100 | NULL |
| Yale | Paint | Prime Part | NULL | 100 | 200 |
| Yale | Paint | Paint Part | 100 | 200 | NULL |
+------+----------------+------------------------+-----------+-----------+-----------+
我正在使用以下查询,但我不明白为什么它不起作用。我用一个字段 table 做了一个简单的测试,它成功了。唯一的不同是该字段在我的测试中是 int,但我正在转换为 int,所以这应该不是问题。
SELECT
[Name] AS [Name],
[Task] AS [Task],
[Desc] AS [Description],
(SELECT TOP(1) t1.[Seq]
FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) > CAST([Seq] AS int)
ORDER BY t1.[Seq] ASC) AS [Prev Task],
[Seq] AS [Curr Task],
(SELECT TOP(1) t1.[Seq]
FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) < CAST([Seq] AS int)
ORDER BY t1.[Seq] DESC) AS [Next Task]
FROM
[opTest]
ORDER BY
[Name] ASC, [Task] ASC, [Seq] ASC
那个returns这个结果:
+------+----------------+------------------------+-----------+-----------+-----------+
| Name | Task | Description | Prev Task | Curr Task | Next Task |
+------+----------------+------------------------+-----------+-----------+-----------+
| Yale | Assembly | Front Wheel Assembly | NULL | 100 | NULL |
| Yale | Assembly | Rear Wheel Assembly | NULL | 200 | NULL |
| Yale | Assembly | Chain Assembly | NULL | 300 | NULL |
| Yale | Assembly | HUB Assembly | NULL | 400 | NULL |
| Yale | Assembly | Final Assembly | NULL | 500 | NULL |
| Yale | CNC Inspection | CNC Machine Inspection | NULL | 100 | NULL |
| Yale | Paint | Prime Part | NULL | 100 | NULL |
| Yale | Paint | Paint Part | NULL | 200 | NULL |
+------+----------------+------------------------+-----------+-----------+-----------+
为什么我没有得到上一个和下一个序列?
在您的查询中,您应该使用 table 别名并在所有列名前加上别名。
您的问题是您没有为第二列 [Seq] 指定别名。是来自 t1
还是 [opTest]
? SQL 服务器假定它来自 t1
CAST(t1.[Seq] AS int)
> CAST([Seq] AS int) -- this is from which table ?
要修复您的查询,请向该列添加适当的别名。例如T.[Seq]
SELECT
[Name] AS [Name],
[Task] AS [Task],
[Desc] AS [Description],
( SELECT TOP(1) t1.[Seq] FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) > CAST(T.[Seq] AS int)
ORDER BY t1.[Seq] ASC )
AS [Prev Task],
[Seq] AS [Curr Task],
( SELECT TOP(1) t1.[Seq] FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) < CAST(T.[Seq] AS int)
ORDER BY t1.[Seq] DESC )
AS [Next Task]
FROM [opTest] T
ORDER BY [Name] ASC, [Task] ASC, [Seq] ASC
可以使用LEAD()
或LAG()
,避免使用子查询
我看到两个问题。
首先,在两个子查询中,您将字段 [seq] 与其自身进行比较。您必须在子查询的两个 [seq] 提及中明确说明要比较查询的哪个级别。如果不明确,它只是默认为当前级别。
其次,您只过滤两个子查询中的 [seq]。这意味着它会显示它的前一个或下一个值,而不管它实际上与 [task] 相关。
另外,就像之前的回答提到的那样。为什么不直接使用 LEAD 和 LAG 函数?
我有以下 table:
CREATE TABLE [opTest]
(
[name] varchar(50),
[task] varchar(50),
[desc] varchar(100),
[seq] varchar(5)
)
INSERT INTO [opTest] VALUES
('Yale', 'Paint', 'Prime Part', '100'),
('Yale', 'Paint', 'Paint Part', '200'),
('Yale', 'Assembly', 'Front Wheel Assembly', '100'),
('Yale', 'Assembly', 'Rear Wheel Assembly', '200'),
('Yale', 'Assembly', 'Chain Assembly', '300'),
('Yale', 'Assembly', 'HUB Assembly', '400'),
('Yale', 'Assembly', 'Final Assembly', '500'),
('Yale', 'CNC Inspection', 'CNC Machine Inspection', '100')
+------+----------------+------------------------+-----+
| name | task | desc | seq |
+------+----------------+------------------------+-----+
| Yale | Paint | Prime Part | 100 |
| Yale | Paint | Paint Part | 200 |
| Yale | Assembly | Front Wheel Assembly | 100 |
| Yale | Assembly | Rear Wheel Assembly | 200 |
| Yale | Assembly | Chain Assembly | 300 |
| Yale | Assembly | HUB Assembly | 400 |
| Yale | Assembly | Final Assembly | 500 |
| Yale | CNC Inspection | CNC Machine Inspection | 100 |
+------+----------------+------------------------+-----+
我想输出序列中上一个、当前和下一个任务的数据。我希望它看起来像这样:
+------+----------------+------------------------+-----------+-----------+-----------+
| Name | Task | Description | Prev Task | Curr Task | Next Task |
+------+----------------+------------------------+-----------+-----------+-----------+
| Yale | Assembly | Front Wheel Assembly | NULL | 100 | 200 |
| Yale | Assembly | Rear Wheel Assembly | 100 | 200 | 300 |
| Yale | Assembly | Chain Assembly | 200 | 300 | 400 |
| Yale | Assembly | HUB Assembly | 300 | 400 | 500 |
| Yale | Assembly | Final Assembly | 400 | 500 | NULL |
| Yale | CNC Inspection | CNC Machine Inspection | NULL | 100 | NULL |
| Yale | Paint | Prime Part | NULL | 100 | 200 |
| Yale | Paint | Paint Part | 100 | 200 | NULL |
+------+----------------+------------------------+-----------+-----------+-----------+
我正在使用以下查询,但我不明白为什么它不起作用。我用一个字段 table 做了一个简单的测试,它成功了。唯一的不同是该字段在我的测试中是 int,但我正在转换为 int,所以这应该不是问题。
SELECT
[Name] AS [Name],
[Task] AS [Task],
[Desc] AS [Description],
(SELECT TOP(1) t1.[Seq]
FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) > CAST([Seq] AS int)
ORDER BY t1.[Seq] ASC) AS [Prev Task],
[Seq] AS [Curr Task],
(SELECT TOP(1) t1.[Seq]
FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) < CAST([Seq] AS int)
ORDER BY t1.[Seq] DESC) AS [Next Task]
FROM
[opTest]
ORDER BY
[Name] ASC, [Task] ASC, [Seq] ASC
那个returns这个结果:
+------+----------------+------------------------+-----------+-----------+-----------+
| Name | Task | Description | Prev Task | Curr Task | Next Task |
+------+----------------+------------------------+-----------+-----------+-----------+
| Yale | Assembly | Front Wheel Assembly | NULL | 100 | NULL |
| Yale | Assembly | Rear Wheel Assembly | NULL | 200 | NULL |
| Yale | Assembly | Chain Assembly | NULL | 300 | NULL |
| Yale | Assembly | HUB Assembly | NULL | 400 | NULL |
| Yale | Assembly | Final Assembly | NULL | 500 | NULL |
| Yale | CNC Inspection | CNC Machine Inspection | NULL | 100 | NULL |
| Yale | Paint | Prime Part | NULL | 100 | NULL |
| Yale | Paint | Paint Part | NULL | 200 | NULL |
+------+----------------+------------------------+-----------+-----------+-----------+
为什么我没有得到上一个和下一个序列?
在您的查询中,您应该使用 table 别名并在所有列名前加上别名。
您的问题是您没有为第二列 [Seq] 指定别名。是来自 t1
还是 [opTest]
? SQL 服务器假定它来自 t1
CAST(t1.[Seq] AS int)
> CAST([Seq] AS int) -- this is from which table ?
要修复您的查询,请向该列添加适当的别名。例如T.[Seq]
SELECT
[Name] AS [Name],
[Task] AS [Task],
[Desc] AS [Description],
( SELECT TOP(1) t1.[Seq] FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) > CAST(T.[Seq] AS int)
ORDER BY t1.[Seq] ASC )
AS [Prev Task],
[Seq] AS [Curr Task],
( SELECT TOP(1) t1.[Seq] FROM [opTest] t1
WHERE CAST(t1.[Seq] AS int) < CAST(T.[Seq] AS int)
ORDER BY t1.[Seq] DESC )
AS [Next Task]
FROM [opTest] T
ORDER BY [Name] ASC, [Task] ASC, [Seq] ASC
可以使用LEAD()
或LAG()
,避免使用子查询
我看到两个问题。
首先,在两个子查询中,您将字段 [seq] 与其自身进行比较。您必须在子查询的两个 [seq] 提及中明确说明要比较查询的哪个级别。如果不明确,它只是默认为当前级别。
其次,您只过滤两个子查询中的 [seq]。这意味着它会显示它的前一个或下一个值,而不管它实际上与 [task] 相关。
另外,就像之前的回答提到的那样。为什么不直接使用 LEAD 和 LAG 函数?