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() 聚合的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server聚合函数与聚合开窗函数

SQL Server聚合函数

SQL Server中的聚合函数都有哪些?

SQL Server中的聚合函数都有哪些?

SQL Server:条件聚合;

SQL Server的各种聚合函数