SQL Server rand() 聚合
Posted
技术标签:
【中文标题】SQL Server rand() 聚合【英文标题】:SQL Server rand() aggregate 【发布时间】:2010-09-26 03:58:15 【问题描述】:问题:一个坐标 lat/lngs 表。两行可能具有相同的坐标。我们想要一个返回一组具有唯一坐标的行(在返回的集合内)的查询。请注意,distinct
不可用,因为我需要返回根据定义不同的 id 列。这类作品(@maxcount
是我们需要的行数,intid
是唯一的 int id 列):
select top (@maxcount) max(intid)
from Documents d
group by d.geoLng, d.geoLat
不幸的是,对于给定的坐标,它总是会返回同一行,这对我的使用来说有点遗憾。如果我们有一个 rand()
聚合,我们可以使用而不是 max()
...请注意,您不能将 max()
与 newid()
创建的 guid 一起使用。
有什么想法吗? (这里还有一些背景知识,如果你有兴趣:http://www.itu.dk/~friism/blog/?p=121)
更新:完整解决方案here
【问题讨论】:
【参考方案1】:您也许可以通过 ROW_NUMBER 函数在 lat 和 long 之间使用 CTE,然后对它使用 rand()。比如:
WITH cte AS
(
SELECT
intID,
ROW_NUMBER() OVER
(
PARTITION BY geoLat, geoLng
ORDER BY NEWID()
) AS row_num,
COUNT(intID) OVER (PARTITION BY geoLat, geoLng) AS TotalCount
FROM
dbo.Documents
)
SELECT TOP (@maxcount)
intID, RAND(intID)
FROM
cte
WHERE
row_num = 1 + FLOOR(RAND() * TotalCount)
这将始终返回第一组 lat 和 lng,我无法使顺序随机化。也许有人可以继续使用这种方法。不过,它会在匹配的 lat 和 lng 组合中为您提供一个随机行。
如果我以后有更多时间,我会尝试绕过最后一个障碍。
【讨论】:
如果将order by intid
替换为newid()
,这实际上是有效的。 partition
似乎强加了一些顺序(这很有意义),因此必须重新调整外部查询中的结果。如果没有重新洗牌,所有行都选择了最南端的位置:-)。
我按照您的建议进行了更改。我不得不承认,我还在学习 CTE,所以这是一个和他们一起玩的好借口。 :) 我原以为按 NEWID() 排序只会改变 lat/lng 对内的排序。【参考方案2】:
这对你不起作用?
select top (@maxcount) *
from
(
select max(intid) as id from Documents d group by d.geoLng, d.geoLat
) t
order by newid()
【讨论】:
这种方法的问题是它总是会为给定的坐标返回相同的文档,即具有最大 id 的那个。我也希望它是随机的。 所以只需要 select top 1 * from ... order by newid() 我不能select *
当group by
,你能详细说明吗?
我不明白这个解决方案是如何工作的。这是我用过无数次的。【参考方案3】:
您从哪里得知 DISTINCT 仅适用于一列?无论如何,您也可以使用 GROUP BY 子句。
【讨论】:
我支持这一点,在所有列上都有不同的作品!所有列必须是唯一的。 你完全正确,我已经重新提出了这个问题。然而问题仍然存在。以上是关于SQL Server rand() 聚合的主要内容,如果未能解决你的问题,请参考以下文章