【问题标题】: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返回组内的随机值

【问题讨论】:

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

标签: sql oracle random group-by oracle11g


【解决方案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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      • 2020-01-03
      相关资源
      最近更新 更多