该表在其他字段中包含“Sales_Order_ID”,“Sales_Order_Line_Number”和“Sales_Order_Line_staus”。我想检索'Sales_Order_ID',其中'Sales_Order_ID'的每条记录都具有相同的'Sales_Order_Line_Status'。
因此,如果销售订单X的每条记录都处于“已关闭”状态,那么我想要检索它。如果销售订单Y有三个状态为“已关闭”的记录和一个状态为“已打开”的记录,那么我不想检索它。
我试过了:
SELECT DISTINCT s1.so_ID, s1.SO_line_status
FROM sales_order_table s1
INNER JOIN sales_order_table s2
ON s1.so_id = s2.so_id
AND s1.so_line_status = s2.so_line_status
ORDER BY s1.so_id
没有成功。以下似乎与我想要的相反:
SELECT DISTINCT s1.so_ID, s1.SO_line_status
FROM sales_order_table s1
INNER JOIN sales_order_table s2
ON s1.so_id = s2.so_id
AND s1.so_line_status <> s2.so_line_status
ORDER BY s1.so_id
所以我试过了:
SELECT DISTINCT s1.so_ID, s1.SO_line_status
FROM sales_order_table s1
INNER JOIN sales_order_table s2
ON s1.so_id = s2.so_id
AND NOT s1.so_line_status <> s2.so_line_status
ORDER BY s1.so_id
没有成功。
然后我去了完全noob并改变了连接类型,只是希望它能工作。我是在这里关闭还是以错误的方式完成它?
另外,我意识到上面的查询不会将结果限制为“已关闭”状态,但我想如果我能得到一个只返回所有相同状态行的结果,那么我可以将它们限制为“已关闭”。
对不起,如果不清楚的话!如果是这样,我会尽力澄清。
答案 0 :(得分:5)
SELECT so_ID
FROM sales_order_table
GROUP BY so_ID
HAVING MAX(SO_line_status) = 'Closed' AND
MIN(SO_line_status) = 'Closed' AND
COUNT(CASE WHEN SO_line_status IS NULL THEN 1 END) = 0
如果你的RDBMS支持它,你也可以使用EXCEPT
SELECT so_ID
FROM sales_order_table
WHERE SO_line_status = 'Closed'
EXCEPT
SELECT so_ID
FROM sales_order_table
WHERE SO_line_status IS NULL OR SO_line_status <> 'Closed'
答案 1 :(得分:2)
这里的基本方法是按ID和状态进行分组。如果该分组的计数仅等于ID的计数,那么您将知道所有行具有相同的状态。
SELECT s1.so_ID, s1.SO_line_status
FROM sales_order_table s1
GROUP BY s1.so_ID, s1.SO_Line_status
HAVING COUNT(*) = (SELECT COUNT(*)
FROM sales_order_table s2
WHERE s2.so_ID = s1.so_ID)
将其缩小至“关闭”状态。 status,只需添加一个WHERE子句:
SELECT s1.so_ID, s1.SO_line_status
FROM sales_order_table s1
WHERE s1.SO_line_status = 'closed'
GROUP BY s1.so_ID, s1.SO_Line_status
HAVING COUNT(*) = (SELECT COUNT(*)
FROM sales_order_table s2
WHERE s2.so_ID = s1.so_ID)
答案 2 :(得分:2)
Joe's approach一定能奏效。以下是一些替代方案(可能也可能不会更加优化):
转换问题,过滤掉状态为Open(或!Closed,具体取决于您拥有的状态)的问题:
SELECT T1.Id
FROM Table as T1
LEFT JOIN (SELECT Id FROM Table WHERE Status <> 'Closed') as T2 ON
T1.Id = T2.Id
WHERE T2.Id IS NULL
使用MAX和MIN作为分组功能:
SELECT Id
FROM Table
GROUP BY Id, Status
HAVING MAX(Status) = 'Closed'
使用2个派生表:
SELECT C.Id
FROM (
SELECT Id FROM Table WHERE Status = 'Closed'
) as C
LEFT JOIN (
SELECT Id FROM Table WHERE Status = 'Open'
) as O ON
C.Id = O.Id
WHERE O.Id IS NULL
我怀疑2种LEFT JOIN
方法会优化最佳,然后是MAX
版本,然后是COUNT
- 但是如果性能对您很重要,那么您肯定应该对其进行分析。如果没有性能考虑,我个人会发现2个派生表最具可读性 - 其他人可能不同意。
答案 3 :(得分:1)
您可以使用ALL运算符:
SELECT DISTINCT Sales_Order_ID
FROM sales_order_table t1
WHERE
'Closed' = ALL (
SELECT Sales_Order_Line_Staus
FROM sales_order_table t2
WHERE t1.sales_order_id = t2.sales_order_id
)
用简单的英语:选择那些所有相关行具有相同状态的Sales_Order_ID
,并且该状态恰好为“已关闭”。
如果您想要任何状态,您可以轻松地执行此操作...
SELECT DISTINCT Sales_Order_ID, Sales_Order_Line_Staus
FROM sales_order_table t1
WHERE
Sales_Order_Line_Staus = ALL (
SELECT Sales_Order_Line_Staus
FROM sales_order_table t2
WHERE t1.sales_order_id = t2.sales_order_id
)
......甚至是这个(如果你对实际Sales_Order_Line_Staus
不感兴趣):
SELECT Sales_Order_ID
FROM sales_order_table
GROUP BY Sales_Order_ID
HAVING COUNT(DISTINCT Sales_Order_Line_Staus) = 1