我想要加入两个表。第一个表名为WorkItem
:
第二个表格是WorkItem_Schedule
:
我希望将第一个加入行ActualEndDate IS NULL
。
如果是WorkItemId 3,我只想在WorkItemScheduleId 95上加入它。只有第一行!
我尝试了这个SQL语句,但我遇到了麻烦:
SELECT
W.WorkItemId
,MIN(WS.WorkItemScheduleId) test
,W.WorkItemName
,WS.[PhaseName]
,WS.[StartDate]
,WS.[EndDate]
,WS.[ActualStartDate]
,WS.[ActualEndDate]
FROM
WorkItem W
INNER JOIN
WorkItem_Schedule WS ON W.WorkItemId = WS.WorkItemId
WHERE
WS.ActualEndDate IS NULL
GROUP BY
W.WorkItemId;
我收到错误
列'WorkItem.WorkItemName'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
我谷歌这个错误,发现我需要在选择列表中添加其他列来分组,所以我尝试了这个sql,但它返回所有的时间表而不是不同的workitemid:
SELECT
W.WorkItemId
,MIN(WS.WorkItemScheduleId) test
,W.WorkItemName
,WS.[PhaseName]
,WS.[StartDate]
,WS.[EndDate]
,WS.[ActualStartDate]
,WS.[ActualEndDate]
FROM
WorkItem W
INNER JOIN
WorkItem_Schedule WS ON W.WorkItemId = WS.WorkItemId
WHERE
WS.ActualEndDate IS NULL
GROUP BY
W.WorkItemId, WS.PhaseName, WS.StartDate, WS.EndDate, WS.ActualStartDate, WS.ActualEndDate;
请帮忙!提前致谢!
答案 0 :(得分:2)
您可以使用ROW_NUMBER()
函数获取“第一个”加入的行。
SELECT * FROM (
SELECT
W.WorkItemId
,WS.WorkItemScheduleId
,CASE WHEN WS.ActualEndDate IS NULL
THEN ROW_NUMBER() OVER (PARTITION BY W.WorkItemId ORDER BY WorkItemScheduleId) --ROW_NUMBER() only invoked when the ActualEndDate IS NULL
ELSE -1 END AS ROWN
,W.WorkItemName
,WS.[PhaseName]
,WS.[StartDate]
,WS.[EndDate]
,WS.[ActualStartDate]
,WS.[ActualEndDate]
FROM WorkItem W
INNER JOIN WorkItem_Schedule WS
ON W.WorkItemId = WS.WorkItemId
GROUP BY W.WorkItemId, WS.PhaseName, WS.StartDate, WS.EndDate, WS.ActualStartDate, WS.ActualEndDate) A
WHERE ROWN = 1 --Getting the "first" instance
答案 1 :(得分:1)
试试这个:
SELECT
W.WorkItemId
,W.WorkItemName
,WS.[PhaseName]
,WS.[StartDate]
,WS.[EndDate]
,WS.[ActualStartDate]
,WS.[ActualEndDate]
FROM WorkItem W
JOIN WorkItem_Schedule WS
ON W.WorkItemId = WS.WorkItemId
WHERE WS.ActualEndDate IS NULL
AND NOT EXISTS(
SELECT 'PREVIOUS'
FROM WorkItem_Schedule WS2
WHERE W2.WorkItemId = WS.WorkItemId
AND WS2.StartDate < WS.StartDate
AND WS2.ActualEndDate IS NULL
)
答案 2 :(得分:1)
加入一系列值的特定行相对容易,并且不涉及任何花哨的技巧。首先,一个简单的连接将显示所有候选行。如您所见,您完成了80%的查询:
SELECT
W.WorkItemId
,WS.WorkItemScheduleId
,W.WorkItemName
,WS.[PhaseName]
,WS.[StartDate]
,WS.[EndDate]
,WS.[ActualStartDate]
,WS.[ActualEndDate]
FROM
WorkItem W
INNER JOIN
WorkItem_Schedule WS
ON W.WorkItemId = WS.WorkItemId
WHERE
WS.ActualEndDate IS NULL
这为您提供了您想要的行以及其他行。现在只过滤掉你不想要的那些。你想要的那个拥有最小(最早)的日期。精细。选择该日期:
...
WHERE
WS.ActualEndDate IS NULL
and WS.StartDate =(
select Min( StartDate )
from WorkItem_Schedule
where WorkItemId = W.WorkItemId
and ActualEndDate is NULL );
不要让子查询抛弃你。如果您的表被正确编入索引,它将仅使用索引搜索找到您的行。
答案 3 :(得分:0)
cross apply
可能是最简单的方法:
select w.*, ws.*
from WorkItem w cross apply
(select top 1 ws.*
from WorkItem_Schedule ws
where ws.WorkItemId = w.WorkItemId and
ws.ActualEndDate is null
order by ws.WorkItemScheduleId
) ws;
首先&#34;我假设你指的是WorkItemScheduleId
最小的那个。