更新NO 2
通过解决方案1和解决方案2的非常重要的输入,我终于有了一个完全符合它需要的sql。感谢两位用户,感谢他们的帮助。我希望我能将这两个解决方案都标记为答案,但考虑到我的查询基础来自@ papo的解决方案,而且与其他解决方案相比它非常短,我将其标记为我的答案。
最终工作sql
SELECT CNumber, Item, Status
FROM WEBS t1
WHERE ( ((t1.Item IN ('SHIPEXP', 'SHIPPING', 'SHIPINT', 'SHIPBOND', 'GIFT WRAP'))
AND EXISTS (SELECT * FROM WEBS
WHERE CNumber = t1.CNumber
AND ( Status NOT IN (1, 11, 12, 13, 14, 15, 16, 17)
)
)
)
OR
( Status NOT IN (1, 11, 12, 13, 14, 15, 16, 17)
)
)
AND CNumber = 12140836
更新
我有一个最终查询,如下所示:这是我接受的解决方案。这已经过修改,以适应我的表格结构和其他条款。
问题是如前所述在SCENARIO 2上查询失败,即在完成所有项目时不显示结果。场景1成功。
SELECT t.ItemCode
, t.ItemStatus
FROM WEBORDER_STATUS t
WHERE t.CustOrderNumber = 12140799
AND ( ( ( t.ItemCode <> 'SHIPEXP' OR t.ItemCode <> 'SHIPPING' OR t.ItemCode <> 'SHIPINT' OR t.ItemCode <> 'SHIPBOND' OR t.ItemCode <> 'GIFT WRAP'
)
AND ( t.ItemStatus <> 11 AND t.ItemStatus <> 12 AND
t.ItemStatus <> 1 AND t.ItemStatus <> 13 AND
t.ItemStatus <> 14 AND t.ItemStatus <> 15 AND
t.ItemStatus <> 16 AND t.ItemStatus <> 17
)
)
OR
( (t.ItemCode = 'SHIPEXP' OR t.ItemCode = 'SHIPPING' OR t.ItemCode = 'SHIPINT' OR t.ItemCode = 'SHIPBOND' OR t.ItemCode = 'GIFT WRAP')
AND EXISTS
( SELECT 1
FROM WEBORDER_STATUS s
WHERE s.CustOrderNumber = t.CustOrderNumber
AND (t.ItemCode <> 'SHIPEXP' OR t.ItemCode <> 'SHIPPING' OR t.ItemCode <> 'SHIPINT' OR t.ItemCode <> 'SHIPBOND' OR t.ItemCode <> 'GIFT WRAP')
AND ( t.ItemStatus <> 11 OR t.ItemStatus <> 12 OR
t.ItemStatus <> 1 OR t.ItemStatus <> 13 OR
t.ItemStatus <> 14 OR t.ItemStatus <> 15 OR
t.ItemStatus <> 16 OR t.ItemStatus <> 17
)
)
)
)
在sql server上使用标准Tsql编写SQL查询时需要帮助。
我有一种情况需要根据状态从表中选择项目。
订单编号111的行如下:商品代码发货将始终为已完成。
情景1:
ItemCode ----状态
123 ----------- Inprogress
456 ----------- Inprogress
789 -----------已完成
SHIPPING ----已完成
预期结果(排除已完成的商品,但包含送货项目,因为所有订单都有运费)
123 ----------- Inprogress
456 ----------- Inprogress
SHIPPING ----已完成
情景2:
ItemCode ----状态
123 -----------已完成
456 -----------已完成
789 -----------已完成
SHIPPING ----已完成
预期结果(排除已完成的项目,但所有项目均已完成排除SHIPPING)
没有结果(所有项目都已完成)
感谢任何帮助或指示。感谢
答案 0 :(得分:3)
当此订单有未完成的商品时,仅显示SHIPPING行。仅在未完成时显示其他项目。
SELECT OrderNo, ItemCode, Status
FROM table1 t1
WHERE ((ItemCode = 'SHIPPING'
AND EXISTS (SELECT * FROM table1
WHERE OrderNo = t1.OrderNo
AND Status != 'Completed'))
OR Status != 'Completed')
AND OrderNo = 111;
答案 1 :(得分:1)
一种选择是使用EXISTS谓词来测试是否有任何行(除了&#39; SHIPPING&#39;)不是状态&#39;已完成&#39;有条件地退回&#39; SHIPPING&#39;行。
例如:
SELECT t.ItemCode
, t.Status
FROM mytable t
WHERE t.OrderNumber = 111
AND ( ( t.ItemCode <> 'SHIPPING' AND t.Status <> 'Completed'
)
OR ( t.ItemCode = 'SHIPPING' AND EXISTS
( SELECT 1
FROM mytable s
WHERE s.OrderNumber = t.OrderNumber
AND s.ItemCode <> 'SHIPPING'
AND s.Status <> 'Completed'
)
)
)
注意
谓词t.OrderNumber = 111
并非必要。这可以省略,或者是其他任何标准。 (我假设您的查询将其作为谓词,因为您显示的示例省略了OrderNumber列。如果省略该谓词,您可能想要在选择列表中返回OrderNumber。)
此:
( t.ItemCode <> 'SHIPPING' AND t.Status <> 'Completed'
)
获取状态不是已完成的所有未运输的行。 (这可能与第二种情况中的任何行都不匹配。)
此:
( t.ItemCode = 'SHIPPING' AND EXISTS
( SELECT 1
FROM mytable s
WHERE s.OrderNumber = t.OrderNumber
AND s.ItemCode <> 'SHIPPING'
AND s.Status <> 'Completed'
)
)
只有当表格中有另一行时,才会获得SHIPPING行,对于相同的OrderNumber以及“未完成”的状态&#39;。如果子查询返回的行没有,则EXISTS
谓词返回FALSE,因此整个表达式的计算结果为FALSE,因此不会返回SHIPPING行。
添加ORDER BY
子句以获取按特定顺序返回的行。最后获得SHIPPING行,例如
ORDER BY CASE t.ItemCode WHEN 'SHIPPING' THEN 2 ELSE 1 END, t.ItemCode
<强>后续强>
根据您更新的查询,请注意&#34;否定&#34;这个:
(a = 'b' OR a = 'c')
将是:
(a <> 'b' AND a <> 'c')
请注意,OR
需要替换为AND
。例如,如果您通过测试用例,请考虑使用itemCode = 'SHIPEXP'
的行。我们知道如果这是真的,那么itemCode <> 'SHIPPING'
也将成立。
同样,表达式:
( ItemStatus <> 11 OR ItemStatus <> 12 )
对于ItemStatus
的任何非空值,将返回TRUE。 (如果值为11,那么ItemStatus <> 12
将为TRUE。这将导致(FALSE OR TRUE),这将返回TRUE。12
的值也是如此...(TRUE OR FALSE)将返回TRUE。我认为你想要的是返回一个FALSE。为了得到它,谓词需要一起“和”。
我相信这是您在查询中看到的行为的关键所在。当你期望它们返回FALSE时,你的谓词返回TRUE。
在ItemCode
上表达谓词的等效(并且更简洁)方式(以查看值是否与值列表中的一个匹配)将是:
t.ItemCode IN ('SHIPEXP','SHIPPING','SHIPINT','SHIPBOND','GIFT WRAP')
同样,ItemStatus
的检查可表示为:
t.ItemStatus NOT IN (11,12,1,13,14,15,16,17)
请注意,使用NOT IN
时,不等式测试会被“和”在一起而不是“或”。这相当于:
t.ItemStatus <> 11 AND t.itemStatus <> 12 AND ...
答案 2 :(得分:0)
这是您的第一个场景:
SELECT ItemCode, Status FROM Your_Table WHERE Status!= 'Completed' AND ItemCode !='SHIPPING'
对于您的第二个场景,可能需要存储过程或嵌套查询的案例