5

我正在使用 Microsoft 的 SQL Server 2008。我需要通过外键聚合以随机获取单个值,但我很难过。考虑下表:

id          fk          val
----------- ----------- ----
1           100         abc
2           101         def
3           102         ghi
4           102         jkl

期望的结果是:

fk          val
----------- ----
100         abc
101         def
102         ghi

fk 102 的 val 将随机为“ghi”或“jkl”。

我尝试使用 NEWID() 来获取唯一的随机值,但是,JOIN 失败,因为 NEWID() 值因子查询而异。

WITH withTable AS (
    SELECT id, fk, val, CAST(NEWID() AS CHAR(36)) random
    FROM exampleTable
)
SELECT t1.fk, t1.val
FROM withTable t1
JOIN (
    SELECT fk, MAX(random) random
    FROM withTable
    GROUP BY fk
) t2 ON t2.random = t1.random
;

我难住了。任何想法将不胜感激。

4

3 回答 3

6

我可能会稍微不同地考虑一下,使用一个名为 的特殊排名函数ROW_NUMBER()

您基本上对每一行应用一个数字,按 分组fk,从 1 开始,使用NEWID()函数作为排序值随机排序。从中可以选择行号为 1 的所有行。此技术的效果是它随机分配哪一行被分配值 1。

WITH withTable(id, fk, val, rownum) AS 
(
    SELECT
        id, fk, val, ROW_NUMBER() OVER (PARTITION BY fk ORDER BY NEWID())
    FROM
        exampleTable
)
SELECT
    *
FROM
    withTable
WHERE
    rownum = 1

这种方法还有一个额外的好处,因为它可以一次性完成分组和随机化。

于 2013-07-02T17:35:19.537 回答
1

您可以不使用聚合来执行此操作,而是使用row_number()

select id, fk, val
from (select t1.*,
             row_number() over (partition by fk order by newid()) as seqnum
      from withTable t1
     ) t1
where seqnum = 1
于 2013-07-02T17:34:00.737 回答
0

一种选择是将相同 fk 的值放入临时表中,然后通过 NEWID() SELECT TOP 1 ORDER

那应该对你有用。

于 2013-07-02T17:34:19.167 回答