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

时间:2017-07-24 20:42:00

标签: sql oracle oracle11g

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

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

表名:住宿

表格记录:

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

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

3 个答案:

答案 0 :(得分:1)

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

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 :(得分: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

希望这有帮助。

答案 2 :(得分: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)