我正在尝试实现一个非常简单的路由系统,它允许项目根据相关表的路由信息从一个步骤转到另一个步骤。我的ASP.NET方法应该基于数据库结果进行下一步,以避免任何愚蠢的硬编码值。
有一个表包含活动步骤(所有步骤“要做”或不做,位:1或0),另一个包含已完成的步骤。根据这些信息,我相信我应该能够从包含所有活动步骤的表中选择前1(下一步),其中stepID不在已完成的stepID列表中。
我在纸上尝试了这个并且它有意义,我也尝试从详细查询到大查询,我应该返回下一步(前1)。底层查询工作,但是,我的大查询有问题应该返回前1项(下一步)。我总是收到以下错误:
“消息156,级别15,状态1.关键字附近的语法不正确 '哪里'。消息156,级别15,状态1.关键字附近的语法不正确 '不'。 (第4行)“
表概述如下。
表路线包含要完成的所有步骤(或不是 - > 0)
itemID |routeID |stepID |stepScheduled |
-------|--------|-------|--------------|
1 |1 |10 |1 |
2 |1 |20 |1 |
3 |1 |30 |1 |
4 |1 |40 |1 |
5 |1 |50 |1 |
6 |1 |60 |1 |
7 |1 |70 |1 |
8 |1 |80 |1 |
9 |1 |90 |1 |
10 |1 |100 |1 |
----------------------------------------
包含已完成步骤的 Steps_Completed (如果此项尚未完成任何步骤,则可能为空)。
completionID |sampleID |stepID |userName |completionDT |stationID |
-------------|---------|-------|---------|--------------------|--------------|
1 |1 |10 |Me |2017-12-28 10:04:41 |workstation 1 |
------------------------------------------------------------------------------
查询我正在尝试返回上面提到的错误消息:
SELECT TOP 1 stepID FROM
(SELECT [stepID] **Routes** WHERE [routeID] = 1 AND [stepScheduled] = 1)
WHERE stepID NOT IN (SELECT stepID FROM **Steps_Completed** WHERE sampleID =
1);
()中的子查询在单独执行时起作用并返回预期值:
(从路线选择[stepID] WHERE [routeID] = 1 AND [stepScheduled] = 1) 返回第一个表中显示的所有行(所有“要做”)
(SELECT stepID FROM Steps_Completed WHERE sampleID = 1) 返回已完成的所有行,如果尚未记录任何内容,则返回空结果。
想法是对“路线”列表进行基本的“减法”,“减去”已完成的步骤,然后选择剩余列表的前1项。由于stepID列表可以由ASC订购,因此前1项应该是我的结果。
问题似乎与“WHERE stepID NOT IN”部分有关。
答案 0 :(得分:0)
以下是您当前查询的即时修复:
SELECT TOP 1 [stepID]
FROM Routes
WHERE
[routeID] = 1 AND
[stepScheduled] = 1 AND
[stepID] NOT IN (SELECT stepID FROM Steps_Completed WHERE sampleID = 1)
ORDER BY
[stepID];
另一种表达方法是使用左连接:
SELECT TOP 1 r.stepID
FROM Routes r
LEFT JOIN Steps_Completed s
ON r.routeID = s.sampleID AND
r.stepID = s.stepID
WHERE
r.routeID = 1 AND
r.stepScheduled = 1 AND
s.sampleID IS NULL
ORDER BY
r.stepID;
此处需要注意的一点是,我们通常必须使用ORDER BY
和TOP
。否则," top"没有很好地定义,因为SQL表没有内部顺序。另外,我认为你不一定要在这里使用子查询,所以我已将其删除了。
答案 1 :(得分:0)
使用别名:
SELECT TOP 1 stepID FROM
(SELECT [stepID] from Routes WHERE [routeID] = 1 AND [stepScheduled] = 1) as a
WHERE stepID NOT IN (SELECT stepID FROM Steps_Completed WHERE sampleID =
1);
答案 2 :(得分:0)
SELECT stepID
FROM Routes
WHERE stepID = (SELECT MIN(stepId)
FROM Routes r
LEFT JOIN Steps_Completed sc
ON r.stepID = sc.stepID
WHERE [routeID] = 1
AND [stepScheduled] = 1
AND sc.stepID is null)