SQL Server rand() aggregate

Проблема: таблица координат lat/lng. Возможно, что две строки имеют одну и ту же координату. Нам нужен запрос, который возвращает набор строк с уникальными координатами (в пределах возвращаемого набора). Обратите внимание, что distinct неприменим, потому что мне нужно вернуть столбец id, который по определению отличается. Подобные работы (@maxcount - это количество строк, которые нам нужны, intid - уникальный столбец int id):

select top (@maxcount) max(intid)
from Documents d
group by d.geoLng, d.geoLat

Он всегда будет возвращать одну и ту же строку для заданной координаты, к сожалению, это немного позор для моего использования. Если бы у нас был агрегат rand(), который мы могли бы использовать вместо max()... Обратите внимание: вы не можете использовать max() с подсказками, созданными newid().

Любые идеи? (здесь вам больше интересного, если вам интересно: http://www.itu.dk/~friism/blog/?p=121)

UPDATE: полное решение здесь

Ответ 1

Вы можете использовать CTE для этого с функцией ROW_NUMBER в lat и long, а затем использовать 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.

Если у меня будет больше времени, я попытаюсь обойти это последнее препятствие.

Ответ 2

это не работает для вас?

select top (@maxcount) *
from 
(
    select max(intid) as id from Documents d group by d.geoLng, d.geoLat
) t 
order by newid()

Ответ 3

Откуда у вас возникла идея, что DISTINCT работает только с одним столбцом? В любом случае, вы также можете использовать предложение GROUP BY.