根据ID更新不同值的多行

时间:2018-12-12 12:12:09

标签: sql sql-server

我有一个名为Todo的表。它包含一个ID列表和一个为NULL的completedDate字段。还有其他一些列,但此处未使用。

然后我有一个查询,该查询返回以下数据: data

查询来自同一表,如下所示...

SELECT Todo.id, MIN(CloudCall.CloudCallHistory.CallStarted)
FROM Todo 
JOIN CloudCall.CloudCallHistory ON CloudCall.CloudCallHistory.ObjectId = Todo.foreignId
JOIN CloudCall.CloudCallNotebookTypeCategoryLink ON CloudCall.CloudCallNotebookTypeCategoryLink.CategoryCode = CloudCall.CloudCallHistory.CategoryId
JOIN NotebookTypes ON NotebookTypes.NotebookTypeId = CloudCall.CloudCallNotebookTypeCategoryLink.NotebookTypeId
WHERE CloudCall.CloudCallHistory.CallStarted > Todo.foreignDate 
    AND Todo.completedDate IS NULL 
    AND Todo.cancelledDate IS NULL
    AND NotebookTypes.NotebookFolderId = 175
    AND CloudCall.CloudCallHistory.CategoryId != 17427
GROUP BY Todo.id

所以我要做的是用ID匹配的新日期更新Todo表。反正有1个查询可以做到这一点吗?

可能看起来像这样吗?:

UPDATE Todo
SET completedDate... (SELECT...)
WHERE id = ?

其中,select将是返回图像中显示的数据的查询。谢谢

4 个答案:

答案 0 :(得分:1)

类似这样的东西

UPDATE Todo
SET completedDate = o.otherDate
FROM Todo t
INNER JOIN (SELECT otherDate, id FROM otherTable) AS o ON t.id = o.id

更新

要针对收集日期的查询进行联接:

UPDATE Todo
SET completedDate = o.min_date
FROM Todo t
JOIN (SELECT Todo.id, MIN(CloudCall.CloudCallHistory.CallStarted) AS min_date
      FROM Todo 
      JOIN CloudCall.CloudCallHistory ON CloudCall.CloudCallHistory.ObjectId = Todo.foreignId
      JOIN CloudCall.CloudCallNotebookTypeCategoryLink ON CloudCall.CloudCallNotebookTypeCategoryLink.CategoryCode = CloudCall.CloudCallHistory.CategoryId
      JOIN NotebookTypes ON NotebookTypes.NotebookTypeId = CloudCall.CloudCallNotebookTypeCategoryLink.NotebookTypeId
      WHERE CloudCall.CloudCallHistory.CallStarted > Todo.foreignDate 
        AND Todo.completedDate IS NULL 
        AND Todo.cancelledDate IS NULL
        AND NotebookTypes.NotebookFolderId = 175
        AND CloudCall.CloudCallHistory.CategoryId != 17427
      GROUP BY Todo.id) AS o ON o.id = t.id

答案 1 :(得分:1)

为此只需使用JOIN

UPDATE t1 
SET t1.completedDate = t2.[Column]
FROM dbo.ToDo AS t1
INNER JOIN dbo.Table2 AS t2
ON t1.CommonField = t2.[Common Field]
WHERE t1.id in (...);

答案 2 :(得分:0)

尝试一下:

UPDATE Todo SET completedDate=CloudCall.CloudCallHistory.CallStarted   
FROM Todo 
JOIN CloudCall.CloudCallHistory ON CloudCall.CloudCallHistory.ObjectId = Todo.foreignId
JOIN CloudCall.CloudCallNotebookTypeCategoryLink ON 
CloudCall.CloudCallNotebookTypeCategoryLink.CategoryCode = 
CloudCall.CloudCallHistory.CategoryId 
JOIN NotebookTypes ON    
NotebookTypes.NotebookTypeId = CloudCall.CloudCallNotebookTypeCategoryLink.NotebookTypeId 
WHERE    
CloudCall.CloudCallHistory.CallStarted > Todo.foreignDate     AND 
Todo.completedDate IS NULL     AND Todo.cancelledDate IS NULL    AND 
NotebookTypes.NotebookFolderId = 175    AND 
CloudCall.CloudCallHistory.CategoryId != 17427
   GROUP BY Todo.id

答案 3 :(得分:0)

请使用别名,使查询可读,而无需水平滚动八页。

由于要处理聚合数据,因此需要使用SQL Server专有的UPDATE FROM语法的变体:

;WITH aggData AS
(
    SELECT Todo.id, MinStart = MIN(ch.CallStarted)
    FROM Todo 
    INNER JOIN CloudCall.CloudCallHistory AS ch
      ON ch.ObjectId = Todo.foreignId
    INNER JOIN CloudCall.CloudCallNotebookTypeCategoryLink AS cl
      ON cl.CategoryCode = ch.CategoryId
    INNER JOIN NotebookTypes AS nt
      ON nt.NotebookTypeId = cl.NotebookTypeId
    WHERE ch.CallStarted > Todo.foreignDate 
        AND Todo.completedDate IS NULL 
        AND Todo.cancelledDate IS NULL
        AND nt.NotebookFolderId = 175
        AND ch.CategoryId <> 17427
    GROUP BY Todo.id
)
UPDATE t SET completedDate = aggData.MinStart
FROM Todo AS t
INNER JOIN aggData 
ON t.id = aggData.id;

您可以简化此过程,以使Todo仅被读取一次,但是让我们从不会彻底重写整个查询的内容开始。