是否可以通过查询获得组中组内的随机值?

Posted

技术标签:

【中文标题】是否可以通过查询获得组中组内的随机值?【英文标题】:Is it possible to get a random value within a group in a group by query? 【发布时间】:2021-12-30 12:16:15 【问题描述】:

我想在分组查询中获得随机,如下所示:

SELECT city
  , SOME_RANDOMIZER_FUNC(latitude) as "RANDOM_LATITUDE_IN_CITY"
  , SOME_RANDOMIZER_FUNC(longitude) AS "RANDOM_LONGITUDE_IN_CITY"
FROM some_table
GROUP BY city

输入:

city    LATITUDE    LONGITUDE
STO     -31.3935    -57.9413
STO     -31.0274    -57.8081
STO     -30.7852    -57.7765
STO     -30.4274    -56.4718
NDU     -30.2747    -57.6023
NDU     -32.2909    -58.0737
NDU     -32.0286    -57.8468
NDU     -32.3600    -57.2021
NDU     -32.6816    -57.6541
MBO     -31.7085    -55.9873
MBO     -30.9359    -55.5457
MBO     -31.1972    -55.7574
MBO     -31.7711    -54.6904

想要的输出:

city    RANDOM_LATITUDE_IN_CITY     RANDOM_LONGITUDE_IN_CITY
STO     -31.0274                    -57.9413
NDU     -32.3600                    -57.6541
MBO     -30.9359                    -55.5457

函数SOME_RANDOMIZER_FUNC返回组内的随机值

【问题讨论】:

有一组经纬度属于同一个城市。但是,一个坐标可以属于一个记录,另一个属于另一个记录,我不知道这是不是问题 我猜样本数据(以及所需的输出)会有所帮助。 【参考方案1】:

在随机函数的输入参数中,您呈现所有数据,然后对其应用分组,这是不允许的。 最好的方法是使用以下代码:

with s_table as (

    select
        city,
        latitude,
        longitude,
        row_number() over(partition by city order by DBMS_RANDOM.VALUE) as random_sort
    from
        some_table
    )
    select
    city,
    latitude,
    longitude
from
    s_table
where
    random_sort =1

【讨论】:

与我的解决方案相同,只是我迟到了两分钟 :-) Oracle 中没有 RAND()。请改用DBMS_RANDOM.VALUE 是的,每个引擎都有生成随机数的功能。 rand()、random()、DBMS_RANDOM.VALUE 等。感谢您的提示。【参考方案2】:

如果您想要一些不确定的行,那么您可以尝试 any_value 函数,自 21c 以来记录:

create table t
as
select
  trunc((level - 1)/10) as city
  , level as lat
  , 100 - level as lon
from dual
connect by level < 101
select /*+gather_plan_statistics*/
  city
  , any_value(lat) as lat
  , any_value(lon) as lon
from t
group by
  city
城市 |纬度 |伦敦 ---: | --: | --: 0 | 1 | 99 1 | 11 | 89 2 | 21 | 79 3 | 31 | 69 4 | 41 | 59 5 | 51 | 49 6 | 61 | 39 7 | 71 | 29 8 | 81 | 19 9 | 91 | 9

db小提琴here

【讨论】:

OP 强调他需要一个 random 值。那不是ANY_VALUE()。非确定性并不意味着随机。我很确定您已经意识到了这一点,但它可能会改善您的答案以澄清这一点。【参考方案3】:

您可以将 FIRST_VALUE 与 DBMS_RANDOM.VALUE 结合使用

例如:

SELECT city, latitude, longitude
FROM
(
    SELECT city
    , FIRST_VALUE(latitude) OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) as latitude
    , FIRST_VALUE(longitude) OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) as longitude
    FROM some_table
) 
GROUP BY city, latitude, longitude
ORDER BY city;
城市 |纬度 |经度 :--- | --------: | --------: 管理层收购 | -30.9359 | -55.5457 国防大学 | -32.6816 | -57.6541 申通 | -30.4274 | -56.4718

dbfiddle here

上的演示

【讨论】:

【参考方案4】:

为每个城市随机编号,然后保留编号为 1 的行。

SELECT city, latitude, longitude
FROM
(
  SELECT 
    city, latitude, longitude,
    ROW_NUMBER() OVER (PARTITION BY city ORDER BY DBMS_RANDOM.VALUE) AS rn
  FROM some_table
)
WHERE rn = 1
ORDER BY city;

【讨论】:

以上是关于是否可以通过查询获得组中组内的随机值?的主要内容,如果未能解决你的问题,请参考以下文章

如何随机抽样删除一些组和随机删除组内的一些个人?

每组随机采样,制作一个新的数据框,重复直到组内的所有实体都被采样

根据可以具有值或为空的字段选择组内的行

php 获取另一组内的组中的字段

如何根据sql中组中的日期集获取前7天的数据

向组内的所有用户发送消息 - Smack API