我正在查询数据库并检索共享32485 ProjectNumber
的所有列
我需要获得每个ChangeDateTime
的最大orderId
。
数据库表:
OrderID ProjectNumber ChangeDateTime
---------------------------------------------
1 32485 30/11/2018
1 32485 29/11/2018
1 32485 28/11/2018
2 32485 30/09/2017
2 32485 29/09/2017
2 32485 28/09/2017
Desierd Result:
OrderID ProjectNumber ChangeDateTime
---------------------------------------------
1 32485 30/11/2018
2 32485 30/09/2017
到目前为止我尝试了什么(但我并不惊讶它只返回最大ChangeDateTime的1条记录):
SELECT TOP 1
Orders.OrderID,
Changes.ChangeDateTime,
Orders.ProjectNumber
FROM Orders
INNER JOIN Changes ON Changes.ItemID = Orders.OrderID
INNER JOIN LineStatusSettings ON
Cast( LineStatusSettings.LineStatusSettingID as varchar(max)) = Changes.NewValue
INNER JOIN LineStatuses ON LineStatuses.LineStatusID= LineStatusSettings.LineStatusID
INNER JOIN OrderTypes ON OrderTypes.OrderTypeID = LineStatusSettings.OrderTypeID
WHERE Orders.ProjectNumber = 32485 AND Orders.Deleted=0
GROUP BY Orders.OrderID,
Changes.ChangeDateTime,
Orders.ProjectNumber
ORDER BY Changes.ChangeDateTime DESC
答案 0 :(得分:2)
你变得太复杂了。此查询产生所需的输出:
SELECT
Orders.OrderID,
Orders.ProjectNumber,
MAX(Changes.ChangeDateTime)
FROM Orders
INNER JOIN Changes ON Changes.ItemID = Orders.OrderID
WHERE
Orders.ProjectNumber = 32485
GROUP BY
Orders.OrderID,
Orders.ProjectNumber
如果您需要JOIN区域中的其他内容,为了限制考虑输出的行,可以将其添加到
中SELECT
Orders.OrderID,
Orders.ProjectNumber,
MAX(Changes.ChangeDateTime)
FROM Orders
INNER JOIN Changes ON Changes.ItemID = Orders.OrderID
INNER JOIN LineStatusSettings ON Cast( LineStatusSettings.LineStatusSettingID as varchar(max)) = Changes.NewValue
INNER JOIN LineStatuses ON LineStatuses.LineStatusID= LineStatusSettings.LineStatusID
INNER JOIN OrderTypes ON OrderTypes.OrderTypeID = LineStatusSettings.OrderTypeID
WHERE Orders.ProjectNumber = 32485 AND Orders.Deleted=0
GROUP BY
Orders.OrderID,
Orders.ProjectNumber
如果您在输出中添加更多列,并且它们不在某些聚合函数中(min / max / avg / sum / count等),那么您也需要将它们添加到组中,它将会可能会增加行数,因为它增加了唯一值组合的数量
另一种有效获取数据负载的方法,并根据几列选择" TOP x"会是这样的:
SELECT * FROM
(
SELECT
*,
ROW_NUMBER() OVER(PARTITION BY Orders.OrderID, Orders.ProjectNumber ORDER BY Changes.ChangeDateTime DESC) as rown
FROM Orders
INNER JOIN Changes ON Changes.ItemID = Orders.OrderID
INNER JOIN LineStatusSettings ON Cast( LineStatusSettings.LineStatusSettingID as varchar(max)) = Changes.NewValue
INNER JOIN LineStatuses ON LineStatuses.LineStatusID= LineStatusSettings.LineStatusID
INNER JOIN OrderTypes ON OrderTypes.OrderTypeID = LineStatusSettings.OrderTypeID
WHERE Orders.ProjectNumber = 32485 AND Orders.Deleted=0
--ORDER BY Orders.OrderID, Orders.ProjectNumber, Changes.ChangeDateTime DESC
)a
WHERE
a.rown = 1
这不会对数据进行分组,它只是将所有内容连接在一起。然后,ROW_NUBMER子句有效地将数据分解为OrderID / PrijectNumber配对的每个唯一出现的块,并设置一个计数器,从每个配对的最近日期开始,并且增加1.不同的OrderID / ProjectNumber配对原因从1开始计数的计数器。这意味着(OrderID 1,ProjectNumber 1)的行号为1,(OrderID 2,Project 1)编号为1的另一行,(OrderID 1,ProjectNumber 2)编号为1的另一行)
如果你只是孤立地运行子查询,它会更容易看到它是如何工作的。我建议你在isloation中运行时取消注释ORDER BY行,因为它将确保结果以一个顺序显示很容易看到发生了什么(当配对改变时,计数器从1重新开始)
答案 1 :(得分:0)
使用TOP 1 WITH TIES
:
SELECT TOP (1) WITH TIES . . .