我一直被困在一个相当简单的场景中,但即使在我搔了一段时间之后我也找不到解决方案......这就是我所拥有的。
我有2张包含以下数据的表格:
Trip (ID, Status)
30063 SUBMITTED
30066 SUBMITTED
30067 ASSIGNED
30068 SUBMITTED
和
AgentTripAssignment(TripId, AgentId, IsRejected)
30063 5 1
30063 2 0
30066 3 0
30066 4 0
30067 1 0
30067 2 0
30067 3 0
我想做的是:
从行程表中返回行程ID,状态为SUBMITTED,如果其他表中存在行程条目,则在具有1个查询的AgentTripAssignment表中,IsRejected = 1的计数为零(作为新查询....在特定情况下为30066,30068)和
从行程表中返回行程ID,其中状态为SUBMITTED,并且条目存在于AgentTripAssignment表中,其中IsRejected = 1的计数在第二个查询的表中至少出现一次(作为代理拒绝.... 30063 in给定的案例)
其他注意事项是,行程状态保持提交,直到3个座席未分配给行程请求,即当状态变为ASSIGNED时,就像30067一样。
非常感谢任何帮助!
答案 0 :(得分:2)
案例1:提交的旅行,没有“拒绝的”分配
这是在分配上使用左连接来处理给定旅行没有分配的情况。如果被拒绝状态的分配计数不为0,则将其排除。
SELECT t.ID
FROM Trip AS t
LEFT JOIN AgentTripAssignmentx AS at
ON at.TripId = t.ID
WHERE t.Status = 'SUBMITTED'
GROUP BY t.ID
HAVING COUNT(CASE WHEN at.IsRejected = 1 THEN 1 ELSE NULL END) = 0
案例2:提交的旅行,已被拒绝的作业
与上述类似,但使用内部联接,并排除没有拒绝分配的行程。
SELECT t.ID
FROM Trip AS t
JOIN AgentTripAssignmentx AS at
ON at.TripId = t.ID
WHERE t.Status = 'SUBMITTED'
GROUP BY t.ID
HAVING COUNT(CASE WHEN at.IsRejected = 1 THEN 1 ELSE NULL END) > 0
答案 1 :(得分:0)
select a.tripid
from agenttripassignment a
join trip b on a.tripid = b.tripid
where b.status = 'submitted'
group by a.tripid
having max(a.isrejected) = 0
同样以1
答案 2 :(得分:0)
这是一个满足您的第一个项目符号点的示例(在SQL Server语法中)。
我打破了查询以试图解释逻辑。 (前2个表语句是您的数据表样本)
WITH T AS ( -- Sample data
SELECT 30063 AS ID, 'Submitted' as Status
UNION ALL SELECT 30066, 'Submitted'
UNION ALL SELECT 30067, 'Assigned'
UNION ALL SELECT 30068, 'Submitted'
), A AS ( -- Sample data
SELECT 30063 AS ID, 5 AS AgentID, 1 AS IsRejected
UNION ALL SELECT 30063, 2, 0
UNION ALL SELECT 30066, 3, 0
UNION ALL SELECT 30066, 4, 0
UNION ALL SELECT 30067, 1, 0
UNION ALL SELECT 30067, 2, 0
UNION ALL SELECT 30067, 3, 0
), TPres AS ( -- get list of all IDs present in A table.
SELECT DISTINCT A.ID
FROM A
), RejCnt AS ( -- get List of all items with a rejected status
SELECT DISTINCT A.ID
FROM A
WHERE IsRejected=1
)
SELECT T.ID
FROM T
JOIN TPres ON TPres.ID=T.ID -- Filter out where entry for trip is in the other table.
LEFT JOIN RejCnt ON RejCnt.ID=T.ID -- Used to Determine if IsRejected is Zero
WHERE T.Status='Submitted' -- Where status=Submitted
AND RejCnt.ID IS NULL -- Has no rejected entries
答案 3 :(得分:0)
这非常简单地使用半连接(过滤行但不提供数据访问但不会导致重复行的连接)。对于您的第一个请求,这是一个反半连接:
SELECT T.*
FROM
dbo.Trip T
WHERE
T.Status = 'SUBMITTED'
AND NOT EXISTS (
SELECT *
FROM dbo.AgentTripAssignment AT
WHERE
T.ID = AT.TripId
AND AT.IsRejected = 1
)
;
这非常简单地读作,“显示表Trip
中的所有行,其中表AgentTripAssignment
中没有匹配的行(基于ID)IsRejected = 1
”。
对于您的第二个查询,它几乎完全相同,只需将AND NOT EXISTS
更改为EXISTS
:“显示表Trip
中至少有一个匹配行(基于ID)的所有行)表AgentTripAssignment
中存在IsRejected = 1
“。
我更喜欢EXISTS
半连接语法的原因是它通常可以提供更好的性能,具体取决于确切的索引。它还有助于数据库开发人员以我认为有益的方式思考。它还有一个好处,就是不必使用DISTINCT
来修复重复,它可以通过允许你从所需的表中返回所有行来避免聚合方法的问题(当GROUP BY
时必须包含表中的所有列。