【发布时间】:2012-01-08 03:56:55
【问题描述】:
我整个下午都在努力解决这个问题 - 看起来很简单,但我一定错过了什么!
我有一个返回一些数据的查询,它返回的两列是“PackageWeight”和“PackageGroup”。本质上,我想过滤这些数据,只为每个“PackageGroup”显示一行 - 这应该是“PackageWeight”列中值最高的行。
这看起来很简单,但我无法使用 TOP 1 和 GROUP BY 的组合在 SQL Server 中工作。我一定是错过了什么!
SELECT VendorID, PackageID, PackageWeight, PackageGroup
FROM (SELECT VendorID, COUNT(*) AS qty
FROM VendorServices
GROUP BY VendorID
) cs
JOIN (SELECT PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup, COUNT(*) AS qty
FROM PackageServices
JOIN lookupPackages ON PackageServices.PackageID = lookupPackages.PackageID
GROUP BY PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup
) ps ON cs.qty >= ps.qty
WHERE (SELECT COUNT(*)
FROM VendorServices cs2
JOIN PackageServices ps2 ON cs2.ServiceTypeID = ps2.ServiceID
WHERE cs2.VendorID = cs.VendorID
AND ps2.PackageID = ps.PackageID
) = ps.qty
此查询返回我需要过滤的完整数据集。但是到目前为止我的尝试都失败了:(
非常感谢任何帮助!
编辑 - 感谢下面的贡献者,到目前为止我有以下查询:
with result_cte as
(
SELECT VendorID, PackageID, PackageWeight, PackageGroup,
RANK() over (partition by PackageGroup order by PackageWeight desc) as [rank]
FROM (SELECT VendorID, COUNT(*) AS qty
FROM VendorServices
GROUP BY VendorID
) cs
JOIN (SELECT PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup, COUNT(*) AS qty
FROM PackageServices
JOIN lookupPackages ON PackageServices.PackageID = lookupPackages.PackageID
GROUP BY PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup
) ps ON cs.qty >= ps.qty
WHERE (SELECT COUNT(*)
FROM VendorServices cs2
JOIN PackageServices ps2 ON cs2.ServiceTypeID = ps2.ServiceID
WHERE cs2.VendorID = cs.VendorID
AND ps2.PackageID = ps.PackageID
) = ps.qty
)
select *
from result_cte
WHERE [rank] = 1
ORDER BY VendorID
到目前为止,一切都很好。我仍然会看一下@gbn 建议的 APPLY 运算符,因为这对我来说是新的 - 我仍然需要做一些测试以确保这个查询在 100% 的时间内工作。不过初步迹象很好!
感谢迄今为止做出贡献的所有人。
编辑 2 - 遗憾的是,在使用更多示例数据填充数据库后,此查询无法正常工作。好像漏掉了一些条目。
也许我需要多解释一下这里发生了什么。我的原始查询返回的数据列出了系统中的每个客户,以及派生的 PackageID(由该查询计算)以及在查找表中分配给该包裹的权重和组。
我需要过滤原始结果表,以便我从每个组中为每个客户获得不超过一个包(每个客户可能从一个或多个组中获得一个包,但可能不会从每个组中获得一个包)
明天我会重新审视这个问题,因为我想我可能会处于“只见树木不见森林”的境地!
谢谢大家。
【问题讨论】:
-
您使用的是什么版本的 SQL Server?
-
@JimmE:在这种情况下,我提供的所有链接都是有效的。
-
@gbn - 感谢您的指点。这看起来很简单,但由于某种原因,我很难让它像我期望的那样工作。我之前没有在您的一个示例中遇到过 CROSS APPLY 操作 - 所以我会去看看。非常感谢。
-
@gbn - 是的,你应该看看其中一个链接。在早期版本中,这可能会变得更加棘手。
标签: sql sql-server sql-server-2008 greatest-n-per-group