首页 文章

Oracle中Where条件之后的示例子句

提问于
浏览
1

我在Oracle中有一个表,我希望在应用某些条件后获得10%的样本记录 . 我在谷歌搜索但是我没有得到正确的算法来在Oracle中的WHERE子句之后使用SAMPLE子句 .

我用下面的例子解释了我的要求 . 能否请您建议如何编写SQL查询?我的尝试不起作用 .

Table Name: 住宿

Table Records:

ACCOM_ID    ACCOM_TYPE
--------    ----------
1       HOTEL
2       HOTEL
3       HOTEL
4       HOTEL
5       HOUSE
6       HOUSE
7       CRUISE

在这里,我希望在应用条件后获得50%的样本记录 . 那是,

SELECT * FROM (SELECT * FROM ACCOMMODATION WHERE ACCOM_TYPE = 'HOTEL') T SAMPLE(50);

要么

SELECT * FROM (SELECT * FROM ACCOMMODATION WHERE ACCOM_TYPE = 'HOUSE') T SAMPLE(50);

但上面的查询无效,失败并出现错误 ORA-00933: SQL command not properly ended . 如果我使用如下,它没有正确地将结果返回给我 . 我只想要2个随机酒店记录,但它有时会返回2,有时3,有时4 .

select * from accommodation sample(50) where accom_type = 'HOTEL';

请参考sql小提琴示例HERE .

Edit: 这是样本表 . 我使用的真实 table 有很多记录,所以不幸的是我无法 order by dbms_random.value() 因为它需要很长时间才能完成 .

3 回答

  • 1

    这应该可行,但对于一张大 table 来说不会很快:

    select * FROM (
      select * from accommodation 
      where accom_type = 'HOTEL'
      order by dbms_random.value
    )
    WHERE rownum <= 0.5 * (
      SELECT count(*) FROM accommodation where accom_type = 'HOTEL'
    )
    ;
    

    演示:http://sqlfiddle.com/#!4/6bf8b/13

  • 1

    这是给定表上的示例代码,以根据您的需要获得结果 . 我从每个ACCOM_TYPE中获取80%的行 .

    SELECT *
        FROM (  SELECT a.*,
                       ROW_NUMBER () OVER (PARTITION BY ACCOM_TYPE ORDER BY ACCOM_ID)
                          AS pos
                  FROM ACCOMMODATION a
              ORDER BY ACCOM_TYPE, pos) t
       WHERE pos <= (SELECT ROUND ( (COUNT (*) * 80) / 100)
                       FROM ACCOMMODATION
                      WHERE ACCOM_TYPE = t.ACCOM_TYPE)
    ORDER BY ACCOM_TYPE, DBMS_RANDOM.VALUE;
    

    在内联视图查询中查找row_number为 pos 列别名,然后在主查询过滤器中,基于每个ACCOM_TYPE的总行数的80%(这可以相应地更改)计算行 .

    最后,对于随机结果,按顺序使用 DBMS_RANDOM.VALUE .

    希望这可以帮助 .

  • 0

    一种方法是计算您对HOTEL和HOUSE的行数,然后使用该数字除以/ 2 . 此查询将计算HOUSE的行数,并使用从子查询获得的rownum数

    Select * from Accommodation
    Where ACCOM_TYPE = 'HOTEL'
    and rownum <= (Select count(accom_id)/2 as HotelCount from ACCOMMODATION 
    WHERE ACCOM_TYPE = 'HOTEL'
    group by accom_type)
    UNION
    Select * from Accommodation
    Where ACCOM_TYPE = 'HOUSE'
    and rownum <= (Select count(accom_id)/2 as HotelCount from ACCOMMODATION 
    WHERE ACCOM_TYPE = 'HOUSE'
    group by accom_type)
    

相关问题