我有一张表格可以跟踪用户的姓名,他们所属的群组,他们正在处理的作业以及他们获得该作业的日期:
如果用户只被赋予作业1,那么他们就在A组,我需要检索他们的所有记录。
如果某个用户被赋予了作业2,那么他们就在B组中,我需要从他们第一次获得作业2时检索所有记录,包括:
所以用户1,2和3很容易 - 我需要他们所有的记录。
但是用户4是挑战。我需要第11行的用户4的所有记录,当他们第一次给第2行时,到第13行。看起来这对我来说应该很容易,但我无法弄明白。< / p>
如何编写一个获取MAX(日期)值的查询,该列出现在一列中,按另一列(在本例中为User Name)分组,并为该用户选择包含MAX的所有记录(日期) )以及随后的所有日期?
我试过这种方法:
SELECT *
FROM Table1 t1
WHERE ExecutedDate >= (SELECT MIN(t2.ExecutedDate)
FROM Table1 t2
WHERE t1.UserName = t2.UserName
AND t2.Group = 'A'
OR (t2.Group = 'B' AND t2.Assignment = 'Assignment 2'
GROUP BY t2.UserName
)
AND t1.Group = 'A'
OR (t1.Group = 'B' AND t1.Assignment = 'Assignment 2')
但是我得到的错误是子查询返回了多个值,这在使用=,&gt;,&lt;,&gt; =,=&lt;时是不允许的,或者子查询用作表达式。
我理解错误消息,虽然我无法弄清楚我的子查询如何返回多个值。如果有人可以向我解释,那也会有所帮助。
答案 0 :(得分:0)
你可以试试这个:
WITH DataSource AS
(
SELECT UserName
,MIN(CASE WHEN [Group] = 'A' THEN 1 ELSE 0 END) AS [HasOnlyAGroup]
,MIN(CASE WHEN [Group] = 'B' THEN 1 ELSE 0 END) AS [HasOnlyBGroup]
,MIN(CASE WHEN [Group] = 'B' THEN [ExecutedDate] ELSE NULL END) AS [FirstExecutionInBGroup]
FROM Table1
GROUP BY UserName
)
SELECT *
FROM DataSource DS
OUTER APPLY
(
-- for users, that has assigments from each group, we need to get the ID of the first assigment of group B
SELECT TOP 1 [Row]
FROM Table1 TMin
WHERE DS.[UserName] = Tmin.[UserName]
AND DS.[FirstExecutionInBGroup] = Tmin.[ExecutedDate]
AND DS.[HasOnlyAGroup] = 0
AND DS.[HasOnlyBGroup] = 0
ORDER BY Tmin.[ExecutedDate] ASC
) MinID
INNER JOIN Table1 T1
ON DS.[UserName] = T1.[UserName]
AND
(
-- case 1: user has only A group assigments - show all rows
(
DS.[HasOnlyAGroup] = 1 AND DS.[HasOnlyBGroup] = 0
)
-- case 2: user has only B group assigments - retrieve rows from the first time that they were given assignment 2
OR
(
DS.[HasOnlyAGroup] = 0 AND DS.[HasOnlyBGroup] = 1
AND
DS.[FirstExecutionInBGroup] <= T1.[ExecutedDate]
)
-- case 3:
OR
(
MinID.[RowID] <= T1.[RowID]
)
);
查询可能需要进行一些更改,但我们的想法是使用CTE
来检查用户是否只有A或B组分配(或两者)。我们也是他们B分配的第一个日期。然后在OUTER APPLY
中,我们使用[Row]
日期值获得最小[FirstExecutionInBGroup]
值。之后,我们拥有执行业务逻辑所需的所有值。